Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle JWT revocation with MQTT

Following the instructions in this Auth0 article, I successfully authenticated MQTT clients using "JWT" as username and the JWT token as a password.

In my use case, however, JWT tokens are short-lived. Clients must fetch a new token before the expiration date of the current token, and then provide it to the MQTT server. Otherwise, the connection is terminated by the server.

My question is: how do I implement the token update? Is it a publish message from the client? To which topic? Do I disconnect the client, and let the client re-authenticate with the new token? Or is there another way?

like image 784
Arthur C Avatar asked Nov 15 '17 18:11

Arthur C


People also ask

How do I revoke access to JWT?

The most common way to revoke access to resources protected by a JWT involves setting its duration to a short period of time and revoking the refresh token so that the user can't generate a new token.

Does MQTT support customer created token based authentication?

Access Token based authentication is the default device authentication type. The unique access token is generated once the device is created in ThingsBoard. It can be changed afterwards.

What happens if someone steals your JWT token?

If your JWT is stolen or compromised, then the attacker has full access to your account. The attacker can send requests to applications, pretending to be you, and can make potentially harmful changes.

Can JWT token be revoked?

The best solution for JWT revocation, is short exp window, refresh and keeping issued JWT tokens in a shared nearline cache. With Redis for example, this is particularly easy as you can set the cache key as the token itself (or a hash of the token), and specify expiry so that the tokens get automatically evicted.


2 Answers

The easiest way is to implement an asynchron service, that checks periodically your connected clients and reads the token timestamp. If the timestamp is to old - force the disconnect of the client, and reconnect.

Depending on the system you use, you can add this functionality to your Message Broker you use.

In HiveMQ for example you can plugin easily an asynchron callback, that schedules these kind of background job and executes this periodically.

The extension system of HiveMQ is well documented and you can find some examples here: https://www.hivemq.com/docs/4/extensions/services.html#managed-extension-executor

like image 200
Anja H Avatar answered Sep 19 '22 03:09

Anja H


Considering refreshing JWT tokens is matter because tokens have expiration dates. If a device is connected over MQTT and its token expires, MQTT broker should automatically disconnect device from broker. You can prevent the device from disconnecting by automatically refreshing its token.

The following samples illustrate how to check whether a token has expired and, if it has, how to reconnect with a new token without disconnecting the device.

long secsSinceRefresh = ((new DateTime()).getMillis() - iat.getMillis()) / 1000;
if (secsSinceRefresh > (options.tokenExpMins * 60)) {
  System.out.format("\tRefreshing token after: %d seconds\n", secsSinceRefresh);
  iat = new DateTime();
  if (options.algorithm.equals("RS256")) {
    connectOptions.setPassword(
        createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
  } else if (options.algorithm.equals("ES256")) {
    connectOptions.setPassword(
        createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
  } else {
    throw new IllegalArgumentException(
        "Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
  }
  client.disconnect();
  client.connect();
  attachCallback(client, options.deviceId);
}
like image 21
Ruhollah Delpak Avatar answered Sep 19 '22 03:09

Ruhollah Delpak