Authentication overview

IdentityServer functions as an OpenID Connect provider and an OAuth 2.0 authorization server, enabling centralized authentication and authorization for various client applications and APIs. It is built on the ASP.NET Core framework, offering a flexible and extensible platform for managing digital identities IdentityServer overview documentation. Developers can configure IdentityServer to issue identity tokens for user authentication and access tokens for API authorization, adhering to established industry standards like OpenID Connect and OAuth 2.0. This allows client applications to delegate user authentication to IdentityServer, receiving back security tokens that assert the user's identity and permissions.

The core components of IdentityServer's authentication process involve:

  • Clients: Applications requesting tokens from IdentityServer. Clients must be registered with IdentityServer and configured with specific authentication methods and allowed scopes.
  • Resources: APIs or identity data that clients want to access. Resources are protected by IdentityServer and require valid access tokens for access.
  • Users: End-users who authenticate with IdentityServer. IdentityServer can integrate with various user stores and external identity providers.

IdentityServer's design emphasizes extensibility, allowing developers to customize almost every aspect of the authentication and token issuance pipeline. This includes custom user stores, consent screens, and token validation logic. The framework supports a range of OAuth 2.0 grant types and OpenID Connect flows, making it suitable for securing diverse application architectures, from traditional web applications to single-page applications (SPAs), native mobile apps, and machine-to-machine communication.

Supported authentication methods

IdentityServer supports various authentication methods for both clients and end-users. The choice of method depends on the client type, security requirements, and the desired user experience.

Client authentication methods

Clients can authenticate with IdentityServer using several methods to prove their identity when requesting tokens. These methods are specified during client registration.

  • Client Secrets (shared secret): A symmetric key shared between the client and IdentityServer. This is suitable for confidential clients that can securely store the secret, such as traditional web applications running on a server.
  • X.509 Client Certificates: Clients authenticate using a private key and a corresponding public key certificate. This offers a higher level of security than shared secrets, as the private key never leaves the client and is often managed by a hardware security module.
  • JSON Web Token (JWT) Bearer Client Assertion: Clients authenticate by signing a JWT with their private key and sending it as an assertion. This method is flexible and allows for richer authentication claims within the JWT.
  • Proof Key for Code Exchange (PKCE): While not a direct client authentication method, PKCE is crucial for public clients (e.g., SPAs, native apps) using the Authorization Code Flow. It prevents interception attacks by requiring the client to prove ownership of the authorization code without needing a client secret IdentityServer client authentication details.

User authentication methods

IdentityServer provides a pluggable user authentication mechanism, meaning it does not dictate how users authenticate but rather integrates with existing identity systems or allows for custom implementations.

  • Local User Accounts: IdentityServer can be configured to manage local user accounts, often backed by a database. This requires implementing custom logic for user registration, login, and password management.
  • External Identity Providers: IdentityServer can federate with external identity providers (IdPs) such as Google, Facebook, Microsoft Account, or other OpenID Connect/SAML 2.0 providers. This allows users to log in using their existing accounts from these services. IdentityServer acts as a proxy, translating the external IdP's authentication into its own token format external identity provider configuration.
  • Multi-Factor Authentication (MFA): While IdentityServer itself doesn't directly implement MFA, it provides hooks and extensibility points to integrate with MFA solutions. This can involve redirecting to an MFA provider or incorporating MFA challenges into the custom login flow.

Authentication Methods Table

Method When to Use Security Level
Client Secrets Confidential clients (server-side web apps) Medium (requires secure secret storage)
X.509 Client Certificates High-security confidential clients, machine-to-machine High (private key never transmitted)
JWT Bearer Client Assertion Flexible client authentication, rich claims, machine-to-machine High (requires secure private key management)
PKCE (for public clients) Single-page applications (SPAs), native mobile/desktop apps High (mitigates authorization code interception)
Local User Accounts Custom identity management, full control over user data Configurable (depends on implementation)
External Identity Providers Leveraging existing identities (social logins, enterprise IdPs) Inherited from external provider

Getting your credentials

Setting up credentials in IdentityServer primarily involves configuring clients and, for user authentication, integrating with a user store or external identity providers.

Client Credentials

  1. Registering a Client: In your IdentityServer configuration, define a new client. This typically involves adding a Client object to your configuration store (e.g., in-memory, database).
  2. Defining Client ID and Secret: For clients using shared secrets, assign a unique ClientId and a securely generated ClientSecret. The secret should be hashed and stored securely in IdentityServer. The client application will use the plain-text secret for authentication IdentityServer client configuration guide. For certificate-based authentication, configure the client with the thumbprint or path to the client certificate.
  3. Configuring Grant Types and Scopes: Specify the allowed OAuth 2.0 grant types (e.g., client_credentials, authorization_code) and the scopes (permissions) that the client is allowed to request.
  4. Redirect URIs and Post-Logout Redirect URIs: For interactive clients, configure valid redirect URIs where IdentityServer will send tokens or authorization codes after successful authentication, and post-logout redirect URIs for redirecting after logout.
new Client
{
    ClientId = "myclient",
    ClientSecrets = { new Secret("mysecret".Sha256()) },
    AllowedGrantTypes = GrantTypes.ClientCredentials,
    AllowedScopes = { "api1" }
},
new Client
{
    ClientId = "web",
    ClientSecrets = { new Secret("secret".Sha256()) },
    AllowedGrantTypes = GrantTypes.Code,
    RedirectUris = { "https://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "https://localhost:5002/signout-callback-oidc" },
    AllowOfflineAccess = true,
    AllowedScopes = { "openid", "profile", "api1" }
}

User Credentials

For user authentication, IdentityServer relies on an implementation of IResourceOwnerPasswordValidator (for password grant type, generally discouraged for interactive clients) or integrates with an external identity provider.

  1. Custom User Store: Implement services to manage user accounts, including password hashing and validation. This is typically done by implementing ASP.NET Core Identity or a custom user service that IdentityServer can call.
  2. External Provider Configuration: To integrate with external identity providers (e.g., Google, Microsoft), you'll add their respective authentication middleware to your ASP.NET Core application's startup. IdentityServer will then incorporate these options into its login flow. For example, to add Google authentication, you would configure the Google OpenID Connect middleware with a Client ID and Client Secret obtained from the Google Developer Console Google OAuth 2.0 documentation.
// Example for adding Google authentication
builder.Services.AddAuthentication()
    .AddGoogle("Google", options =>
    {
        options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
        options.ClientId = "your_google_client_id";
        options.ClientSecret = "your_google_client_secret";
    });

Authenticated request example

Once a client has obtained an access token from IdentityServer, it can use this token to make authenticated requests to protected APIs. The access token is typically a JWT (JSON Web Token) and is included in the Authorization header of the HTTP request as a Bearer token.

Example: Client Credentials Flow for Machine-to-Machine

This example demonstrates a client (e.g., a background service) obtaining an access token using its client ID and secret, then using that token to call a protected API.

Step 1: Request Access Token from IdentityServer

The client makes a POST request to IdentityServer's token endpoint.

POST /connect/token HTTP/1.1
Host: your-identityserver-domain.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=myclient&client_secret=mysecret&scope=api1

IdentityServer responds with an access token (and typically an expiration time, token type, and optionally a refresh token).

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8

{
  "access_token": "eyJhbGciOiJIUzI1NiIsI...",
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "api1"
}

Step 2: Make Authenticated Request to a Protected API

The client then uses the received access_token to call a protected API endpoint.

GET /api/data HTTP/1.1
Host: your-api-domain.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsI...

The API, configured to validate tokens issued by IdentityServer, will verify the token's signature, issuer, audience, and expiration before granting access to the requested resource. If the token is valid, the API processes the request.

Security best practices

Implementing IdentityServer securely requires adherence to several best practices to protect client applications, user data, and the IdentityServer instance itself.

  • Secure Client Secrets: For clients using shared secrets, ensure secrets are strong, unique, and stored securely. Avoid hardcoding secrets in code. Use environment variables, secret management services (e.g., Azure Key Vault, AWS Secrets Manager), or configuration providers that encrypt secrets at rest ASP.NET Core Key Vault configuration. Rotate secrets regularly.
  • Use PKCE for Public Clients: Always use Proof Key for Code Exchange (PKCE) for public clients like SPAs and native mobile/desktop applications. PKCE significantly mitigates authorization code interception attacks, as public clients cannot securely store client secrets.
  • Validate Redirect URIs: Configure strict validation for all client redirect URIs. Only allow pre-registered, specific URIs to prevent open redirect vulnerabilities. Wildcards should be used with extreme caution and only when absolutely necessary, with further validation in place.
  • Implement HTTPS Everywhere: All communication with IdentityServer, client applications, and protected APIs must occur over HTTPS. This protects tokens and sensitive data from eavesdropping and tampering during transit.
  • Token Lifetime Management: Configure appropriate lifetimes for access tokens, identity tokens, and refresh tokens. Shorter lifetimes for access tokens reduce the impact of token compromise, while refresh tokens with longer lifetimes can be used to obtain new access tokens without re-authenticating the user, often with rotation and revocation mechanisms.
  • Refresh Token Rotation: For enhanced security, implement refresh token rotation. Each time a client uses a refresh token to get a new access token, a new refresh token is issued, and the old one is invalidated. This limits the window of opportunity for a compromised refresh token to be used.
  • Secure Cookie Management: Ensure IdentityServer cookies (e.g., authentication cookies) are configured with appropriate security flags: HttpOnly, Secure, and SameSite=Lax or Strict.
  • Logging and Monitoring: Implement comprehensive logging for IdentityServer events, including authentication attempts (success/failure), token issuance, and revocation. Monitor these logs for suspicious activity, such as brute-force attacks or unusual token requests.
  • Regular Updates: Keep IdentityServer and its underlying .NET framework updated to the latest stable versions to benefit from security patches and improvements.
  • Content Security Policy (CSP): For the IdentityServer UI (login pages, consent pages), implement a robust Content Security Policy to mitigate cross-site scripting (XSS) and other injection attacks.
  • Input Validation: Rigorously validate all input received by IdentityServer, especially from client applications and user interfaces, to prevent injection attacks.