OAuth2

The OAuth 2.0 Authorization Framework is an open-standard authorization protocol or framework that provides applications the ability for secure access to protected resources without giving them the password. The key concepts of OAuth include resource owners, clients, authorization server, access tokens, and scopes.

  • Resource owners are entities capable of authorizing access to a protected resource (e.g. user).
  • Clients are third-party applications that want access to a protected resource (e.g. application).
  • Authorization servers are responsible for verifying authorization grants and issuing access tokens (e.g. Keycloak).
  • Access tokens are used to access protected resources (i.e. JWT token).
  • Scopes are used to limit the amount of access that an OAuth client has to a protected resource (e.g. read-only)

Introduction

In the traditional client-server authentication model, the client requests an access-restricted resource (protected resource) on the server by authenticating with the server using the resource owner’s credentials. In order to provide third-party applications access to restricted resources, the resource owner shares its credentials with the third party

Limitation:

  • Third-party are required to store credentials (e.g: password).
  • Servers are required to support password authentication.
  • Third-party has no restrictions on the resources they can access.
  • Resource owners cannot revoke access to a third-party.
  • Security compromise casscade down to end-user’s password and data.

Instead of using resource owner’s credentials, OAuth uses access tokens to access protected resources. Access tokens are issued by the authorization server and are short-lived. Access tokens are NOT used to authenticate the client, but instead are used to identify the client and authorize access to the protected resource.

Protocol Flow

             +--------+                               +---------------+
             |        |--(A)- Authorization Request ->|   Resource    |
             |        |                               |     Owner     |
             |        |<-(B)-- Authorization Grant ---|               |
             |        |                               +---------------+
             |        |
             |        |                               +---------------+
             |        |--(C)-- Authorization Grant -->| Authorization |
             | Client |                               |     Server    |
             |        |<-(D)----- Access Token -------|               |
             |        |                               +---------------+
             |        |
             |        |                               +---------------+
             |        |--(E)----- Access Token ------>|    Resource   |
             |        |                               |     Server    |
             |        |<-(F)--- Protected Resource ---|               |
             +--------+                               +---------------+

                      Figure 1:  Abstract Protocol Flow
            (https://datatracker.ietf.org/doc/html/rfc6749#section-1.2)

OAuth Protocol Flow is the process that allows an application to request authorization to access a user’s data. It involves the user granting permission to the application, the application sending an authorization request to the authorization server, and the authorization server responding with an access token which can be used to request the user’s data. The protocol flow is divided into four steps:

  • The user grants the application permission to access their data by clicking on a “Login with…” button or similar.
  • The application then sends an authorization request to the authorization server which contains information about the application, the user, and the data the application is requesting access to.
  • The authorization server then responds with an access token which is used to request the user’s data.
  • The application then sends a request to the resource server with the access token, and the resource server responds with the requested data.

Grant Types

Authorization grants are credentials representing the resource owner’s authorization (to access its protected resources) expressed in a specific manner, for the specific purpose of being exchanged for an access token.

There are four grant types:

  • Authorization Code Grant: Used when the client needs to access resources that are owned by the user, such as when the user needs to log into an application or grant access to their data
  • Implicit Grant: Used when the client needs to access resources on behalf of a user without the user having to provide credentials.
  • Resource Owner Password Credentials Grant: Used when the client needs to access resources that are owned by the user, but the user does not need to log in or provide credentials.
  • Client Credentials Grant: Used when the client needs to access resources that the client owns, such as when the client needs to make requests on its own behalf.

Authorization Code Grant

Instead of requesting authorization directly from resource owner, the client application requests authorization from the authorization server. The authorization server authenticates the resource owner and obtains authorization. The authorization server then issues an authorization code to the client application. The client application then exchanges the authorization code for an access token.

The Authorization Code grant type is the most secure of the OAuth 2.0 grant types and provides the highest level of assurance that the access token is only issued to the intended client application

Implicit Grant

The Implicit Grant type is an OAuth 2.0 authorization flow that does not require an intermediate code exchange step. Instead, the client-side application directly requests an access token from the authorization server, and the authorization server directly issues the access token to the client-side application. The Implicit grant type is suitable for client-side applications (such as JavaScript apps) where the client secret can’t be securely stored. It is also used in mobile applications where the client secret is not available.

The Implicit grant flow is similar to the Authorization Code grant flow, except that it does not require the client to exchange an authorization code for an access token. Instead, the authorization server responds with an access token directly and can be verify via the access token’s signature.

Resource Owner Password Credentials Grant

When there is a high degree of trust between the resource owner and the client (e.g. the client is part of the device), the resource owner password credentials (i.e. username and password) can be used to obtain an access token directly.

Client Credentials Grant

OAuth2 Client Credentials grant is an authorization flow used by clients to obtain an access token outside of the context of a user. In this flow, the client will send its own credentials (usually in the form of a client ID and a client secret) to the authorization server, which will then respond with an access token. This access token can then be used to access the client’s own resources, not on behalf of a user. This type of flow is typically used by applications that need to access their own APIs, such as for backend services.

Access Token

An OAuth 2 Access Token is a string that is used to authenticate a user and grant access to an API. They are issued by an authorization server, typically after a user has successfully authenticated and given their consent to access the API. Access tokens are used to make requests to the API on behalf of the user, and usually have a limited lifetime. Access tokens may also be revoked by the user or the authorization server at any time. Access tokens are typically encoded using the JWT (JSON Web Token) format, which includes the user’s identity, the scope of the API access granted, an expiration time and other security-related information like a signature.

Refresh Token

A refresh token is a special kind of token that is used to obtain a new access token. It is issued to the client by the authorization server and is used to obtain a new access token when the current access token becomes invalid or expires.

       +--------+                                           +---------------+
       |        |--(A)------- Authorization Grant --------->|               |
       |        |                                           |               |
       |        |<-(B)----------- Access Token -------------|               |
       |        |               & Refresh Token             |               |
       |        |                                           |               |
       |        |                            +----------+   |               |
       |        |--(C)---- Access Token ---->|          |   |               |
       |        |                            |          |   |               |
       |        |<-(D)- Protected Resource --| Resource |   | Authorization |
       | Client |                            |  Server  |   |     Server    |
       |        |--(E)---- Access Token ---->|          |   |               |
       |        |                            |          |   |               |
       |        |<-(F)- Invalid Token Error -|          |   |               |
       |        |                            +----------+   |               |
       |        |                                           |               |
       |        |--(G)----------- Refresh Token ----------->|               |
       |        |                                           |               |
       |        |<-(H)----------- Access Token -------------|               |
       +--------+           & Optional Refresh Token        +---------------+

                 Figure 2: Refreshing an Expired Access Token
           (https://datatracker.ietf.org/doc/html/rfc6749#section-1.5)

Clients

Client registration

Before initiating the protocol, the client registers with the authorization server

In order to register a client, client developers needs to:

  • Specify client type
  • Provide client redirect URIs

Client types

There are two types of clients:

  • Confidential: Clients that can keep their credentials confidential (e.g. web applications)
  • Public: Clients that cannot keep their credentials confidential (e.g. mobile applications)

Clients can have multiple components, such as a web application and a mobile application. In this case, the client have different client types and security context and should be registered separately.

OAuth 2.0 defines three different classes of clients:

  • web applications: store the client credentials on a server (e.g. web server)
  • user-agent-based applications: execute code within a user agent (e.g. web browser)
  • native applications: installed on a user’s device (e.g. mobile phone or tablet)

This specification has been designed around the following client profiles:

  • web application

    A web application is a confidential client running on a web server. Resource owners access the client via an HTML user interface rendered in a user-agent on the device used by the resource owner. The client credentials as well as any access token issued to the client are stored on the web server and are not exposed to or accessible by the resource owner.

  • user-agent-based application

    A user-agent-based application is a public client in which the client code is downloaded from a web server and executes within a user-agent (e.g., web browser) on the device used by the resource owner. Protocol data and credentials are easily accessible (and often visible) to the resource owner. Since such applications reside within the user-agent, they can make seamless use of the user-agent capabilities when requesting authorization.

  • native application

    A native application is a public client installed and executed on the device used by the resource owner. Protocol data and credentials are accessible to the resource owner. It is assumed that any client authentication credentials included in the application can be extracted. On the other hand, dynamically issued credentials such as access tokens or refresh tokens can receive an acceptable level of protection. At a minimum, these credentials are protected from hostile servers with which the application may interact. On some platforms, these credentials might be protected from other applications residing on the same device.

Client identifier

Client ID is a unique string that is used to identify the client application when it requests access to a user’s resources from an authorization server. It is used to verify that the application is registered and trusted by the authorization server, and to ensure that the application is not attempting to gain access to resources it does not have permission to access. It is also used to help the authorization server track the application’s access to the user’s resources.

Client authentication

Client Authentication is a process used to verify a client application’s identity when requesting access to a user’s resources from an authorization server. This process helps to ensure that the application is registered and trusted, and that it is not attempting to gain access to resources it does not have permission to access. The process typically involves the client application providing a unique identifier and a secret key, which the authorization server can use to authenticate the client. In addition, the authorization server may require additional authentication methods, such as a certificate or a user’s username and password.

Client password

Clients can be assigned a password that is used to authenticate the client when it requests access to a user’s. It can be used to authenticate with authorization server via the HTTP Basic authentication scheme.

The client identifier is encoded using the “application/x-www-form-urlencoded” encoding algorithm per Appendix B, and the encoded value is used as the username; the client password is encoded using the same algorithm and used as the password

E.g.:

 Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

Alternatively, but NOT RECOMMENDED, the client can authenticate with the authorization server using the client_id and client_secret in the request body using:

  • client_id as the username
  • client_secret as the password

Protocol endpoints

The authorization process utilizes 2 endpoints:

  • Authorization endpoint: used to interact with the resource owner and obtain an authorization grant.
  • Token endpoint: used by the client to obtain an access token by presenting its authorization grant or refresh token.

Authorization endpoint

The authorization endpoint is used to interact with the resource owner and obtain an authorization grant.

Response types:

  • code: for requesting an authorization code.
  • token: for requesting an access token (implicit grant).

Token endpoint

The token endpoint allows clients to obtain access token and refresh token. This endpoint is used with every authorization grant except for the implicit grant type (since an access token is issued directly).

A client will usually send an authorization grant (such as an authorization code) to the token endpoint, and the endpoint will return an access token and a refresh token. The access token is used to gain access to protected resources, while the refresh token is used to obtain a new access token when the current one expires.

The token endpoint can also be used to revoke access tokens, and to obtain additional information about the token, such as its expiration time.

Obtaining Authorization

Authorization code grant

The authorization code flow involves the following steps:

  • The client initiates the flow by redirecting the user to the authorization server.
  • The user authenticates with the authorization server and grants the client access.
  • The authorization server sends an authorization code back to the client application.
  • The client application exchanges the authorization code for an access token.
  • The client application can use the access token to make API requests.
            +----------+
            | Resource |
            |   Owner  |
            |          |
            +----------+
                 ^
                 |
                (B)
            +----|-----+          Client Identifier      +---------------+
            |         -+----(A)-- & Redirection URI ---->|               |
            |  User-   |                                 | Authorization |
            |  Agent  -+----(B)-- User authenticates --->|     Server    |
            |          |                                 |               |
            |         -+----(C)-- Authorization Code ---<|               |
            +-|----|---+                                 +---------------+
              |    |                                         ^      v
             (A)  (C)                                        |      |
              |    |                                         |      |
              ^    v                                         |      |
            +---------+                                      |      |
            |         |>---(D)-- Authorization Code ---------'      |
            |  Client |          & Redirection URI                  |
            |         |                                             |
            |         |<---(E)----- Access Token -------------------'
            +---------+       (w/ Optional Refresh Token)

        Note: The lines illustrating steps (A), (B), and (C) are broken into
        two parts as they pass through the user-agent.

                          Figure 3: Authorization Code Flow
              (https://datatracker.ietf.org/doc/html/rfc6749#section-4.1)

Implicit grant

The implicit grant flow involves the following steps:

  • The client initiates the flow by redirecting the user to the authorization server.
  • The user authenticates with the authorization server and grants the client access.
  • The authorization server sends an access token back to the client application.
  • The client application can use the access token to make API requests.

           +----------+
           | Resource |
           |  Owner   |
           |          |
           +----------+
                ^
                |
               (B)
           +----|-----+          Client Identifier     +---------------+
           |         -+----(A)-- & Redirection URI --->|               |
           |  User-   |                                | Authorization |
           |  Agent  -|----(B)-- User authenticates -->|     Server    |
           |          |                                |               |
           |          |<---(C)--- Redirection URI ----<|               |
           |          |          with Access Token     +---------------+
           |          |            in Fragment
           |          |                                +---------------+
           |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
           |          |          without Fragment      |     Client    |
           |          |                                |    Resource   |
           |     (F)  |<---(E)------- Script ---------<|               |
           |          |                                +---------------+
           +-|--------+
             |    |
            (A)  (G) Access Token
             |    |
             ^    v
           +---------+
           |         |
           |  Client |
           |         |
           +---------+

         Note: The lines illustrating steps (A) and (B) are broken into two
         parts as they pass through the user-agent.

                        Figure 4: Implicit Grant Flow
            (https://datatracker.ietf.org/doc/html/rfc6749#section-4.2)

Resource owner password credentials grant

The resource owner password credentials grant flow involves the following steps:

  • The client application requests an access token from the authorization server by providing the resource owner’s credentials.
  • The authorization server validates the credentials and sends an access token back to the client application.
           +----------+
           | Resource |
           |  Owner   |
           |          |
           +----------+
                v
                |    Resource Owner
               (A) Password Credentials
                |
                v
           +---------+                                  +---------------+
           |         |>--(B)---- Resource Owner ------->|               |
           |         |         Password Credentials     | Authorization |
           | Client  |                                  |     Server    |
           |         |<--(C)---- Access Token ---------<|               |
           |         |    (w/ Optional Refresh Token)   |               |
           +---------+                                  +---------------+

                Figure 5: Resource Owner Password Credentials Flow
            (https://datatracker.ietf.org/doc/html/rfc6749#section-4.3)

Client credentials grant

The client credentials grant flow involves the following steps:

  • The client application requests an access token from the authorization server by providing its client credentials.
  • The authorization server validates the credentials and sends an access token back to the client application.
         +---------+                                  +---------------+
         |         |>--(A)- Client Authentication --->|               |
         | Client  |                                  | Authorization |
         |         |<--(B)---- Access Token ---------<|     Server    |
         |         |    (w/ Optional Refresh Token)   |               |
         +---------+                                  +---------------+

                    Figure 6: Client Credentials Flow
          (https://datatracker.ietf.org/doc/html/rfc6749#section-4.4)