OpenIddict is an extensible OpenID Connect and OAuth 2.0 framework for ASP.NET Core. It provides the necessary infrastructure to implement an authorization server, a client, and a resource server. To achieve this, OpenIddict relies on several key entities that represent different aspects of the OAuth 2.0 and OpenID Connect specifications.

OpenIddict Entities

OpenIddict primarily uses the following entities (or their underlying data models) to manage the state and configuration of your authorization server:

OpenIddictApplication

The OpenIddictApplication entity represents a client application that can request tokens from your OpenIddict server.

  • Purpose: Stores information about registered clients, such as their ClientId, ClientSecret, RedirectUris, PostLogoutRedirectUris, Permissions (what flows/endpoints/scopes they’re allowed to use), and DisplayName.
  • Usage in Flows:
    • Authorization Flow: When a client initiates an authorization request, OpenIddict validates the ClientId and RedirectUri against the registered OpenIddictApplication entry.
    • Token Flow: For confidential clients, the ClientSecret is validated during the token exchange. The Permissions associated with the application determine which grant types it can use.
    • Introspection Flow: An API (acting as an introspection client) would typically authenticate itself using its ClientId and ClientSecret (or other means) to call the introspection endpoint.
    • Revocation Flow: Similar to introspection, the client requesting token revocation identifies itself via its ClientId and ClientSecret.
    • Logout Flow: The PostLogoutRedirectUris are used to redirect the user back to the client after a successful logout.

OpenIddictAuthorization

The OpenIddictAuthorization entity represents a grant of consent given by a resource owner (user) to a client application for a set of scopes.

  • Purpose: Tracks user consents for applications, preventing the need to prompt the user for consent repeatedly for the same scopes. Authorizations can be “permanent” (explicitly granted by a developer or sysadmin) or “ad-hoc” (automatically created by OpenIddict to link a chain of tokens for security purposes, e.g., in the authorization code flow).
  • Usage in Flows:
    • Authorization Flow: If a permanent authorization already exists for the requesting client and scopes, OpenIddict might bypass the consent screen, streamlining the user experience. Ad-hoc authorizations are created to link authorization codes to subsequent access/refresh tokens.
    • Token Flow: When exchanging an authorization code for tokens, OpenIddict might associate the new tokens with an existing ad-hoc authorization.
    • Revocation Flow: Revoking an authorization can invalidate all tokens associated with that authorization.

OpenIddictScope

The OpenIddictScope entity represents a permission or a group of permissions that a client can request on behalf of a user.

  • Purpose: Defines the various scopes (e.g., openid, profile, email, custom API scopes) that can be granted. It also allows associating resources with scopes.
  • Usage in Flows:
    • Authorization Flow: The client requests specific scopes, and the user is typically presented with these scopes for consent. The OpenIddictAuthorization then records the granted scopes.
    • Token Flow: The scopes granted in the authorization flow are included in the issued access token, defining the permissions the client has when accessing protected resources.
    • UserInfo Flow: The scopes like openid, profile, email determine which claims are included in the UserInfo response.

OpenIddictToken

The OpenIddictToken entity represents various types of tokens issued by the authorization server.

  • Purpose: Stores information about issued Authorization Codes, Access Tokens, Refresh Tokens, Identity Tokens, and Device Codes. This allows for their lookup, validation, and revocation. OpenIddict supports both JWT (JSON Web Token) and opaque reference tokens.
  • Usage in Flows:
    • Authorization Flow: An Authorization Code is issued and stored, linking back to the OpenIddictApplication and OpenIddictAuthorization.
    • Token Flow: The Authorization Code is exchanged for an Access Token and optionally a Refresh Token and Identity Token. These tokens are stored (unless token storage is explicitly disabled) and linked to the OpenIddictApplication and OpenIddictAuthorization.
    • Introspection Flow: An introspection request involves looking up an Access Token in the OpenIddictToken store to determine its validity and associated claims.
    • Revocation Flow: A revocation request explicitly targets an Access Token or Refresh Token to mark it as invalid in the OpenIddictToken store, preventing its future use.

Main OpenIddict Flows and Entity Usage

Here’s how these entities are used in the core OAuth 2.0 and OpenID Connect flows supported by OpenIddict:

1. Authorization Code Flow

This is the most common and recommended flow for web applications and mobile apps.

  • Step 1: Authorization Request (Client to Authorization Server) ➡️
    • The client redirects the user’s browser to the authorization endpoint, including parameters like client_id, redirect_uri, response_type=code, and scope.
    • OpenIddictApplication: OpenIddict validates the client_id and redirect_uri against the registered OpenIddictApplication entries. It also checks if the requested scopes are permitted for this application.
  • Step 2: User Authentication & Consent (User with Authorization Server) 👨‍💻✅
    • If the user isn’t authenticated, they’re redirected to a login page (handled by your application, not OpenIddict directly).
    • If no prior consent exists for the requested scopes, OpenIddict prompts the user for consent.
    • OpenIddictAuthorization: If the user grants consent, a new OpenIddictAuthorization entry (or an existing one is updated) is created/retrieved, recording the user’s approval for the client to access the specified scopes.
  • Step 3: Authorization Code Grant (Authorization Server to Client) 📝
    • OpenIddict generates a short-lived Authorization Code.
    • OpenIddictToken: An OpenIddictToken entry is created to store this Authorization Code, linked to the OpenIddictApplication and OpenIddictAuthorization.
    • The user’s browser is redirected back to the redirect_uri with the Authorization Code.
  • Step 4: Token Request (Client to Authorization Server) 🔑
    • The client makes a back-channel request to the token endpoint, exchanging the Authorization Code (and client_secret for confidential clients) for tokens.
    • OpenIddictApplication: The client_id and client_secret are validated against the OpenIddictApplication.
    • OpenIddictToken: OpenIddict validates the Authorization Code by looking it up in the OpenIddictToken store. If valid, it then issues an Access Token and optionally a Refresh Token and Identity Token. These new tokens are also stored as OpenIddictToken entries, often linked to the original OpenIddictAuthorization and OpenIddictApplication.
  • Step 5: Resource Access (Client to Resource Server) 🛡️
    • The client uses the Access Token to call protected APIs on a resource server.

2. Client Credentials Flow

This flow is used when a client (e.g., a service or daemon) needs to access resources it owns, without any user involvement.

  • Step 1: Token Request (Client to Authorization Server) 🔑
    • The client sends a request directly to the token endpoint with its client_id and client_secret, and grant_type=client_credentials.
    • OpenIddictApplication: OpenIddict validates the client_id and client_secret against the OpenIddictApplication entity. It also checks if the application has permission to use the “client credentials” grant type and any requested scopes.
    • OpenIddictToken: If valid, OpenIddict issues an Access Token and stores it as an OpenIddictToken entry, linked to the OpenIddictApplication.
  • Step 2: Resource Access (Client to Resource Server) 🛡️
    • The client uses the Access Token to call protected APIs.

3. Refresh Token Flow

Used to obtain new access tokens when existing ones expire, without requiring the user to re-authenticate.

  • Step 1: Token Request (Client to Authorization Server) 🔄
    • The client sends a request to the token endpoint with a refresh_token and grant_type=refresh_token.
    • OpenIddictApplication: OpenIddict validates the client requesting the refresh.
    • OpenIddictToken: OpenIddict validates the provided refresh_token by looking it up in the OpenIddictToken store. If valid and not revoked, it issues a new Access Token (and optionally a new Refresh Token). Both the new and potentially the old tokens are updated/stored as OpenIddictToken entries. The original Refresh Token might be invalidated, or a new one issued.
    • OpenIddictAuthorization: The new tokens are typically linked to the existing OpenIddictAuthorization that granted the original refresh token.

4. Introspection Flow

Allows resource servers to determine the active state and contents of an access token.

  • Step 1: Introspection Request (Resource Server to Authorization Server) 🕵️
    • A resource server receives an access token and sends it to the introspection endpoint along with its own client credentials.
    • OpenIddictApplication: The resource server’s client_id and client_secret are validated against its OpenIddictApplication entry to ensure it has permission to perform introspection.
    • OpenIddictToken: OpenIddict looks up the provided access token in the OpenIddictToken store. If found and active, it returns information about the token, such as its active status, associated claims, and expiration.

5. Revocation Flow

Allows clients to revoke previously issued access or refresh tokens.

  • Step 1: Revocation Request (Client to Authorization Server)
    • The client sends a request to the revocation endpoint with the token to be revoked (access token or refresh token) and its client credentials.
    • OpenIddictApplication: The client’s client_id and client_secret are validated against its OpenIddictApplication entry to ensure it has permission to revoke tokens.
    • OpenIddictToken: OpenIddict finds the specified token in the OpenIddictToken store and marks it as revoked, preventing its further use.
    • OpenIddictAuthorization: If the revoked token was a Refresh Token or an Authorization Code that was part of an ad-hoc authorization, OpenIddict might also revoke other associated tokens or the authorization itself to maintain security and consistency.

6. UserInfo Flow (OpenID Connect Specific)

Allows clients to retrieve claims about the authenticated end-user.

  • Step 1: UserInfo Request (Client to UserInfo Endpoint) ℹ️
    • After obtaining an access token (usually from the Authorization Code Flow), the client makes a GET or POST request to the UserInfo endpoint, including the Access Token in the Authorization header.
    • OpenIddictToken: OpenIddict validates the Access Token by looking it up in the OpenIddictToken store (if configured for reference tokens) or by validating its signature and expiration (for JWTs).
    • OpenIddictScope: The scopes granted for the Access Token (stored in OpenIddictAuthorization and represented by OpenIddictScope entities) determine which user claims are returned in the UserInfo response (e.g., profile scope for name, family name; email scope for email address).

7. Logout Flow (OpenID Connect Specific)

Allows the user to log out from the authorization server and potentially all connected clients.

  • Step 1: End Session Request (Client to Authorization Server) 👋
    • The client redirects the user’s browser to the end session endpoint, optionally providing an id_token_hint and post_logout_redirect_uri.
    • OpenIddictApplication: OpenIddict validates the post_logout_redirect_uri against the registered OpenIddictApplication entry.
    • OpenIddictToken: OpenIddict may use the id_token_hint to identify the user’s session and perform a server-side logout, potentially invalidating associated OpenIddictToken entries.
    • OpenIddict performs its internal logout logic (e.g., clearing server-side session data).
  • Step 2: Redirection (Authorization Server to Client) 🔙
    • The user’s browser is redirected back to the post_logout_redirect_uri on the client. The client then performs its own local logout.

These entities and their interactions are fundamental to how OpenIddict manages the security and identity aspects of your applications, providing a robust and flexible framework for implementing OAuth 2.0 and OpenID Connect.

Exit mobile version