How to handle JWT revocation with MQTT
Asked Answered
P

2

16

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?

Paregoric answered 15/11, 2017 at 18:1 Comment(0)
S
1

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);
}
Scheme answered 17/9, 2019 at 18:54 Comment(2)
Is doing disconnect/connect the best way? No possibility of keeping the channel open?Paregoric
@ArthurC In order to flow authentication process in MQTT broker, there is not another way except disconnect/connecting clients.Scheme
K
4

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

Kornegay answered 29/1, 2019 at 13:7 Comment(1)
How would the client handle token refresh?Paregoric
S
1

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);
}
Scheme answered 17/9, 2019 at 18:54 Comment(2)
Is doing disconnect/connect the best way? No possibility of keeping the channel open?Paregoric
@ArthurC In order to flow authentication process in MQTT broker, there is not another way except disconnect/connecting clients.Scheme

© 2022 - 2024 — McMap. All rights reserved.