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. Learn what OAuth 2.0 is and how it can be used with MQTT. Before you jump into this post, it’s a good idea to read the previous posts on authentication and authorization first.

The scope of this post is to introduce OAuth 2.0 and explain how it can be used with MQTT. In IoT, there are a lot of different use cases that involve OAuth 2.0. This post explains the basic concepts and obstacles, but does not attempt to provide solutions for all possible scenarios. If you have specific questions after reading the post, please start a conversation with us in the comments.

What is OAuth 2.0 ?

OAuth 2.0 is an authorization framework that allows a client to access a resource that is owned by a resource owner without giving unencrypted credentials to the client. 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 authorize the app to use Facebook on your behalf. You can revoke this authorization anytime by deleting the privilege in the Facebook settings.

How does it work?

To understand OAuth 2.0, you need to understand the different roles that are involved:

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

Resource Owner
The resource owner is a human who owns the resource on the resource server. In the example, the resource owner is the person who owns the Facebook account that is stored on the Facebook server.

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

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

This 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 token 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 holds some basic claims about the token (issuer, issue date, expiration date, audience, scope). You can extend the payload with your own information. Each token is signed by the authorization server so the resource server can validate that 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 short-living token that 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.The refresh token is needed to get a new access token from the server once the previous one expires. Refresh tokens have longer expiration dates than access tokens.

OAuth 2.0 authorization grant types

The specification describes four different flows that can be used to authorize a client and retrieve an access token from the authorization server. We will explain each flow briefly. Before we dive into the explanation, keep in mind that OAuth 2.0 has been designed for use 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. When a client tries to access a resource, the web browser is redirected to a login window of the authorization server. After the resource owner is successfully authenticated, an authorization code is sent back to the browser. The web browser sends this code to the client, which then requests an access token from the resource server.

Implicit

The implicit flow is meant for public clients where trust comes only from the interaction of the resource owner with the authorization server. After the resource owner is redirected and successfully logged in, the web browser receives an access token directly from the authorization server. The web browser hands the token to the client. The client can then access the resource.

Resource Owner Credentials

The resource owner credentials flow is used when the resource owner trusts the client application. For example, when you want to log into the Dropbox mobile app that Dropbox created, you can enter your password, because Dropbox knows your password anyway. The resource owner enters their credentials directly into the client application. The client then requests an access token and a refresh token from the authorization server. After the client receives the tokens, it 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. The client 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 in the following way:

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

This quote emphasises that OAuth 2.0 was designed for the HTTP protocol. Additionally, the specification includes this statement:

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

When you look at the OAuth flows, it is obvious that a constrained IoT device, which acts without human interaction is not covered by the OAuth specification. Three of the four OAuth flows do not make sense without human interaction. The Client Credential Flow is an exception.

oauth-clientcredential

The client credential flow, however, requires that the MQTT client holds the credentials. The reason to use OAuth 2.0 for MQTT in the first place is to avoid storing credentials on the client, which is exactly what the Client Credential flow suggests. The key questions is how to authenticate the client towards the authorization server. The answer depends on many different factors (provisioning, capabilities, trustworthiness, and location of the device). Additionally, some devices do have the possibility of human interaction, for example, a mobile app using MQTT. Howerver, there are numerous other scenarios that cannot 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 acquired an access token, it can send this token 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 the expiration date of the token.
  • Check on the authorization server if the token was revoked.

When you use HiveMQ, these validation can be done by a custom plugin during the authentication callback.

Only if all of validations succeed, the client is connected to the broker.

Publish/Subscribe with an access token

The same validations that are used for connecting to the MQTT broker can be used when clients want to publish messages or subscribe to a topic. In MQTT, it is common that a large number of publish and subscribe messages are send. A caching implementation is needed to avoid performance degradation when validating the token each time for every message. Additionally, when publishing or subscribing, the broker needs to authorize the client. This client authorization can be achieved in two different ways:

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

Since the size of the token is limited to only 65535 bytes, a third party is needed when the authorization rules exceed the token size limit.

This was a quick introduction to OAuth 2.0 and how it fits together with MQTT. In this post, we barely scratched the surface of the topic. We probably need another post in the future to delve into the individual parts of OAuth 2.0 and MQTT. If you would be interested in a more detailed post, let us know 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, subscribe to our newsletter or RSS feed. If you think that we missed some important information, please tell us in the comments. We are always open to questions and suggestions.

10 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

    1. David Karlsson says:

      Would You cache the token in the broker, or is it actually a part of the content in each pulblish call?

    2. Hi David,

      Nice to see you are taking an interest in MQTT and HiveMQ.
      Usually the Token is passed in the username or password field, when the MQTT connection is established.
      For Authentication purposes authenticating it once for validation should suffice.
      Should you also implement Authorisation mechanisms that might for instance be based on the claims of the token, we recommend caching the Authorisation results.

      Hope this helps.

      Kind regards,
      Florian from The HiveMQ Team.

  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 *