MQTT Security Fundamentals: OAuth 2.0 & MQTT

mqttsecurityfundamentals_part7

Welcome to the seventh part of the MQTT Security Fundamentals series. The topic for this post is OAuth 2.0 and MQTT. You will learn what OAuth 2.0 is and how it can be used with MQTT. Before reading this post it’s recommended to read the posts about authentication and authorization first.

The scope of this post is to introduce OAuth 2.0 and explain how it could be used with MQTT. There are a lot of different use cases in which OAuth 2.0 could play a role in IoT. This post will explain the basic concepts and obstacles, but will not provide solutions for all possible scenarios. If you have specific questions after reading the post, please leave us a comment.

What is OAuth 2.0 ?

OAuth 2.0 is an authorization framework, that allows a third party to access a resource owned by a resource owner without giving unencrypted credentials to the third party. For example a mobile app wants to access your Facebook profile to post status updates. You don’t need to give your Facebook password to the app, instead you log into Facebook and as a result the app is authorized to use Facebook on your behalf. You can also revoke this authorization any time by deleting the privilege in the Facebook settings.

How does it work?

In order to understand OAuth 2.0 we explain the different roles that are involved:

Resource Server
A resource server has resources, which need protection and can only be accessed by authorized users. Access is granted when the client shows a valid access token, which allows the access to the specific resource. In the example above this would be the Facebook server.

Resource Owner
The resource owner is a human, who owns the resource on the resource server. In the example this would be the person, who owns the Facebook account, which is stored on the Facebook servers.

Client
The client is an application, which needs to access a resource on the resource server, which belongs to the resource owner. In the example, the client would be the mobile app.

Authorization server
The authorization server is a central server, which controls the access to all resources. It can issue tokens to clients and also revoke issued tokens. The authorization server and the resource server must trust each other. In the example this would be the Facebook authorization server.

In the following a simplified OAuth 2.0 flow shows how the different roles interact with each other.

oauth-simple

Tokens

OAuth 2.0 commonly uses JSON Web Tokens (JWT), which are JSON objects with base64 encoding. A JWT contains header, payload and signature. The header of each token contains information about the cryptographic algorithms for signature and encryption. The payload of the token hold some basic claims about the token (issuer, issue date, expiration date, audience, scope, ..) and can be extended with own information. Each token will be signed by the authorization server, so the resource server can validate the issuer is the trusted authorization server and not somebody else.

OAuth 2.0 uses two different types of JWTs: Access Tokens and Refresh Tokens. An access token is a rather short-living token, which grants access to a certain resource. The expire date is commonly between one hour and one day. A refresh token can not be used to access a resource, but it is needed to get a new access token from the server, when the previous one is expired. Refresh tokens have rather long expiration dates compared to access tokens.

OAuth 2.0 authorization grant types

The specification describes four different flows, which can be used to authorize a client and retrieve an access token from the authorization server. We will explain each of them briefly. Before diving in it has to be noted that OAuth 2.0 has been designed for the usage with HTTP and web applications. Therefore some flows are very specific to this kind of application architecture. For more detailed information on the different grant types, please see the OAuth 2.0 specification.

Authorization Code

The authorization code flow is specifically designed for trusted clients (web application), where the web browser of the user should never see the access token. So when a client tries to access a resource the web browser will be redirected to a login window from the authorization server. After the resource owner was successfully authenticated an authorization code will be send back to the browser. Then the web browser sends the code to the client, which then requests an access token from the resource server.

Implicit

This flow is meant for public clients, where the trust only comes from the interaction of the resource owner with the authorization server. After the resource owner got redirected and successfully logged in, the web browser will get an access token directly from the authorization server. It will hand over the token to the client, which is able to access the resource.

Resource Owner Credentials

This flow is used when the resource owner has trust into the client application. For example when you want to log into the Dropbox mobile app which is created by Dropbox, you can enter your password, because Dropbox has it anyways. The resource owner enters his credentials directly into the client application and then the client requests an access token and a refresh token from the authorization server. After receiving the tokens the client should drop the credentials.

Client Credentials

If the client application can access resources the client credential flow can be used. The specification is very vague on the authentication method and declares it out of scope. The client has to authenticate with username password or any other method and receives an access token as response. It can use the access token to request the resource from the resource server. In this flow no refresh tokens should be used, because the client can provide the credentials again any time.

OAuth 2.0 and MQTT

The official OAuth web site describes OAuth as:

An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service. –oauth.net

That already makes cleat that OAuth 2.0 was designed for the HTTP protocol. If somebody is still not convinced, the specification also states that

This specification is designed for use with HTTP. The use of OAuth over any protocol other than HTTP is out of scope. – OAuth 2.0 specification

If you look at the just described OAuth flows, it is obvious that a constrained IoT device, which is out in the field without human interaction is a scenario that is not covered by the OAuth specification. At least three of the four OAuth flows do not make sense without human interaction, only the Client Credential Flow is an exception.

oauth-clientcredential

But the difficulty with this flow is that the MQTT client must hold the credentials. The reason why using OAuth 2.0 in the first place is that no credentials are on the client, which is exactly what the Client Credential flow suggests. So the key questions is how to authenticate the client towards the authorization server. This depends on a lot of different factors, e.g. provisioning, capabilities, trustworthiness and location of the device. Also some device do have the possibility for human interaction, like a mobile app using MQTT. There are a lot of different scenarios, which can not be covered in this post. We will probably write a post about this topic in the future.

Connect to an MQTT broker with an Access Token

If the client has successfully retrieved an access token, it can send it to the broker in the CONNECT message using the password field. The username can be a special string for recognizing token usage. The limit of a password in MQTT is 65535 bytes, so the token can’t be longer than that.

When the broker gets the token it can do different types of validations:

  • Check the validity of the signature from the token
  • Check if the expiration date of the token has already passed
  • Check on the authorization server if the token was revoked

When using HiveMQ these validation can be done by using a custom plugin and adding the validations in an authentication callback.

Only when all of the validation succeed, the client is successfully connected to the broker.

Publish/Subscribe with an Access Token

The same validations used when connecting to the MQTT broker can be used when clients want to publish or subscribe. In MQTT often a huge number of publish and subscribe message messages occur constantly, so some kind of caching is needed to avoid performance losses when validating the Token every time a publish or subscribe message happens. Additionally when publishing or subscribing, the broker needs to authorize the client. This can be done in two different ways:

  • The token has the authorization for the client included in the scope claim
  • The broker has a third party source, for example a database or LDAP to look up the authorizations for the client.

With the limitation of a token to only 65535 bytes, a third party is needed when all the authorization rules don’t fit into that length.

This was a first introduction into OAuth 2.0 and how it fits together with MQTT. In this post we only scratched the surface of the whole topic. So there will be most likely another post in the future we a more focused and in detail view of individual parts of OAuth 2.0 and MQTT. Let us know if you would be interested in that in the comments!

We hope you enjoyed the seventh part of the MQTT Security Fundamentals, if you want to get notified as soon as we publish the next post, you can subscribe to our newsletter or RSS feed. You think we have missed some important information? Please tell us, we are always open to questions and suggestions.

8 comments

  1. Preethi Ramamurthy says:

    How does it work in the case of a human interaction using the device. eg. a mobile phone using MQTT? How can the OAuth mechanism be used in such a scenario?

  2. Hi Preethi,

    This is an interesting question and can’t be answered in general.
    For the most cases it would be possible that the process of retrieving an access token or authorization grant happens before connecting to the MQTT broker. For example over HTTP.
    If you want to only use MQTT than a separate broker and an individual process to retrieve the tokens is necessary.
    Because OAuth 2.0 is only a framework and designed for HTTP, this wouldn’t most likely be compatible with the standard.

    Hope that helps,
    Christian

    1. Preethi Ramamurthy says:

      Hi Christian,

      Thanks for the reply. I am new to this field. So if I understand you correctly, you say that the initial authorization between the resource owner and the authorization server has to be done using HTTP when a human using mobile phone scenario is considered. And after the initial authorization between the resource owner and the server is done, we could setup the connection between the device (smartphone) and the server/broker as like in MQTT? Am I right?

  3. Hi Preethi,

    yes, that would be one way of doing it.
    Another one would be to handle the initial request for an access token over a separate MQTT broker and don’t use any HTTP at all. But it is a challenge to still be compliant to the OAuth 2.0 spec.

    Best regards,
    Christian

  4. Mac says:

    [quote]to avoid performance losses when validating the Token every time a publish or subscribe message happens[/quote]Please, can you explain this sentence? I thought, token validation is needed only on CONNECT event, not on every publish/subscribe events. Or am I mistaken? Thanks!

  5. Hi Mac,

    very good question! If you only validate the token on CONNECT messages, the token could get revoked or gets invalid and the broker won’t notice it, because MQTT clients can have *very* long sessions without disconnects (and subsequent new CONNECT messages). So to be safe, the token could get validated on every “action” from a client. This needs proper caching, though, as each client can send many messages and there is no point in validating the token multiple times per second. We have seen deployments where the token is cached for 5-10 minutes and gets re-validated on the next action.

    Hope this helps,
    Dominik

  6. Gaurav Garg says:

    Really good article , very informative

  7. About the client_credentials grant authentication, I would suggest that the terms “client_id and client_secret” are more appropriate than “username and password” when it comes to client credentials.

    The OAuth 2.0 specification does not explicitely give an authentication mechanism (they don’t like to), but they do give a huge hint in their example : https://tools.ietf.org/html/rfc6749#section-4.4.2
    The access token request uses basic authentication, where a confidential client can safely put “client_id:client_secret”, base64 encoded. That’s the way Spring Security OAuth 2.0 (Java) has implemented the client_credentials grant in their authorization server, and I think it makes a lot of sense.

Leave a Reply

Your email address will not be published. Required fields are marked *