Skip to main content

Tutorial: 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 a CA certificate file created and configured on the FairCom server.Tutorial: Create certificates using OpenSSL

    Note

    When you do not require clients to authenticate by certificate, do not assign a CA certificate to the FairCom server.

  • Ensure you have a server certificate file created and configured on the FairCom server.Tutorial: Create certificates using OpenSSL

    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

  • Ensure you have a private key file created and configured on the FairCom server.Tutorial: Create certificates using OpenSSL

    The private key file is the secret key that is paired with the server certificate file. It is used by the server in the TLS protocol to identify the server to clients.

  • Ensure you have client certificate file created and ready to use in this Python program.Tutorial: Create certificates using OpenSSL

    The client certificate file allows the Python program to identify itself to the FairCom server. Each Python program that wants to use a certificate must be configured to send the certificate to the server. When the FairCom server is not configured with the CA certificate, do not use a client certificate in a Python program.

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 )