An OAuth2 Grant Selection Decision Tree for Securing REST APIs

OAuth2 protocol, grants, and guidelines for selecting grants

Imesh Gunaratne
Feb 18, 2018 · 9 min read

One of the most widely used security protocols for securing REST APIs is OAuth2. The OAuth2 specification defines four different grant types for obtaining access tokens depending on the type of the access token owner, type of the application and the level of trust that you have with the application. It would be quite important understand the fundamentals of OAuth grants before securing REST APIs using OAuth as it would directly impact on application security and user experience if they are not properly used. In this article, I will explain the four types of grants and guidelines for selecting each grant based on a simple decision tree.

Abstract Protocol Workflow

Let’s first understand the roles used in the OAuth2 specification:

  • Resource Server
    The resource server can be considered as a web server which would host a collection of resources and protect them using OAuth2 protocol.
  • Resource Owner
    The resource owner would be the user who owns the resources hosted on the resource server.
  • Client
    This would the client application which would provide access to the resources hosted on the resource server on behalf of the resource owner with authorization.
  • Authorization Server
    The authorization server would issue access tokens to the client after successfully authenticating the resource owner and obtaining authorization. In some scenarios, resource server would also act as the authorization server.

As the first step, a client application would need to register itself in the resource server and obtain a client id and a client secret for accessing required resources. Afterwards, it would need to go through three main steps for accessing protected resources, namely; authorizing the resource owner and retrieving an authorization grant, obtaining an access token using the authorization grant, and accessing protected resources using the obtained access token. OAuth specification defines four different grants based on the nature of the client application:

  • Client Credentials Grant
  • Authorization Code Grant
  • Implicit Grant
  • Resource Owner Password Credentials Grant

1. Client Credentials Grant

The Client Credentials Grant might be the simplest grant in OAuth2 specification. It has been designed to be used for machine to machine communication where the end user identification is not necessary for resource authorization. In this approach, the client application itself acts as the resource owner and make use of the client credentials for obtaining access tokens:

Step A: Authentication Request:

First, the client application makes an authorization request to the authorization server by providing the client credentials in the Authorization header and the grant type in the message body:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials

Step B: Authentication Response:

If the authentication request is successful, the authorization server will respond with an access token, access token expiration time, and any other application specific parameters:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}

Step C: Resource Request:

Thereafter, the client application will use the access token for requesting resources hosted on the resource server:

GET /example/resource HTTP/1.1
Host: server.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

2. Authorization Code Grant

Authorization Code Grant might be the most widely used grant for publicly available client applications. As illustrated in the above figure, this approach uses browser redirections for communicating with the resource server and the authorization server. It has been purposely designed for web applications that execute its logic on a web server and which have the capability to store the client credentials securely without being exposed to the client application that runs on a web browser.

Step A: Authorization Request:

First, the client application makes an authorization request by redirecting the user to the authorization server by specifying the response type, client id, and the redirection URL:

GET /authorize?response_type=code
&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

Step B: User Authentication:

Then, the user will be prompted to login either on the authorization server itself or by federating to a third party identity provider.

Step C: Authorization Response:

Once the authentication is successful, the authorization server will redirect the user back to the client application by providing an Authorization Code in a query parameter in the Location HTTP header.

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz

Step D: Access Token Request:

Afterwards, the client application will make another request to the authorization server to obtain an access token using the given authorization code. In this request, the client credentials will be provided in the Authorization header, in addition the grant type, authorization code, redirection URL will be sent in the message body:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

Step E: Access Token Response:

If the token request is valid, the authorization server will respond with an access token, expiration time, refresh token and any other application specific parameters:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}

Step F: Resource Request:

Thereafter, the client application will use the access token for requesting resources hosted on the resource server:

GET /example/resource HTTP/1.1
Host: server.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

3. Implicit Grant

The Implicit Grant has been designed for client applications such as client side web applications that downloads its code and executes on a web browser which cannot securely store its client credentials. Unlike the Authorization Code Grant, this does not use client credentials for authenticating the client application. Instead, it relies one the resource owner authentication for providing the access token.

Step A: Authorization Request:

First, the client application will make an authorization request to the authorization server by specifying the response type, client id, state (an opaque value such as a CSRF token for preventing cross-site request forgery attacks) and the redirection URL:

GET /authorize?response_type=token
&client_id=s6BhdRkqt3
&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

Step B: User Authentication:

Then, the user will be prompted to login either on the authorization server itself or by federating to a third party identity provider.

Step C: Access Token Response:

Once the authentication is successful, the authorization server will respond with an access token, state, token type, and token expiration time:

HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
&state=xyz
&token_type=example
&expires_in=3600

Step D: Resource Request:

Thereafter, the client application will use the access token for requesting resources hosted on the resource server:

GET /example/resource HTTP/1.1
Host: server.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

4. Resource Owner Password Credentials Grant

The Resource Owner Password Credentials Grant has been designed to be used when the resource owner has a trust relationship with the client application for providing user credentials directly to the client application without redirecting to the authorization server. According to the specification this grant should only be used when other flows are not viable as it may only suitable for first-party applications that users would have trust.

Step A: Authentication Request:

First, the client application will make an authentication request to the authorization server by providing the client credentials in the Authorization header, and the grant type, user credentials in the message body:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

Step B: Access Token Response:

If the authentication/access token request is successful, the authorization server will respond with an access token, token expiration time, refresh token and any other application specific parameters:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}

Step C: Resource Request:

Thereafter, the client application will use the access token for requesting resources hosted on the resource server:

GET /example/resource HTTP/1.1
Host: server.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

Refresh Token Workflow

Once an access token is obtained using one of the above grants, it has been designed to expire after the given token expiration time for providing additional security. Due to this design the client application will need to use the refresh token for obtaining a new token when the existing token expires. Even though this can be implemented by using a timer on the client application for obtaining a new token when the expiration time occurs, the best practice is to make an additional call to obtain a new token when the authorization server respond with the invalid token error.

The following is a sample HTTP POST request for obtaining a new access token using the refresh token:

POST /token HTTP/1.1
Host: server.example.com
grant_type=refresh_token
&client_id=3MVG9lKcPoNINVBIPJjdw1J9LLM82HnFVV
&client_secret=12312342342wefsdfsf3241334
&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

Grant Selection Decision Tree

According to the OAuth2 specification the grant selection for securing an API using OAuth2 can be taken based on the requirements for end user identification, client type (server side web application, native application, client side web application) and the level of trust the resource owner would have on the client application:

If the resource server does not require identifying the end user who interacts with the client application, and if the client application itself acts as the resource owner it can use the Client Credentials Grant for obtaining access tokens for accessing protected resources in the resource server. In this approach client application only requires client credentials for issuing access tokens and it does not keep track of the end user. This approach would be suitable for server to server communication.

If the end user identification is needed in the resource server for authorization, and if the client is either a server side web application or a native application accessed by third party users, the OAuth2 specification recommends using the Authorization Code Grant. This is the most recommended grant for securing resources accessed by publicly hosted applications and third party users due to its design of exchanging authorization codes for access tokens. In this design, the native applications will use operating system features or authorization server SDKs for managing the redirections similar to web applications.

If the end user identification is needed in the resource server for authorization, and if the client application is a either a client side web application or a native mobile or desktop application that is used by the first party, the Resource Owner Password Credentials Grant can be used for obtaining access tokens. In this workflow, both user agent based and native applications do not require to store client credentials on their applications. Instead, it make use of the end user credentials for obtaining the access tokens for increased security. Moreover, it is important to note the requirement of the trust between the resource owners and the client because of users would need to provide their user credentials in the client application itself.

If providing user credentials directly to the client application is a concern and if the authorization is done via a third party authorization server the Implicit Grant can be used for client side web applications which require end user identification. It will make use of browser redirection to navigate the user to the authorization server and obtain access token via the response flow.

Conclusion

OAuth2 specification defines four main grants for obtaining access tokens according to the nature of the client application and authorization requirements of the resources. Therefore, it is important to understand the fundamentals of these grants before using OAuth2 for securing REST APIs. If grants are used inappropriately, security vulnerabilities may occur and systems may get exposed to attackers very easily. For an instance, if Client Credentials Grant is used in a client side web application or a native mobile application an attacker would be able to extract client credentials without much effort by either reading its source code or application content.

References

The OAuth 2.0 Authorization Framework, Internet Engineering Task Force (IETF), https://tools.ietf.org/html/rfc6749

The OAuth 2.0 Authorization Framework: Bearer Token Usage, Internet Engineering Task Force (IETF),https://tools.ietf.org/html/rfc6750

Proof Key for Code Exchange (PKCE) by OAuth Public Clients, Internet Engineering Task Force (IETF), https://tools.ietf.org/html/rfc7636

The OAuth 2.0 Authorization Framework, Alex Bilbie, https://alexbilbie.com/guide-to-oauth-2-grants/

Scalable

Industry best practices for implementing scalable enterprise applications

Imesh Gunaratne

Written by

Engineer at Google

Scalable

Scalable

Industry best practices for implementing scalable enterprise applications

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade