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?
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.
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.
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.
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.
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
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With