2

I'm currently working on python to QlikSense server connection using websocket-client. for authentication, I have used certificates which are generated by Qlik sense server.

Even I followed the same logic of code mentioned at this link, but still getting an error.

from websocket import create_connection

def conn(senseHost, userDirectory, userId, privateKeyPath):

    # self.url = "wss://" + senseHost + ":4747/app/" # invalid
    url = "wss://" + senseHost + ":4747/app"  # valid
    ca = open(privateKeyPath + "root.pem").read()
    cer = open(privateKeyPath + "client.pem").read()
    key = open(privateKeyPath + "client_key.pem").read()
    certs = ({"ca": ca,
              "cert": cer,
              "key": key})
    # import pdb
    # pdb.set_trace()
    # ERROR raised here.
    ws = create_connection(url, sslopt=certs,
                                header={'X-Qlik-User: UserDirectory=%s; UserId=%s' % (userDirectory, userId)})
    session = self.ws.recv()
    return session

# below code has specific perameters.
c = conn("blablah.com","XYZ","ME","path/to/cert/")

I traced an error using pdb,

-> ws = create_connection(url,sslopt=certs,header={'X-Qlik-User: UserDirectory=%s; UserId=%s' % (userDirectory, userId)})
(Pdb) n
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:777)
bhargav patel
  • 919
  • 10
  • 16
  • QS certificates are self-signed. Which means that the connection is secured but the certificates are not trusted. Probably this is the reason why you are getting the error and your code should ignore the error. Im not a python developer but try something like this ` ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE}) ws.connect("wss://xxx.com:9090/websocket")` Found at https://stackoverflow.com/questions/46852066/how-to-create-python-secure-websocket-client-request?rq=1 – Stefan Stoichev Mar 13 '18 at 14:38
  • If i specify ssl.CERT_NONE then it gives **websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.** – bhargav patel Mar 14 '18 at 03:18

1 Answers1

2

I found a solution after 4 hours of effort.

def conn(senseHost, userDirectory, userId, privateKeyPath):
    url = "wss://" + senseHost + ":4747/app"  # valid
    certs = ({"ca_certs": privateKeyPath + "root.pem",
              "certfile": privateKeyPath + "client.pem",
              "keyfile": privateKeyPath + "client_key.pem",
              "cert_reqs":ssl.CERT_REQUIRED,
              "server_side": False
              })
    ssl.match_hostname = lambda cert, hostname: True
    ws = create_connection(url, sslopt=certs,
                                header={'X-Qlik-User: UserDirectory=%s; UserId=%s'% (userDirectory, userId)})
bhargav patel
  • 919
  • 10
  • 16
  • What does this line do? ssl.match_hostname = lambda cert, hostname: True – Kevin P. Jan 30 '20 at 02:54
  • ssl.match_hostname = lambda cert, hostname: True is also known as monkey patching. which sets match_host name to true i.e, This will avoid condition like, Qlik_sense_server_hostname == request_origin_hostname. – bhargav patel Jan 30 '20 at 04:37