Hi All, WSO2 MB currently only supports authentication. The current implementation is an extensible approach, where we can plug custom authenticators. However it does not support authorization and this creates a security concern where any one who is authenticated can publish or subscribe to any topics.
This is a concern for IoT use-cases, where if an application needs to publish data(eg: control operation) to a device then we require an authorization layer to validate who can send commands to that particular device. Hence, we have extended the current model in WSO2 MB to support authorization for MQTT. Below is the flow of the architecture and the common idea on how authentication and authorization is supported. 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 the above steps authentication happens in Step 1 and this session will be maintained for Step 2. However 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) Now lets consider how we can solve authorization in both the levels. (Here I have taken OAuth based approach to explain the flow) *Level 1:* eg : Scope based authorization - Step 1: client sends a token - Step 2: validate the token - Step 3 : (if authentication is successful) Check whether the scope related to token matches with the required scope to connect to the client. <authenticator class= "org.wso2.carbon.andes.authentication.andes.OAuth2BasedMQTTAuthenticator"> <property name="hostURL"> https://localhost:9443/services/OAuth2TokenValidationService</property> <property name="username">admin</property> <property name="password">admin</property> <!--<authenticate the user only if below scopes are related to the token. This value can be empty if we wanted skip the authorization for connection Multiple scopes can mentioned by having a space delimiter>--> *<property name="scopes"></property>* <property name="maxConnectionsPerHost">10</property> <property name="maxTotalConnections">150</property> </authenticator> Similarly for Basic Authentication it will follow a role based authorization. In the implementation aspect in the MB this needs to done within the authenticator extension. *Level 2:* In MQTT specification it has been mentioned that: *"An implementation may restrict access to Server resources based on information provided by the Client such as User Name, Client Identifier, the hostname/IP address of the Client, or the outcome of authentication mechanisms."* In here we will be following the second approach where outcome of authentication will be passed to authorization. In Level 2 the required steps to authrozie will be. *Publisher flow*, After the client gets connected then it will publish the message to a particular topic. In here we have the information related to the client which is stored and retrieved after authentication(this could be scopes that are related to the token or the username) and the topic that the client needs to publish. *Subscriber flow* In subscriber flow the client has the similar information as publisher that are retrieved from authentication. However in the subscribe use case it can subscribe to multiple topics. For both instances if the authorization fails then the client will be disconnected from the broker. To achieve this we have created an interface that can be used to plug any authorization logic. This can be simple configured in broker.xml by adding below both tags. <!-- Instructs the MQTT server whether clients should be authorized before either publishing or subscribing Possible values: NOT_REQUIRED: This is the default value. MQTT clients will skip the authorization check REQUIRED: Clients will authorized before publishing/subscribing. this will execute the class given in authorzier Note: authentication should be REQUIRED for authorization to be REQUIRED. --> <authorization>NOT_REQUIRED</authorization> <!--Class name of the authorizer to use. class should inherit from org.dna.mqtt.moquette.server.IAutherizer Note: default implementation authorizes against carbon permission with the topic. --> <authorizer class="org.wso2.carbon.andes.authorization.andes.CarbonPermissionBasedMQTTAuthorizer"/> The reason for having pluggable authorization is because MQTT-topics are designed specific to use cases and these topic could be dynamic. Therefore it is difficult to bring this into a common template. One such example is that in an IoT use case: User sends a specific command to all his raspberry pi devices. User publishes to the topic:*iot/username/raspberrypi/#* Device will be subscribed to the topic: *iot/username/raspberrypi/{deviceId}*. If there are multiple users and device id then it will be mapped to a template such as iot/{username}/raspberrypi/{deviceId}. In this case the authorization should be on whether the user has the access to particular device(extract the username and device id from topic). This needs custom implementation and this is supported through the interface. flow of authentication and authorzation is depicted in below image *Furthermore I have a done basic authorization implementaion based on Carbon Permission model. Where we can map the topic directly to permission hierarchy. This will only be practical for static topics. * e.g.: If a client wants to publish to wso2/clubs or wso2/teamgroups then the client requires the minimum permission for : /permission/mqtt/topic/wso2/clubs and /permission/mqtt/topic/wso2/teamgroups respectively with the action 'publish'. In here "/permission/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/clubs or wso2/teamgroups topics. Similarly subscriber requires the permission with the action 'subscribe'. The source code for this implementation is available in [2][3]. [1] http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html [2] https://github.com/wso2/andes/pull/517 [3] https://github.com/wso2/carbon-business-messaging/pull/256 *Ayyoob Hamza* *Software Engineer* WSO2 Inc.; http://wso2.com email: ayy...@wso2.com cell: +94 77 1681010 <%2B94%2077%207779495>
_______________________________________________ Architecture mailing list Architecture@wso2.org https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture