In Previous version of WSO2 Message Broker it only supports the extensibility for authentication for MQTT. This can be configured by implementing the IAuthenticator interface that was provided by MB and this can be configured in the broker.xml.
OPTIONAL
In the above configuration making authentication to “REQUIRED” will make sure that the unauthenticated client cannot connect to the broker. In here the authentication implementation class that was implemented the IAuthenticator interface needs to be given under authenticator. Below is the flow of the architecture and the common idea on how authentication and authorization needs to be implemented in MQTT Broker. When a client wants to publish/subscribe then they have to follow two steps. Step 1 : Client connects to the Broker Step 2 : Client publish/subscribe to topics. In mqtt the connection and publish/subscribe are two separate steps. Client id can be any unique id used to create the mqtt connection. Once the connection is made (Step 1) to the broker it authenticates the connected client and stores the unique "clientId" in the session. Furthermore two clients with same clientId cannot connect to the broker at the same time, it allows only one to be connected. In a subsequent call for subscription/publish, the broker authorizers the client against the clientId created for the connection. And this clientId is retrieved from the session related to the connection in Step 1. In addition if we think about authorization then there should be two levels to consider. Level 1 : Is the client authorised to connect to the broker (Authorization in Step 1) Level 2 : Is the client authorised to publish or subscribe to a specific topic (Authorization in Step 2). Therefore to resolve this we have introduced a new interface called “ IAuthorizer”. public interface IAuthorizer { /** * Check whether the user is authorized to connect to the server. * @param authorizationSubject passed from authentication. * @return */ boolean isAuthorizedToConnect(MQTTAuthorizationSubject authorizationSubject); /** *
* @param authorizationSubject passed from authentication. * @param topic that the client is requesting for access. * @param permissionLevel request permission level. This is either publish or subscribe. * @return */ boolean isAuthorizedForTopic(MQTTAuthorizationSubject authorizationSubject, String topic, MQTTAuthoriztionPermissionLevel permissionLevel); }
When a client connects to the broker then after the authentication “isAuthorizedToConnect” method will be triggered. In here “MQTTAuthorizationSubject” parameter that is passed to this method consist of authentication and client connection request parameters. Therefore this will allow us to authorize the client by whether it has the permission to connect and also it is also possible to verify whether the client is authorized to connect with specific mqtt connection properties (ie : QOS). Similarly if the client is authorized to connect to the server then the next step would be that the client can publish/subscribe. Therefore whenever a client publish/subscribe to a topic then “isAuthorizedForTopic” method will be triggered in IAuthorizer implementation. This method will receive 3 parameters, They are : ● MQTTAuthorizationSubject : Client information that needs to be authorized. ● Topic : Topic that the client is trying to publish or subscribe. ● MQTTAuthoriztionPermissionLevel : Publish/Subscribe
Whenever a client connects then it will trigger the IAuthorizer implemenation that is mentioned in broker.xml configuration: NOT_REQUIRED "> Please note that the authentication should be REQUIRED inorder for the authorization to be REQUIRED. By default we have provided following authentication and authorization extension with the WSO2 MB. Authentication Extension For Authentication we have supported BASIC and OAUTH. Configuration for Basic: Configuration for OAUTH:
https://localhost:9443/services/OAuth2TokenValidationService admin admin 10 150 MQTT specification only has fields for basic authentication. However in specification it has been mentioned[1] : "The CONNECT Packet contains Username and Password fields. Implementations can choose how to make use of the content of these fields. They may provide their own authentication mechanism, use an external authentication system such as LDAP [RFC4511] or OAuth [RFC6749] tokens, or leverage operating system authentication mechanisms." There are existing studies on how to support token based authentication by extending the current authentication model. Such as the model explained in the paper[2]. Therefore we provided this capability with the Message Broker by creating an implementation of the interface, In here for OAUTH Validation we have used the WSO2 Identity Server In the current authentication model the message broker can load only one authenticator, which is by default uses the CarbonBasedMQTTAuthenticator and this supports basic authentication. We have created another authenticator to support the token based authentication. In this implementation token needs to be passed along with the username field. Authorization Extension We have have a done basic authorization implementation based on Carbon Permission model. Where we have mapped the topic directly to the permission hierarchy. Please note this implementation will only be practical for static topics. Therefore recommended approach would be to implement this interface according to the use cases. Below is the configuration for the permission based authorizer. /permission/admin/mqtt/connect
In here the “connectionPermission” is the permission that required for the client to connect to the broker then once its connected then the topic is mapped directly to a permission and this permission is cross checked with the user. e.g.: If a client wants to publish to wso2/apimgt or wso2/iot then the client requires the minimum permission for : /permission/admin/mqtt/topic/wso2/apimgt and /permission/mqtt/topic/wso2/iot respectively with the action 'publish'. In here "/permission/admin/mqtt/topic" is a prefix for all topics to map into one hierarchy. Further if the client has permission for /permission/mqtt/topic/wso2 with the 'publish' action then the client can publish to both wso2/apimgt or wso2/iot topics. Similarly subscriber requires the permission with the action 'subscribe'. [1] http://docs.oasisopen.org/mqtt/mqtt/v3.1.1/mqttv3.1.1.html [2] http://eprints.port.ac.uk/15538/1/oauth_mqtt3.pdf