An OAuth2 Grant Selection Decision Tree for Securing REST APIs
In this article, I will explain the four types of grants and guidelines for selecting each grant based on a simple decision tree.
Join the DZone community and get the full member experience.
Join For FreeOAuth2 Protocol, Grants, and Guidelines for Selecting Grants
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 to understand the fundamentals of OAuth grants before securing REST APIs using OAuth, as it would directly impact the 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 the OAuth2 protocol.
- Resource Owner: The resource owner would be the user who owns the resources hosted on the resource server.
- Client: This is 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, the 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 log in, 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 download 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 on 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 log in, 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 be suitable for first-party applications that users would 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 and 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 responds 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:
Figure 6: Grant Selection Decision Tree, Reference
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, the 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 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 makes 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 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 an 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 a 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/
Published at DZone with permission of Imesh Gunaratne. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments