Advanced Authentication Mechanisms - MQTT Security Fundamentals
In the last post of our MQTT Security Fundamentals series, we explained the basics of authentication and how the MQTT protocol provides a username and password in the CONNECT message for authentication. This post introduces more ways to authenticate a client and shows you how to implement authentication on the MQTT broker.
MQTT Authentication with Other Information
In the last post, we learned that authentication confirms the identity of something or someone. We also saw how a username and password combination can be used for authentication. In addition to the username and password, MQTT clients provide other information that can be used for authentication:
Every MQTT client has a unique client identifier. The client provides this unique ID to the broker in the MQTT CONNECT message. The client ID can have a maximum of 65535 characters (the MQTT 3.1.1 specification removed the previous limit of 23 characters). It’s common practice to use the 36 character Universal Unique Identifier (UUID) or other unique client information as the client ID. For example, the MAC address of the network module or the device serial number. In the authentication process, client IDs are often used in combination with the username and password. A common way to confirm if a client can access the MQTT broker is to validate the username/password and the client ID that is correct for that credential combination. It is also possible to ignore the username/password and just authenticate against the client ID; however, this method is not a good security practice. (For some closed systems, this type of authentication may be sufficient).
Another possible authentication method is using the X.509 client certificate. The client presents this certificate to the broker during the TLS handshake (we explain more about transport level security and how SSL/TLS works with MQTT in a later post). After a successful TLS handshake, some brokers such as HiveMQ permit use of certificate information for application layer authentication. This enables the broker to read all of the information in the certificate and use it for authentication purposes as well. If you provision IoT devices, X509 client certificates can be a very good source for authenticating clients on the MQTT broker.
Implementing Authentication with HiveMQ MQTT Broker
We’ve seen that there are different types of information available for authentication of an MQTT client. Now, it’s time to wire the MQTT broker and the authentication store, which can be a database, a webservice, a LDAP directory or a simple access control list (ACL). Let’s take a look at how authentication logic can be implemented on the HiveMQ MQTT broker. The HiveMQ broker has an open source plugin system that allows you to hook into different events on the broker. HiveMQ offers various callback interfaces that are very easy to implement in custom plugins. The broker calls the plugin implementations at runtime. HiveMQ provides the OnAuthenticationCallback interface for authentication.
This callback implementation is sufficient for customizing the authentication mechanism to your use case. The callback method has one parameter of type ClientCredentialsData. This parameter contains all data that HiveMQ obtained from the connecting client. You can use this data to verify the client ID, username, password, and the certificate of the client. If the client presents valid information for authentication, this callback returns the value true.
There are two ways to decline authentication:
- Returning the value false
- Throwing an Exception
If the callback returns the value false, HiveMQ checks for other installed plugins and requests authentication from them. If one of these plugins returns the value true, HiveMQ authenticates the client. To prevent HiveMQ from checking other plugins and refuse the connection immediately, an exception must be thrown. In case of an exception, it is also possible to modify the CONNACK return code. We have an extensive example using a dummy implementation of username/password authentication on GitHub.
Callbacks must be registered with HiveMQ by adding them to the callback registry. This can be done easily in the main class of a plugin. The main class is required for each plugin and needs to extend the interface PluginEntryPoint. The callback is injected via dependency injection and added to the callback registry. Once the plugin is on the registry, it can be used with the HiveMQ broker.
You can find ready-to use, open-source, HiveMQ plugins for authenticating clients in our plugin directory. For example, the File RBAC Extension for ACLs. If you need more information about how to develop, run, and deploy a custom authentication plugin for the HiveMQ broker, see the plugin developer guide.
This brings us to the end of the authentication part of MQTT Security Fundamentals. In the next post, we dive into topic-level authorization with MQTT.
We hope you enjoyed part three of the MQTT Security Fundamentals series. If you want to stay updated or get notified of our new content, subscribe to our newsletter or RSS feed. Feel free to use the comments section to ask questions or to leave feedback.