MQTT Client Authentication Options for Your HiveMQ Extension
HiveMQ extensions can use different types of authenticators to authenticate MQTT clients.
Each extension can register an authenticator in the Security Registry. In HiveMQ, an extension that registers an authenticator is called a security extension.
You can use multiple security extensions. When you use more than one security extension, the associated authenticators are called in the same order as their extensions (highest priority first). If an authenticator with a higher priority makes a final decision (such as a successful or failed authentication), authenticators of lower priority extensions are not called. The extension with the next lower priority is only called if the authenticator explicitly delegates the decision to the next extension.
Since version 4.3, HiveMQ only allows MQTT clients to connect if a security extension is present.
For testing purposes, HiveMQ includes a hivemq-allow-all-extension that authorizes all MQTT clients to connect to HiveMQ.
Before you use HiveMQ in production, you must add an appropriate security extension and remove the hivemq-allow-all-extension.
You can download security extensions from the HiveMQ website
or develop your own security extension.
|
A simple authenticator can only use information from the CONNECT packet of an MQTT client (usually the username and password) and connection information (such as X.509 certificates).
Simple authentication works for all MQTT versions but has the following limitations:
-
No challenge/response style authentication.
-
No re-authentication during the same connection.
An enhanced authenticator includes all features of a simple authenticator and can also use AUTH packets (introduced in MQTT 5) to implement enhanced authentication mechanisms:
-
Challenge/response style authentication and
-
Support for re-authentication during the same connection.
| An enhanced authenticator is not required to use enhanced authentication mechanisms. Enhanced authenticators can also authenticate MQTT clients that do not support enhanced authentication. For example, MQTT 3 clients. |
Simple Authenticator for MQTT Clients
The SimpleAuthenticator interface is used to perform authentication at the moment a CONNECT packet is received from a newly connecting client.
For this task, HiveMQ provides SimpleAuthInput and SimpleAuthOutput parameters.
Extension input and extension output principles apply.
The SimpleAuthOutput parameter can easily be used for asynchronous processing.
The SimpleAuthInput parameter provides the following information:
-
The
CONNECTpacket from the client (the username and password may be of particular interest) -
Connection information (the X.509 client certificate may be of particular interest)
-
Client information (the client identifier may be of particular interest)
The SimpleAuthOutput parameter provides three important methods to decide authentication:
-
authenticateSuccessfully()finishes the authentication process for the client and allows it to connect to HiveMQ. ACONNACKpacket with reason codeSUCCESSis sent to the client. Authenticators of extensions with a lower priority are not called. -
failAuthentication()finishes the authentication process for the client and disconnects the client. ACONNACKpacket with a failure reason code can be sent to the client and the connection is closed. Authenticators of extensions with a lower priority are not called. -
nextExtensionOrDefault()does not decide the authenticity of the client. Authenticators of extensions with a lower priority are called. If no further authenticators are present, the default behavior is applied. The default behaviour is to fail the authentication.
In addition to the authentication decision, a SimpleAuthenticator can also authorize and restrict client actions by modifying the Default Permissions of the client and its Client Settings.
In most scenarios, HiveMQ sends a CONNACK packet to the client after the SimpleAuthenticator completes.
However, during the disconnection flow for MQTT 3 clients, HiveMQ does not send a CONNACK packet when failAuthentication() is called with one of the following reason codes: IMPLEMENTATION_SPECIFIC_ERROR, MALFORMED_PACKET, PROTOCOL_ERROR, or UNSPECIFIED_ERROR.
The authenticator can set the reason code, reason string, and user properties of the CONNACK packet. The following failure reason codes and reason strings are possible:
| Action | Reason Code | Reason String |
|---|---|---|
No authenticator present (no security extension present or all providers returned |
|
|
|
|
|
|
|
|
|
As specified |
|
|
|
As specified |
|
As specified |
As specified |
|
|
|
|
As specified |
|
|
|
As specified |
|
As specified |
As specified |
Authenticator throws exception (this is not a feature, but a safeguard) |
|
|
Authenticator did not call any decisive method (this is not a feature, but a safeguard) |
|
|
The reason string and user properties are only sent to MQTT 5 clients.
You can specify all CONNACK reason codes that are defined in the MQTT 5 specification.
The MQTT 3 specification defines significantly fewer reason codes.
The following table shows the mapping of the CONNACK reason codes between the different MQTT versions:
| MQTT 5 Reason Code | MQTT 3 Reason Code |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A SimpleAuthenticator can be provided by an AuthenticatorProvider.
The AuthenticatorProvider can be registered via the Security Registry.
A SimpleAuthenticator object can be used to authenticate different clients by returning the same object in the AuthenticatorProvider.
Sharing the same object has the following requirements:
-
The implementation does not store the authentication state in the object.
-
The implementation is thread safe.
Enhanced Authenticator for MQTT Clients
Enhanced authentication has two life cycles:
-
Authentication when a client initially connects:
-
onConnectis called when theCONNECTpacket is received from the newly connecting client. -
onAuthis called for eachAUTHpacket received from the client after you calledcontinueAuthenticationin the authenticator.
-
-
Re-authentication during the client connection:
-
onReAuthis called when anAUTHpacket with the reason codeREAUTHENTICATEis received from the client. -
onAuthis called for eachAUTHpacket received from the client after you calledcontinueAuthenticationin the authenticator.
-
Initial authentication and re-authentication can not interleave.
An EnhancedAuthenticator can behave similarly to a SimpleAuthenticator if the authentication is directly succeeded or failed in the onConnect call.
|
HiveMQ provides an EnhancedAuthOutput parameter to all methods of the EnhancedAuthenticator.
The onConnect method gets an EnhancedAuthConnectInput parameter.
The onAuth and onReAuth methods get an EnhancedAuthInput parameter.
Extension input and extension output principles apply.
The EnhancedAuthOutput parameter can easily be used for asynchronous processing.
The EnhancedAuthConnectInput parameter provides the following information:
-
The
CONNECTpacket from the client (the username, password, authentication data and authentication method may be of particular interest) -
Connection information (the X.509 client certificate may be of particular interest)
-
Client information (the client identifier may be of particular interest)
The EnhancedAuthInput parameter provides the following information:
-
The
AUTHpacket from the client (the authentication data and authentication method may be of particular interest) -
Connection information (the X.509 client certificate may be of particular interest)
-
Client information (the client identifier may be of particular interest)
The EnhancedAuthOutput parameter provides four important methods to decide authentication:
-
authenticateSuccessfully()finishes the authentication process for the client successfully. Authenticators of extensions with a lower priority are not called.-
Initial authentication: The client is allowed to connect to HiveMQ. A
CONNACKpacket with reason codeSUCCESSand optionally specified authentication data is sent to the client. -
Re-authentication: The client is allowed to stay connected to HiveMQ. An
AUTHpacket with reason codeSUCCESSand optionally specified authentication data is sent to the client.
-
-
failAuthentication()finishes the authentication process for the client and disconnects the client. Authenticators of extensions with a lower priority are not called.-
Initial authentication: A
CONNACKpacket with a failure reason code is sent to the client and the connection is closed. -
Re-authentication: A
DISCONNECTpacket with a failure reason code is sent to the client and the connection is closed.
-
-
continueAuthentication()continues the authentication process for the client. HiveMQ sends anAUTHpacket with reason codeCONTINUE_AUTHENTICATIONand optionally specified authentication data to the client. Afterwards HiveMQ awaits anotherAUTHpacket from the client. Authenticators of extensions with a lower priority are not called. -
nextExtensionOrDefault()does not decide the authenticity of the client. Authenticators of extensions with a lower priority are called. If no further authenticators are present, the default behavior is applied. The default behaviour is to fail the authentication.
continueAuthentication can only be called if the client supports enhanced authentication.
MQTT 3.1 and 3.1.1 clients do not support enhanced authentication.
MQTT 5 clients only support enhanced authentication if the initial CONNECT packet contains an authentication method.
|
In addition to the authentication decision, an EnhancedAuthenticator can also authorize and restrict client actions by modifying the Default Permissions of the client and its Client Settings.
After the EnhancedAuthenticator completes, either a CONNACK, AUTH or DISCONNECT packet is sent to the client (depending on the authentication decision).
The authenticator can set the user properties of these packets.
When the authentication fails, the CONNACK packet (initial authentication) or DISCONNECT packet (re-authentication) provides a failure reason code and reason string.
If the authenticator does not set the reason code and reason string, the default reason codes and default reason strings are used.
The following failure reason codes and reason strings are possible:
| Action | Reason Code | Reason String |
|---|---|---|
No authenticator present (no security extension present or all providers returned |
|
|
|
||
|
|
|
|
||
|
|
|
|
||
|
As specified |
|
|
||
|
|
As specified |
|
As specified |
As specified |
|
|
|
|
||
|
As specified |
|
|
||
|
|
As specified |
|
As specified |
As specified |
|
|
|
|
||
|
|
|
|
||
|
As specified |
|
|
||
|
|
As specified |
|
As specified |
As specified |
Authenticator throws exception (this is not a feature, but a safeguard) |
|
|
|
||
Authenticator did not call any decisive method (this is not a feature, but a safeguard) |
|
|
|
The reason string and user properties are only sent to MQTT 5 clients.
On initial authentication, you can specify all CONNACK reason codes that are defined in the MQTT 5 specification.
The MQTT 3 specification defines significantly fewer reason codes.
This table shows the mapping of the CONNACK reason codes between the different MQTT versions.
Re-authentication is only possible for MQTT 5 clients.
Therefore, you can use all DISCONNECT reason codes that are defined in the MQTT 5 specification.
We recommend that you use reason codes that are suitable for both CONNACK and DISCONNECT packets so you do not have to distinguish between initial authentication and re-authentication.
|
The following table shows which reason codes can be used for initial authentication (CONNACK reason code) and/or re-authentication (DISCONNECT reason code):
| Disconnected Reason Code | Initial authentication | Re-authentication |
|---|---|---|
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
An EnhancedAuthenticator can be provided by an EnhancedAuthenticatorProvider.
The EnhancedAuthenticatorProvider can be registered via the Security Registry.
The provider is only called once per client connection.
This enables the EnhancedAuthenticator to store state between the initial authentication and later re-authentications.
An EnhancedAuthenticator object can be used to authenticate different clients by returning the same object in the EnhancedAuthenticatorProvider.
Sharing the same object has the following requirements:
-
The implementation does not store the authentication state in the object.
-
The implementation is thread safe.
Client Settings
The output parameters of authenticators provide ModifiableClientSettings for configuring the client specific restrictions.
Client Receive Maximum
For MQTT 5 clients, this setting allows you to override the Receive Maximum that the client provided in the CONNECT packet.
For MQTT 3 clients, this setting allows you to set a Receive Maximum.
public class ModifyRestrictionsAuthenticator implements SimpleAuthenticator {
@Override
public void onConnect(SimpleAuthInput simpleAuthInput, SimpleAuthOutput simpleAuthOutput) {
ModifiableClientSettings clientSettings = simpleAuthOutput.getClientSettings();
clientSettings.setClientReceiveMaximum(10);
}
}
Overload Protection Throttling Level
This setting enables you to set the overload protection throttling level on a per-client basis.
You can disable the overload protection for a client (NONE).
Use the overload protection throttling level NONE with extreme care.
This option leaves HiveMQ unprotected against misbehaving clients.
This may lead to out of memory errors.
|
Client Queue Size Maximum
Clients will use per default the globally configured max-queue-size.
This may not always the ideal queue size for clients.
It is possible to overwrite it in the ModifiableClientSettings like in the following example:
public class ModifyRestrictionsAuthenticator implements SimpleAuthenticator {
@Override
public void onConnect(SimpleAuthInput simpleAuthInput, SimpleAuthOutput simpleAuthOutput) {
ModifiableClientSettings clientSettings = simpleAuthOutput.getClientSettings();
clientSettings.setClientQueueSizeMaximum(10);
}
}