OAuth 2.0 authentication standard and its flows
This chapter provides an overview of the Oauth2 specification and its defined flows. For more details please visit RFC 6749 OAuth2.
Basic knowledge about OAuth2
OAuth2 defines an abstract flow. Four roles are relevant in this flow:
Resource Owner |
The entity, which allows a third party to access their data. The Resource Server provides the required resources. |
Resource Server |
The server, which holds protected resources |
Client |
The client or application, which wants to access the resources on the Resource Server on behalf of the Resource Owner. |
Authorization Server |
The server authenticates the Resource Owner and issues access tokens. The token will be used by the client to access the protected resources on the Resource Server. |
-
The client requests authorization from the resource owner. The authorization request can be made directly to the resource owner (as shown), or preferably indirectly via the authorization server as an intermediary.
-
The client receives an authorization grant, which is a credential representing the resource owner’s authorization, expressed using one of four grant types defined in this specification or using an extension grant type. The authorization grant type depends on the method used by the client to request authorization and the types supported by the authorization server.
-
The client requests an access token by authenticating with the authorization server and presenting the authorization grant.
-
The client requests the protected resource from the resource server and authenticates by presenting the access token.
-
The resource server validates the access token, and if valid, serves the request.
-
The client receives the response from the server.
OAuth2 flows in detail
Authorization Code Grant Flow
The OAuth2 Authorization Code Grant/Flow is used in order to receive access and refresh tokens. It requires a confidential client for the backend.
-
Client initializes authorization code request by redirecting the resource owner’s user-agent to the authorization endpoint. In addition, it is sending its client_id and a redirect_uri, where the resource owner will be redirected after login.
-
The resource owner uses their credentials to successfully login, consent may be requested, which can be granted or denied by the resource owner
-
If grants are provided the user-agent is redirected to the redirect_uri. The redirect uri contains an authorization code and any local state provided by the client
-
Client communicates over back-channel with authorization server and requests access token by sending the previous received authorization code.
-
Client receives access token and optional refresh token from authorization server.
The access token can then be added to every request to the Resource Server for example using the header Authorization: Bearer <access_token>, contained in a cookie or as part of a referenced user session. To make the cookie:
-
make it Secure and HttpOnly (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies),
-
do not set the domain attribute! Otherwise, you will have security issues due to implicit wildcard scoping of your cookie,
-
use the __Host prefix to enforce strict cookie scope ( Cookie Prefixes ) including secure and absence of domain attribute on supporting clients
-
and restrict cookie usage with proper XSRF protection.
Make sure to have proper CSRF / XSRF protection in place to restrict usage of the authorization cookie! |
Authorization Code Flow with PKCE
PKCE stands for Proof Key for Code Exchange (see RFC7636). PKCE makes it possible to do an authorization code flow without backend. Both redirection or popups are possible for the login flow. It is basically the same as the authorization code flow without PKCE above, but user-agent and client are the same. Interception of the authorization code is prohibited by added a code challenge to (A) that is derived from a random code verifier using cryptographic hashing method define by the code challenge method.
Upon receiving the authorization code after successful user login, it can be exchanged for a token without requiring any client credentials. The public clients clientId and the code_verifier are sufficient to get a token for the user.
Without PKCE, "OAuth 2.0 (RFC6749) public clients are susceptible to the authorization code interception attack" (RFC7636). The implicit flow was the easiest flow to be implemented for public clients, as the authorization code grant flow without PKCE does not offer any security benefit. This is visualized for apps in the following schema from RFC 7636.
What makes PKCE secure?
PKCE add a challenge-response mechanism to the Authorization Code Grant Flow’s code exchange. The requesting client generates a cryptographically random string, the code verifier, and derives the code challenge from it. After receiving the authorization code from the authorization server, only the legitimate client knows the code verifier that authorization server expects to authenticate the code exchange request. Only given a valid code verifier matching the authorization code, it returns access and id tokens.
How to get the public client’s id into the app?
Multitenant Access Control randomly generates the client ids, thus an application will have different client ids on each environment. Hardcoding it into the application is therefore not a good idea. Therefore, it is recommended to offer a public configuration endpoint from which the client (app, CLI, pure client side SPA…) can request configuration settings like its client id on a specific environment. So once the user selected the environment to use (in case of an CLI there might be multiple environments to interact with), the client can read its public client’s id and use it to trigger the user login flow.
Implicit Grant Authorization Flow (deprecated)
Implicit Flow is insecure and deprecated. It has been used before PKCE was invented, but now that there is PKCE, use Authorization Code Flow with PKCE instead. This flow is not secure because the access-token is returned as part of the redirection URI. |
Resource Owner Password Credentials Flow
This flow should only be used, when the Client and Resource Server were deployed by the same authority and there is absolute trust between both. OAuth2 RFC 6749 recommends to minimize use of this grant type and utilize other grant types whenever possible.There is a risk of credential misuse by the client as well as an increased risk of leaking credentials.This grant type is also often used for migrating existing clients, which are e.g. using HTTP Basic, to OAuth.
-
Resource Owner provides his credentials to the Client
-
Client requests access token from Authorization Server in the name of the Resource Owner.
-
The Authorization Server authenticates the client, validates the credentials and returns an access token on success.
Client Credentials Flow
In Client Credentials Flow the client uses his credentials to authenticate against the Authorization Server. The client himself can be the Resource Owner of the protected resources. This flow does not require any end-user to be involved, therefore this flow is typically used for service-to-service communication.
-
The client authenticates with the authorization server and requests an access token.
-
On successful authorization, the server returns an access token.