/dev/posts/

OAuth 2.x and OpenID Connect sequence diagrams

Published:

Updated:

Some sequence diagrams about OAuth 2.x and OpenID Connect.

Some sequence diagrams of OAuth 2.X and OpenID Connect. They provide an overview/summary/roadmap of several OAuth and OpenID Connect (OIDC) specifications. Look at the specifications and other references for details.

Table of content

OAuth

OAuth component diagram
Oauth Flows
Flow Initial Request
Authorization code flow frontchannel GET/POST authorization_endpoint (response_type=code)
Implicit flow frontchannel GET/POST authorization_endpoint (response_type=token)
Device flow backchannel POST device_authorization_endpoint
Client credential flow backchannel POST token_endpoint (grant_type=client_credentials)
Resource Owner password grant backchannel POST token_endpoint (grant_type=password)
Assertion authorization grants backchannel POST token_endpoint (grant_type=some assertion type)
OAuth 2.0 overview (using the authorization code flow with PKCE)

Authorization Code Flow

OAuth Authorization Code Flow, simplified diagram

In this diagram, the user and user agent are not represented explicitly.

OAuth Authorization Code Flow

Warning: user-agent for authorization server frontend code

Native client applications, should use an external user-agent for the authorization server frontend code i.e. either a standalone browser or an in-app browser tab. (such as Android Custom Tab, iOS ASWebAuthenticationSession or cordova-plugin-browsertab).

It should not use an embedded / in-app browser to execute the authorization server frontend logic (WebView, Cordova InAppBrowser).

In-app browser executes the authorization server frontend code in the system/user browser while the in-app browser tab executes the authorization server frontend code in the client application. In the first case, the user credentials are isolated from the client application.

Some extensions:

Token Usage

Authenticated request with a bearer access token

Using a bearer access token for accessing a protected resource.

Refresh token

Refresh tokens are used by the client to obtain fresh access tokens from the authorization server.

Token Introspection

Let the resource server get information about an access token (including whether it is still valid)

Token Revocation

Let the client revoke a refresh token or an access token

OAuth Metadata and Registration

Server metadata

Getting the configuration/features of an authorization server

Dynamic client registration and dynamic client registration management

Automated registration of a client on the authorization server and updating the client registration

OAuth Discovery

Authorization server discovery (draft)

Let the client application discover the authorization server to be used for a resource server

Client discovery

Let the authorization server discover the client instead of registering the client

Other OAuth Flows

OAuth implicit flow

This is a (legacy) flow which was intended to be used for non-confidential clients but is now replaced with the authorization code flow with Proof Key for Code Exchange (PKCE) which is more secure.

Note: lack of support for refresh tokens for some flows

Refresh tokens are NOT supported for the implicit[1] flow and for the client credentials flow.

OAuth resource owner crecentials grant (aka password grant)

Legacy flow, very insecure[2] where the user provides his/her password to the application.

OAuth device flow

Used for provisioning an access token to device which cannot execute a browser or have limited interactivity

OAuth client credentials flow

Used by the client (i.e. application) in order to obtain tokens for itself

Not represented here:

Authorization request protection

The following approaches may be used (or combined) to protect the privacy and/or integrity of the authorization request.

JWT-Secured Authorization Request (JAR)

The authorization request is a JWT which can be signed or signed-then-encrypted.

Pushed Authorization Requests (PAR)

With Pushed Authorization Requests, the client sends the authorization request directly to the authorization server (backchannel) instead of sending it through the user agent (frontchannel). This prevents the user from having access to and tempering with the authorization request.

OpenID Connect

OpenID connect component diagram
OpenID Connect Flows
Flow response_type nonce c_hash at_hash ...rt_hash
Authorization code flow code OPTIONAL OPTIONAL OPTIONAL N/A
Implicit flow id_token token REQUIRED OPTIONAL REQUIRED N/A
id_token REQUIRED OPTIONAL OPTIONAL N/A
Hybrid flow code id_token REQUIRED REQUIRED[3] REQUIRED[3:1] N/A
code token REQUIRED OPTIONAL OPTIONAL N/A
code id_token token REQUIRED REQUIRED[3:2] REQUIRED[3:3] N/A
CIBA push mode N/A N/A N/A REQUIRED REQUIRED[4]
CIBA other modes N/A N/A N/A OPTIONAL OPTIONAL
OpenID connect overview (using the authorization code flow with PKCE)

Authorization Code Flow

OpenID Connect with the Authorization Code Flow, simplified

In this diagram, the user and user agent are not represented explicitly.

OpenID Connect with the Authorization Code Flow
UserInfo

The acces_token may be used by the client to obtain additional user information.

Other OpenID connect flows

OpenID Connect implicit flow
OpenID Connect hybrid flow.

In this flow, an authorization code is returned in the authentication response alongside with the access_token and or id_token.

Note: at_hash and c_hash claims

The at_hash and c_hash claims contain half of the hash of the access_token and code respectively. The former is required in both implicit and hybrid flows. The latter is required in the ID token returned by the authorization endpoint in the hybrid flow. They protect against access token and authorization code substitution attacks respectively..

OpenID Connect Discovery and Registration

OpenID Connect discovery and client registration

Discovery is based on Webfinger

Third-party Inititated Login

OpenID Connect Third-party Inititated Login

Front-channel initiation of the login process by the OpenID provider or another party

Session Management

OpenID Connect Session Management

This uses a <iframe> for direct (front-channel) communication of session state update.

Note: two iframes

The specification mentions two <iframe>. But as far as I understand, the Relying party <iframe> is not stricly absolutely necessary and is only an implementation detail.

Logout

OpenID Connect Front-Channel Logout

Logout process initiated by the OpenID Provider through the user UA using a <iframe>

OpenID Connect Back-Channel Logout

Logout process initiated by the OpenID Provider using a direct (back-channel) request

OpenID Connect Relying Party Initiated Logout

CIBA

CIBA component diagram
OpenID Connect Client-Initiated Backchannel Authentication Flow (CIBA)

This is not unlike the device flow but more user friendly.

Bound Tokens

Client authentication using mutual TLS and Certificate-Bound Access Tokens
OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer (DPoP) (RFC9449)

Alternative to Certificate-bound Access Tokens when mTLS is not practical (eg. for Single Page Applications). The idea is the same but demonstration of the possession of a private key is given at the application (HTTP) layer in a DPoP HTTP header.

Appendix, Token Summary

Overview of different tokens
Name Flow Content
Authorization code (code) AS → client → AS opaque
Access Token (access_token) AS → client → RS opaque (may be a JWT, at+jwt)
Refresh token (refresh_token) AS → client → AS opaque (sometimes a JWT)
JWT-Secured Authz. Request (JAR) (request) client → AS JWT (oauth-authz-req+jwt)
JWT-Secured Authz. Response Mode (JARM) AS → client JWT
JWT response for Token Introspection AS → RS JWT (token-introspection+jwt)
DPoP Proof-of-possession (DPoP:) client → AS / RS JWT (dpop+jwt)
Software Statement (software_statement) client vendor → client → AS JWT
Authorization or Logout State (state) client → AS → client opaque
PKCE Code Verifier (code_verifier) client → AS opaque (random)
PKCE Code Challenge (code_challenge) client → AS hash of the code verifier (base64url)
OIDC ID token (id_token) OP (AS) → client (→ AS) JWT
OIDC Nonce (nonce) client → AS → client opaque
OIDC Session ID (sid) AS → client → AS opaque
OIDC Session State (session_state) OP (AS) → client opaque
OIDC private_key_jwt and client_secret_jwt client authentication ( client_assertion) client → OP / AS JWT

Appendix, Testing OpenID Connect using Keycloak

Keycloak is an Apache-licensed Identity and Access Management (IAM) software. We can quickly spawn a local instance in a container in order to experiment with OAuth and OpenID Connect:

podman run --name keycloak -p 127.0.0.1:8080:8080\
    -e KEYCLOAK_ADMIN=admin \
    -e KEYCLOAK_ADMIN_PASSWORD=change_me \
    quay.io/keycloak/keycloak:20.0.1 start-dev

A different port can be used:

podman run --name keycloak -p 127.0.0.1:3000:3000 \
    -e KEYCLOAK_ADMIN=admin \
    -e KEYCLOAK_ADMIN_PASSWORD=change_me \
    quay.io/keycloak/keycloak:20.0.1 start-dev --hostname-port=3000 --http-port=3000

Some interesting Docker/Podman arguments:

Some interesting KeyCloak arguments:

Interesting endpoints:

The Keycloak web site hosts a simple test OpenID connect client which can be used to test the OIDC provider.

See as well:

References

IANA registries:

Lists of specifications:

Informational:

Examples of Server Metadata:

Other:


  1. See “Why in implicit grant flow , the auth server MUST NOT issue a refresh token” for why the refresh token is not supported in the implicit flow. ↩︎

  2. The password flow is very insecure because the user password is given to the OAuth client. Moreover this flow only support password-based user authentication. ↩︎

  3. The c_hash and at_hash claims are REQUIRED in the id_token returned as part of the authentication response (when the corresponding value is present as well). They are OPTIONAL (when relevant) in the id_token returned in the Access Token Response. ↩︎ ↩︎ ↩︎ ↩︎

  4. If a refresh_token is sent. ↩︎