Introduction
In our last post, we went over the OAuth 2.0 Resource Owner Password Credentials grant type. In this post we will move forward and cover another grant type, the Authorization Code grant.
OAuth 2.0 Quick Overview
OAuth 2.0 is about delegating access between entities using a token that defines the scope of access allowed. Using a token instead of a username and password combo allows the resource owner to give a client access to resources without giving up your personal username and password information. OAuth 2.0 RFC-6749 Defines the different roles that each entity in this process plays, since we will be referring to these roles throughout this blog post, here is a quick overview of each role.
- Resource Owner: The entity who is granting access to a protected resource.
- Resource Server: The thing that is protected and takes access tokens. In our case, the REST API.
- Client: The application that needs to access the Resource Server.
- Authorization Server: The server that issues an access token once you have authenticated successfully as the Resource Owner.
These are the four different grant types that OAuth 2.0 provides:
- Client Credentials
- Resource Owner Password Credentials (ROPC or Password Grant Type)
- Implicit
- Authorization Code
Authorization Code Grant Type
The Authorization Code grant type is very common and is used by both confidential and public clients to exchange an authorization code for an access token. The difference being that a confidential application can keep a client password secret to the world at large, whereas a public client is an application that would not be able to ensure that the password is kept confidential. The Authorization Code grant is commonly used when the client is a web app executing on a server, a native or mobile app, or a SPA (single page application). A major difference that sets this grant type apart is that it requires the application requesting access to launch a browser or some type of user-agent to engage in the authorization flow. In certain applications it is a best practice to enable the PKCE (Proof Key for Code Exchange) extension of this flow for an added layer of security.
Here is a brief overview of the steps in this flow, using a web browser as the user agent:
- The Client begins the flow by (usually) opening a web browser to send the Resource Owner to the authorization page on the Authorization Server.
- The Resource Owner (User) sees the authorization prompt and approves the Client’s request.
- The Client is redirected back to the application with an Authorization Code that is included in the redirection URI.
- The Client then exchanges the Authorization Code for an access token from the Authorization Server.
- If a refresh token is issued with the access token, the Client can use the refresh token to get a new access and refresh token from the Authorization Server without going through the authorization code flow again.
UML Sequence Diagram of Authorization Code Flow
This will be a general overview diagram that will show the Authorization Code Flow. An Explanation will follow, breaking down each step in more detail.
-
- The Client initiates the flow by redirecting the Resource Owner to the authorization endpoint via the User-Agent.
- The Client includes its client identifier, requested scope, local state, and a redirection URI that the authorization server will use to send the user-agent back once access is granted or denied. The scope, state, and redirect URI are technically optional at this point, although state is a recommended value, as it is used to prevent cross-site request forgery in this process.
- Resource owner grants or denies clients request and authenticates with the authorization server via the User Agent.
- If access is granted, the authorization server redirects the user-agent back to the Client using the redirection URI provided in step 1a earlier. The redirection URI includes an authorization code and any local state that was provided by the Client initially.
- The Client having obtained the authorization code requests an access token with the authorization code.
- The authorization server authenticates the Client, validates the authorization code, and ensures that the redirection URI matches the URI used to redirect the Client in step 4. If everything is valid, the authorization server responds with an access token and optionally includes a refresh token.
- The Client can now construct requests for the REST API with the access token.
The above diagram is only a look at the authorization Code flow, there is another part of the flow that has been added on after security concerns, which are discussed below, were raised. This is the Proof for Key Code Exchange, it is recommended for securing the authorization Code flow on a mobile device, or SPA. We will briefly go over PKCE in the next section.
Proof Key for Code Exchange (PKCE)
We are going to do a brief overview of, PKCE (pronounced as “pixy”). PKCE is an extension to OAuth 2.0 designed to prevent an authorization code interception attack. PKCE is primarily applicable to native apps and mobile devices. A malicious app could register itself as the handler of a URI that is also used by a legitimate application on the same device. This way, the malicious app would receive the authorization code as it is redirected to the legitimate application. With this authorization code, the legitimate app could request its own access tokens from the authorization server.
1 Authorization Code Interception Attack
How can we stop an attack like this? Enter PKCE stage left. PKCE leverages the use of a one-time key to secure our OAuth 2.0 authorization code flow. The key that PKCE uses to stop this is a cryptographically random key, called a “code verifier”. A unique “code verifier” is created for each authorization request. The code verifiers transformed value, called “code challenge” is sent to the authorization server to obtain the authorization code. The access token request is then sent to the authorization endpoint with the “code verifier”, the authorization server then compares it with the previously received request code, so it can prove that the Client has possession of the correct “code verifier”. This works because an attacker would not have access to this one-time key. Since the parts of the flow that use this key are sent over TLS and cannot be intercepted.
2 PKCE Visual Aid
Conclusion
The authorization code grant type is widely used and very common, chances are you have used this grant type in your day-to-day life or work, without realizing it. It allows a user to grant a Client access in a way that is streamlined for the end user. When it comes to applicable use cases, the authorization code grant type is a good option for your OAuth 2.0 implementation if your Client is a web app executing on a remote server, a SPA, or if your Client is a Native/Mobile app. For the latter two options, best practices assert that the use of the PKCE extension of this grant type should be used, to prevent an authorization code interception attack.
In this blog we have now covered three of the four grant types:
- Authorization Code
- Client Credentials
- Resource Owner Password Credentials (ROPC or Password Grant Type)
Be on the lookout for our upcoming article on the Implicit grant type!
Reference
https://tools.ietf.org/html/rfc6749
https://tools.ietf.org/html/rfc7636