APICodeSecurity

Understanding OpenID Connect (OIDC)


OAuth 2.0 provides a framework for authorizing applications to call APIs but isn’t designed for authenticating users to applications. 

From OpenID to OpenID Connect

Web authentication was revolutionized by OpenID, which followed Security Assertion Markup Language (SAML). OpenID and SAML use the same basic principles, both facilitate web single sign-on (SSO) and cross-domain identity federation. The OpenID protocol is more community-friendly, user-centric, and decentralized. As of today, OpenID has evolved through three generations. The first generation of OpenID was 1.0/1.1/2.0, and the second generation is the OpenID extension for OAuth. The third generation of OpenID is OpenID Connect (OIDC).

OpenID Connect: An Overview

OpenID Connect is built on top of OAuth 2.0. On top of OAuth 2.0, it adds an identity layer. An ID token is abstracted from this identity layer by using JSON Web Tokens (JWTs). OAuth 2.0 authorization servers that support OpenID Connect return an ID token along with an access token.

OpenID Connect is about authentication, while OAuth 2.0 is about access delegation. Authentication involves proving your identity, whereas authorization involves what you can do.

The client will receive an ID token along with the access token when using OpenID Connect. The ID token represents the identity of the end user. OpenID Connect is at the application or client level — not at the API or resource server level. Clients and applications use OpenID Connect to find out who the end user is, but APIs do not need to know. APIs only expect access tokens. To find out who the end user is, the resource owner or API must query the authorization server or rely on a self-contained access token.

Anatomy of the ID Token

OAuth 2.0 supports OpenID Connect through the ID token. This is a JSON Web Token (JWT) that communicates authenticated user information.

Sample ID Token:

{
"exp": 1661084482,
"iat": 1661084182,
"auth_time": 1661084180,
"jti": "4e2d7853-5ed4-4360-bb1b-faeaee52d5d0",
"iss": "https://sso.authserver.com",
"aud": "account-console",
"sub": "bc3f4efb-1ab7-4f2d-97cb-a9f35b5102f8",
"typ": "ID",
"azp": "account-console",
"nonce": "c88497bc-8729-4d5d-8d58-d961bf712a76",
"session_state": "cfbd3474-df5c-4339-8fc9-20138d118e4a",
"at_hash": "WGlpN-jdreEcuwwi2ELm-A",
"acr": "1",
"sid": "cfbd3474-df5c-4339-8fc9-20138d118e4a",
"email_verified": true,
"name": "Neeraj Kushwaha",
"preferred_username": "learncsdesign@gmail.com",
"given_name": "Neeraj",
"family_name": "Kushwaha",
"email": "learncsdesign@gmail.com"
}

Let’s examine the definition of each attribute:

  • exp — The “exp” (expiration time) claim identifies the expiration time on or after which the JWT must not be accepted for processing.
  • iat — “Issued At” indicates when the authentication for this token occurred.
  • auth_time — The time at which the end user authenticates with the authorization server.
  • jti — The jti (JWT ID) claim provides a unique identifier for the JWT.
  • iss — Identifies the issuer, or “authorization server” that constructs and returns the token.
  • aud — Identifies the intended recipient of the token.
  • sub — The principal about which the token asserts information, such as the user of an app.
  • typ — Indicates that the token is an ID token.
  • azp — Authorized party — the party to which the ID Token was issued.
  • nonce — The nonce matches the parameter included in the original /authorize request to the IDP. If it does not match, your application should reject the token.
  • session_state —The session_state value is based on a salted cryptographic hash of Client ID, origin URL, and OP browser state.
  • at_hash — The access token hash is included in ID tokens only when the ID token is issued from the /authorize endpoint with an OAuth 2.0 access token.
  • acr — Stands for authentication context class reference. The value of this parameter must be understood by both the authorization server and the client application. It gives an indication of the level of authentication.
  • sid — Session ID
  • Other fields are self-explanatory.

OIDC Roles

OIDC involves three different roles:

  • End User — An individual who needs to be authenticated.
  • OpenID Provider — An OpenID provider is an OAuth 2.0 authorization server that implements OIDC and can authenticate a user and return claims about the authentication to a relying party.
  • Relying Party — An OAuth 2.0 client that requests claims about a user from an OpenID Provider.

How OIDC Works

In order to make an authentication request to an OpenID Provider, OIDC defines three different authentication flows.

  • Authorization Code Flow
  • Implicit Flow
  • Hybrid Flow

OIDC Authorization Code Flow

OIDC Authorization Code Flow uses two requests and an intermediary authorization code, similar to OAuth 2.0. An application redirects the user’s browser to an OpenID Provider to authenticate. By authenticating the user, the OpenID Provider redirects the user’s browser back to the application. With the authorization code, the application obtains an ID Token, access token, and optionally a refresh token from the OpenID Provider.

  1. The user accesses the application (Relying Party)
  2. The user’s browser is redirected to OpenID Provider for authentication.
  3. The OpenID Provider interacts with the user to authenticate and obtain consent for the scope of the information request.
  4. As soon as the user authenticates and gives consent, the OpenID Provider creates or updates an authentication session for the user.
  5. The user’s browser redirected back to the application with the authorization code.
  6. The application sends a token request to OpenID Provider with an authorization code.
  7. OpenID Providers respond with ID Tokens, access tokens, and refresh tokens.
  8. The application can use the access token at the OpenID Provider’s user info endpoint.

OIDC Implicit Flow

In OIDC, implicit flows are similar to the same grant type in OAuth 2.0. It is not recommended to use OAuth 2.0 implicit grants to obtain an access token. That guidance, however, is based on the possibility that the browser history or referer header could reveal an access token embedded in a URL fragment. An application that only needs to authenticate users and can obtain user information via an ID Token does not require an access token. It may be acceptable to use the Implicit Flow in this case.

  1. A user accesses the application (relying party).
  2. The user’s browser is redirected to OpenID Provider for authentication.
  3. The OpenID Provider interacts with the user to verify their identity and to obtain their consent regarding the scope of their information request.
  4. An authentication session is created or updated for the user when the OpenID Provider receives login credentials and consent from the user.
  5. With an ID token, the user’s browser was redirected back to the application.
  6. By obtaining user claims from ID Token, the application displays appropriate application content.

OIDC Hybrid Flow

Both the Authorization Code Flow and the Implicit Flow are included in the OIDC Hybrid Flow. It is designed for applications with both a secure back end and a front end with client-side JavaScript executing in a browser.

A Hybrid Flow allows the application front end to receive an ID Token and authorization code in a front-channel response, leaving the application backend to obtain an access token (and optional refresh token) from the token endpoint using the authorization code from the token endpoint.

  1. A user accesses an application (a relying party).
  2. The user’s browser is redirected to OpenID Provider for authentication.
  3. OpenID Providers interact with users to authenticate and to obtain consent for the scope of user information requests.
  4. The OpenID Provider creates or updates an authentication session for the user after the user authenticates and provides consent.
  5. A user’s browser is redirected back to the application front end with an authorization code and ID token.
  6. To get additional tokens, the client application validates ID Token, and if it is valid, the backend calls the token endpoint with an authorization code.
  7. The token endpoint of the OpenID Provider returns the tokens requested.
  8. Using the access token, the client application can call OpenID Provider’s UserInfo endpoint.

UserInfo Endpoint

The UserInfo endpoint of the OpenID Provider allows applications to retrieve claims about a user. The UserInfo endpoint is an OAuth2.0 API endpoint and to call it requires an access token issued by the OpenID Provider.

UserInfo is useful when the desired user profile claims are too large to fit in an ID Token returned.

Summary

On top of OAuth2.0, OpenID Connect provides an identity layer to authenticate users and enable single sign-on. Adding to OAuth2.0, OIDC adds an ID Token and a UserInfo endpoint, which returns claims about an authentication event and the authenticated user to the application.

Using OIDC and OAuth2.0 together solves both authentication and API authorization by delegating user authentication to an OpenID Provider.


References

Book — Solving Identity Management in Modern Applications

Leave a Reply

Your email address will not be published.