Close
AlgoliaLogoLight
Close full mode
logo

OAuth 2

Git RepositoryEdit on Github

What is OAuth 2 ?

OAuth 2 is a protocol that grants applications access to protected resources from another application by requesting an authorization grant from the user who owns the resources or the application itself.


Major components

  • Resource owner (user)
  • Client (application)
  • Authorization server
  • Resource server

Flow

The four components will have interaction with each other as below:

1.Authorization Request
2.Authorization Grant
3.Authorization Grant
4.Access Token
5.Access Token
6.Protected Resources
Cilent
Resource Owner
Authorization Server
Resource Server
  1. The client requests access to resources on the target server from the resource owner.
  2. The client receives an authorization grant which is the credentials of the resource owner (eg. username and password). This authorization grant is different depending on the grant type used by the authorization server.
  3. The client authenticates with the authorization server and presenting the received authorization grant.
  4. The authorization server authenticates the client and validates the grant. If the grant is valid, the server will issue an access token to the client.
  5. The client sends the received access token to request resources from the resource server.
  6. The resource server validates the access token and sends resources if valid.

Client Registration

  • Before a client application can request an access to resources on a resource server, the client application must be registered on an authorization server associated with the resource server.
  • The registration is typically a one-time task. Once registered, the registration remains valid, unless the client app registration is revoked.
  • At registration, the client application is assigned a client ID and a client secret (password) by an authorization server.
  • An authorization server will use client ID and secret for authentication a client application and a redirect URI for sending a authorization code.
developerauthorization serverRegister a client application with a 'redirectURI' value.1Get assigned client ID and random secret (password).2developerauthorization server
  • Client ID and secret are unique to a client application on that authorization server.
  • All web, mobile or single page applications for the same client application have the same client ID specific to that authorization server.
  • Given some scenarios that application A has many types of applications e.g. mobile, single page app:
client ID is 'ABC'
client ID is 'ABC'
client ID is 'ABC'
client application A, mobile app on user M's phone
Authorization server X
client application A, single page app on user M's browser
Authorization server X
client application A, mobile app on user N's phone
Authorization server X
  • If a client application registers with multiple authorization servers (e.g. both Facebook, Twitter and Google), each authorization server will issue its own unique client ID to the client application.
  • Given the following example:
client ID is 'ABC'
client ID is 'DEF'
client ID is 'XYZ'
client application A, mobile app on user M's phone
Authorization server X
client application B, mobile app on user M's phone
Authorization server X
client application A, mobile app on user M's phone
Authorization server Y

Redirect URI

  • During the registration the client also registers a redirect URI. This redirect URI is used when a resource owner grants authorization to the client application.
  • When a resource owner has successfully authorized the client application via the authorization server, the authorization server will use the redirect URI to redirect back to the client.
  • ❗❗❗ Don't store a secret on mobile app and single page app. For those kind of the app, use redirect URI and Authorization code grant type with PKCE for security.

Sequence diagrams of each grant type

Assumption

  • We have registered user and client application on Authorization server database.
  • Our authorization and resource are on the different machines.
  • However, the authorization server may be the same server as the resource server or a separate entity as mentioned in https://tools.ietf.org/html/rfc6749#section-1.1

Grant Types

  1. Client credentials

  2. Password

  3. Authorization code

  4. Authorization code with PKCE

1. Client credentials Grant

  • client send client id and secret and get token in response body
  • No URL redirect, if someone can steal id and secret, one can get an access token
  • The main usage is for server to server.
client (application)authorization serverAPI (resource server)send client credentials (client ID and client secret)1If credentials are valid, send access token.2Save tokens and request an API to access a user's resources with an access token in HTTP header.3Verify an access token and send response data back to a client.4client (application)authorization serverAPI (resource server)

2. Password Grant

user (resource owner)client (application)authorization serverAPI (resource server)send credentials (username and password)1send client credentials (client ID and client secret) and user credentials2If credentials are valid, send access token and refresh token back.3Save tokens and request an API to access a user's resources with an access token in HTTP header.4Verify an access token and send response data back to a client.5user (resource owner)client (application)authorization serverAPI (resource server)

3. Authorization code Grant

  • Unlike the Clients Credentials grant type, it involves a user for approval.
  • This process requires a user to logged in before getting an authorization code.
user (resource owner)client (application)authorization serverAPI (resource server)Log in to a client application1Connect to an authorization server with client ID and redirect URI.2Show a form to a user to log in and then ask a user to allow permissions (scopes).3Get approval from a user that a client app can access user's resources.4Save an authorization code temporary and redirect to a redirect URI with an authorization code.5Send HTTP POST with an authorization code to request tokens6Verify the correctness of authorization code clientID, redirectURI. Then send access token and refresh token back.7Save tokens and request an API to access a user's resources with an access token in HTTP header.8Verify an access token and send response data back to a client9user (resource owner)client (application)authorization serverAPI (resource server)
  • If someone can steal client ID and redirectURI, one can't get an authorization code because it requires a user to log in allow permission.
  • However, a hacker can fake a redirect URI and an authorization code especially on mobile device.

4. Authorization code with PKCE

What is PKCE?

"PCKE" stands for "Proof Key for Code Exchange" and usually pronounce "Pixie". It is a superset feature on top of OAuth2 Authorization Code grant type and will be forced to use by OAuth 2.1 for security.

With this grant type, A hacker can get an authorization code and code challenge but cannot know a "code verifier". Then one cannot get an access token.

The flow is similar to regular authorization code grant type, but the client must generate "code verifier" and "code challenge" (from the code verifier) and send the generated code challenge with its credentials to the authorization server.

client (application)authorization servergenerate code verifier and code challenge1connect by presenting client ID, redirect URI, code challenge, and name of method generated the code challenge2client (application)authorization server

Then the authorization server will store the code challenge and send an authorization code to the client.

When the client would to requests an access token, It has to send the received authorization code with code verifier generated at the first. Beside authorization code, the authorization server will also validate the code verifier by generating another code challenge from the received code verifier and comparing it with the stored code challenge before sending tokens.

client (application)authorization serverRequest access token by presenting an authorization code, redirect URI, and code verifier.1Validate code verifier and authorization code, and send tokens back if valid.2client (application)authorization server

Full Diagram:

user (resource owner)client (application)authorization serverresource serverLog in to a client application1Create code verifier and code challenge then connect to an authorization server with client ID, redirect URI, code challenge and method name used to generate code challenge (sha256).2Show a form to a user to log in and then ask a user to allow permissions (scopes).3Get approval from a user that a client can access user's resources.4Generate authorization code and save it with received code challenge temporary and send the code to the client by attach it to the redirect URI and redirect back5Send HTTP POST with an authorization code, redirect URI, and code verifier to request tokens.6Validate code verifier, code challenge, authorization code clientID, and redirectURI then send access token and refresh token back if valid.7Save tokens and request an API to access a user's resources with an access token in HTTP header.8Verify an access token and send response data back to a client9user (resource owner)client (application)authorization serverresource server

In summary, The authorization code flow with PKCE has some extra work as following:

  • code verifier and code challenge generation in the client
  • Client send code challenge when connect to a authorization server for getting a authorization code
  • Client send code verifier when exchange token with an authorization code

Tokens

Token is a random string generated by authorization server and send to a client if authorization grant sent by the client is valid. Tokens used by OAuth2 have 2 types

  1. Access Token
  • It is a token that allows clients to access user data.
  • It is a replacement for a user's username and password.
  • It will be sent from authorization server to the client through response body, with a limited validity period (expires_in) sent as shown in the code below, and will be in the requests that are sent by the client to the resource server.
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
}
  1. Refresh Token
  • It is a token that a client uses to request a new access token from the authorization server when the access token expires.
  • In generally, it is valid longer than the access token.
  • It eliminates the need to request an authorization grant to request access to the token every time.
  • It is sent with the access token from the authorization server to the client and is used by client like the following:
client (application)authorization serverAPI (resource server)send authorization grant1send access token and refresh token.2use access token to request an API to access data.3If access token is expired, send an error.4use refresh token to request new access token.5new access token (and optional new refresh token).6use access token to request an API to access data.7send protected data.8client (application)authorization serverAPI (resource server)

Common mistakes

Tips

  • We use token as value of Authorization header when making a request to a resource server
Authorization: `Bearer ${tokens.access_token}`
Loading comments...