The MigratoryData JWT Authorization add-on allows you to authorize users to subscribe to and/or publish real-time messages on specific subjects using the JSON Web Tokens (JWT) standard. The add-on is preinstalled in the MigratoryData server starting with version 6.0.9 and its source code is freely available on GitHub. It is built using the Server Extensions API for Authorization.

Overview

The following diagram highlights the JWT authorization workflow with MigratoryData.

  1. Your client application connects to your backend services to request a JWT token. The client application typically provides the login credentials, such as the username and password of the user who opened the client application.

  2. Your backend checks the login credentials of the user and retrieves the client’s permissions, typically from a database.

    Then, it should generate a JWT token with the payload containing several standard and custom fields, also referred to as claims. The JWT token must include at least the standard claim exp containing the expiration time of the token, expressed in seconds as epoch time. It must also include the custom claim permissions containing the permissions of the client using the following JSON format:

"permissions": {
    "sub": [
        "/subject/sub1",
        "/subject/sub2"
    ],
    "pub": [
        "/subject/pub1",
        "/subject/pub2",
        "/subject/pub3"
    ],
    "all": [
        "/subject/pubsub1",
        "/subject/pubsub2"
    ]
}

where the subfield sub defines the subjects to which the client is authorized to subscribe, the subfield pub defines the subjects on which the client is authorized to publish, and the subfield all defines the subjects on which the client is authorized to both publish and subscribe.

Finally, before sending the JWT token to the client application, the JWT token needs to be signed either with an HMAC secret or an RSA private key. Both the symmetric signature using HMAC algorithms and the asymmetric signature using RSA algorithms are supported as further detailed in the documentation of the parameter signature.type.

We provide examples on how to generate JWT tokens using PHP and Node.js. If your backend services use another language, you should be able to easily adapt those examples to your language or otherwise please get in touch with us.
  1. Once the client gets the JWT token from your backend services, it attempts to connect to the MigratoryData server by providing the JWT token with the MigratoryData client API method setEntitlementToken().

  2. The JWT Authorization add-on of the MigratoryData server verifies the signature of the JWT token either with an HMAC secret if the JWT token was signed using an HMAC algorithm, or with an RSA public key if the JWT token was signed using an RSA algorithm. If correct, it parses the permissions from the JWT token and store them in memory for subsequent publish and subscribe authorization requests. Finally, if both the signature verification and permission parsing are successful, then the add-on sends a notification NOTIFY_CONNECT_OK to the client, or otherwise it sends a notification NOTIFY_CONNECT_DENY.

Enabling the add-on

The JWT Authorization add-on is preinstalled in the MigratoryData server under the following folder, according to the package type used to install the MigratoryData server:

Location Package type
addons/authorization-jwt Platform-independent tarball package
/usr/share/migratorydata/addons/authorization-jwt RPM or DEB Linux package

To enabled it, set the parameter Entitlement of the MigratoryData server on JWT.

If you modify the JWT Authorization add-on from the available source code, please refer to the README file of the source code to learn how to enable the modified add-on.

Configuring the add-on

The default configuration is available under the following folder:

Location Package type
addons/authorization-jwt Platform-independent tarball package
/etc/migratorydata/addons/authorization-jwt RPM or DEB Linux package

It includes the parameters described below.

renewTokenBeforeSeconds

renewTokenBeforeSeconds  
Description Specify the number of seconds before a token expiry when to send a token renew notification to the client
Default value 60
Required parameter Optional

When a JWT token is about to expire, a notification is sent to the client by the JWT Authorization add-on to renew its JWT token. The notification is sent to the client with the number of seconds configured by this parameter before the JWT token expiry.

signature.type

signature.type  
Description Specify the signing algorithm to be used to verify the JWT tokens, either hmac or rsa
Default value hmac
Required parameter Optional

Currently, the available signature types are the following ones:

hmac - a symmetric signature method using a single secret key both for signing and verifying JWT tokens. The signature algorithms supported by this method, automatically selected according to the length of the secret key, are as follows:

  • HS256 (HMAC SHA256), requires a 32-byte secret - recommended for most use cases
  • HS384 (HMAC SHA384), requires a 48-byte secret
  • HS512 (HMAC SHA512), requires a 64-byte secret

rsa - an asymmetric signature method using a pair of public and private keys, where the private key is used for signing a JWT token, and the public key is used for verifying a JWT token. The signature algorithms supported by this method, automatically selected according to the length of the private key, are as follows:

  • RS256 (RSA SHA256), requires a 2048-bit private key - recommended for most use cases
  • RS384 (RSA SHA384), requires a 3072-bit private key
  • RS512 (RSA SHA512), requires a 4096-bit private key

signature.hmac.secret

signature.hmac.secret  
Description Specify the secret key for hmac signature verification
Default value none
Required parameter Mandatory (if the parameter signature.type is set on hmac)

If your signature type is hmac, configure this parameter with a base64-encoded secret key for verifying the JWT tokens of your clients. The length of this secret key determines the signature algorithm to be used as explained in the documentation of the parameter signature.type. For most cases, a 32-byte secret key is recommended. You can generate a 32-byte secret key encoded as base64 using the command:

openssl rand -base64 32

signature.rsa.publicKeyPath

signature.rsa.publicKeyPath  
Description Specify the file path of the public key for rsa signature verification
Default value none
Required parameter Mandatory (if the parameter signature.type is set on rsa)

If your signature type is rsa, configure this parameter with the file path of the public key for verifying the JWT tokens of your clients. The size in bits of the private key corresponding to the public key determines the signature algorithm to be used as explained in the documentation of the parameter signature.type. For most cases, a 2048-bit private key is recommended. You can generate a private key for signing your JTW tokens using this command:

openssl genrsa \
-out rsa-private-key.pem \
2048

Then, extract the public key from the private key — to be configured with this parameter — as follows:

openssl rsa -in rsa-private-key.pem \
-pubout \
-outform PEM \
-out rsa-public-key.pem

Generating JWT tokens on your backend

According to the language you are using for your backend services, please find below examples on how to generate JWT tokens with PHP and Node.js. If your backend services use another language, you should be able to easily adapt those examples to your language or otherwise get in touch with us.

Handling JWT tokens on the client side

The JWT Authorization add-on sends the following notifications to the client application:

Add-on Notification Description
NOTIFY_TOKEN_INVALID Notify the client that the JWT token it provided is invalid
NOTIFY_TOKEN_EXPIRED Notify the client that the JWT token it provided is expired
NOTIFY_TOKEN_TO_EXPIRE Notify the client that its JWT token is about to expire and needs to be renewed. This notification is sent with the number of seconds defined by renewTokenBeforeSeconds before the token expiry
NOTIFY_TOKEN_UPDATED Notify the client that the new JWT token it provided has been taken into account by the add-on, i.e. the token renewal was successful

The client application also receives a number of notifications from the MigratoryData server. Here are several of these notifications related to authentication and authorization:

Server Notification Description
NOTIFY_SERVER_UP Notify the client that its WebSocket connection with the MigratoryData server has been established
NOTIFY_SERVER_DOWN Notify the client that its WebSocket connection with the MigratoryData server failed
NOTIFY_CONNECT_OK Notify the client it authenticated successfully with the JWT Authorization add-on or with a custom authorization extension built using the Authorization API v2
NOTIFY_CONNECT_DENY Notify the client it failed to authenticate with the JWT Authorization add-on or with a custom authorization extension built using the Authorization API v2 for the reason provided in the details of the notification
NOTIFY_SUBSCRIBE_ALLOW Notify the client it successfully subscribed to the subject provided in the details of the notification
NOTIFY_SUBSCRIBE_DENY Notify the client it failed to subscribe to the subject provided in the details of the notification
NOTIFY_PUBLISH_OK Notify the client it successfully published a message with the message ID provided in the details of the notification
NOTIFY_PUBLISH_DENY Notify the client it failed to publish a message with the message ID provided in the details of the notification

The following sequence diagram details the workflow of these notifications using an example:

We provide the source code of a client application handling JWT tokens on github. This client application is written using MigratoryData Client API for Java. You should be able to easily adapt it to any other language or otherwise please get in touch with us.