Skip to main content

TLS in Python for JSON DB API

Use TLS in Python for JSON DB API

Abstract

Use TLS in Python for JSON DB API

If you are familiar with the Python Requests library, implementing TLS using self-signed TLS certificates for a secure connection is simple. This document also covers the basics of the JSON DB API.

Prerequisites
  • Ensure you have properly enabled TLS and created and configured TLS certificates. See Secure MQTT with certificates.

    You must create a separate server certificate for each computer that runs a FairCom server. Each FairCom server must be configured to use the appropriate server certificate for the computer on which it runs

  • Each user must have a unique client certificate. A client certificate allows a client program to identify itself to a FairCom server. Each program that wants to use a certificate must be configured to send the certificate to the server.

    Note

    Do not use a client certificate in a client program to connect to a FairCom server that is not configured with a certificate.

Ensure you meet the prerequisites before this procedure.

  1. Configure the HTTPS listener in the services.json file to use your CA certificate, server certificate, and private key.

  2. Ensure the "enabled" property is set to true.

  3. Update the "tls" object:

    • Update the "certificateFilename" property value to the path and filename of the server certificate you created or obtained for this FairCom server

    • Add a "certificateAuthoritiesFilename" property and set it to the path and filename containing CA certificate.

      Note

      This is the certificate from the CA that signed the server certificate.

    • Add a "privateKeyFilename" property and set it to the path and filename of the private key file that corresponds with the server certificate.

  4. Save any changes.

  5. Restart the server for the changes to take effect.

Example 1. HTTPS listener
{
  "serviceName": "https8443",
  "description": "Port 8443 using TLS-secured HTTPS protocol for REST and Web Apps on all TCP/IP addresses bound to this server",
  "port": 8443,
  "protocol": "https",
  "enabled": true,
  "tls": {
    "certificateAuthoritiesFilename": "C:/Certificates/ca.crt",
    "certificateFilename":            "C:/Certificates/server.crt",
    "privateKeyFilename":             "C:/Certificates/server.key"
  }
},


Ensure you meet the prerequisites before this procedure.

  1. Update your existing POST:

    • Update the "verify" property value to the location of the certificate you obtained for your FairCom server.

    • Update the "cert" property value to the location of your client files. 

      Note

      A tuple should be passed to this parameter, where the first element is the client certificate and the second is the client private key file.

  2. If you do not already have a JSON DB API project, establish a TLS connection by making the following update to this code.

    endpoint = "https://myserver.local:8443/api"
    create_session = json.loads( '{"api":"admin","action":"createSession","params":{"username":"admin","password":"ADMIN"}}' )
    server_certificate = "C:/Certificates/server.crt"
    client_certs = ("C:/Certificates/client.crt", "C:/Certificates/client.key")
    login_response = requests.post( endpoint, json = create_session, verify = server_certificate, cert = client_certs )
    • Set the endpoint to match the Subject Alternate Name in your server certificate.

      Important

      The name of the endpoint must either be the Common Name (CN) of the server certificate or one of the Subject Alternative Names in your server certificate. If this is not the case, the server certificate will be rejected.

    • Set the username to a valid username on the FairCom server.

    • Set the password to a valid password on the FairCom server.

    • Set the server_certificate to the public certificate for your FairCom server.

    • Set the client_certs to the tuple containing the client certificate file and its private key file.

      Note

      These files must be available on the computer that runs the Python code.

  3. Observe the response and make a note of the "authToken" to use in subsequent JSON DB API calls.

Ensure you meet the prerequisites before this procedure.

  1. Retrieve the "authToken" using the following code:

    auth_token = login_response.json()['result']['authToken']
  2. Parse the login_response variable and check the "errorCode" property.

    Note

    "errorCode" with a value of 0 indicates success. "errorCode" with a non-zero value indicates a failure. See Errors and contact FairCom for more information about an error.

  3. Verify that the root object contains a "result" object with an "authToken" property.

  4. List the databases on the server using the following code:

    list_databases = json.loads( '{"api":"db","action":"listDatabases","authToken":""}' )
  5. Insert the "authToken" using the following code:

    list_databases['authToken'] = auth_token
  6. Send the command using the following function call:

    Note

    The only change from the request.post() function in Configure the Python client is the variable passed to the "json" parameter and the variable that the response is assigned to.  This line is a good target for refactoring into a function that takes the JSON body as a parameter and performs error checking on the response.

    list_databases_response = requests.post( endpoint, json = list_databases, verify = server_certificate, cert = client_certs )
  7. Observe the response by using the following code:

    print( list_databases_response.json() )

    Or for a formatted output use:

    print( json.dumps( list_databases_response.json(), indent = 2 ) )
  8. Close the connection using the deleteSession() API call:

    delete_session = {"api": "admin", "action": "deleteSession", "authToken": ""}
    delete_session_response = requests.post( endpoint, json = delete_session, verify = server_certificate, cert = client_certs )

Note

This complete code example has additional error checking.

endpoint = "https://myserver.local:8443/api"
create_session = json.loads( '{"api":"admin","action":"createSession","params":{"username":"admin","password":"ADMIN"}}' )
server_certificate = "C:/Certificates/server.crt"
client_certs = ("C:/Certificates/client.crt", "C:/Certificates/client.key")
login_response = requests.post( endpoint, json = create_session, verify = server_certificate, cert = client_certs )

if login_response.status_code != 200:
  print( login_response )
  raise SystemExit( -2 )

auth_token = login_response.json()['result']['authToken']

list_databases = json.loads( '{"api":"db","action":"listDatabases","authToken":""}' )
list_databases['authToken'] = auth_token
list_databases_response = requests.post( endpoint, json = list_databases, verify = server_certificate, cert = client_certs )

if list_databases_response.status_code != 200:
  print( list_databases_response )
  raise SystemExit( -3 )
print( json.dumps( list_databases_response.json(), indent = 2 ) )

delete_session = {"api": "admin", "action": "deleteSession", "authToken": ""}
delete_session_response = requests.post( endpoint, json = delete_session, verify = server_certificate, cert = client_certs )

if delete_session_response.status_code != 200:
  print( delete_session_response )
  raise SystemExit( -4 )