You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1中AddOpenIdConnect与AddJwtBearer中间件疑问

ASP.NET Core 3.1 OIDC & JWT Bearer Middleware Questions Answered

Hey there! Let's break down your questions step by step—since you're new to this deeper ASP.NET Core auth stuff, it's totally normal to hit these confusion points. First, let's clarify what each middleware does, then tackle your specific questions and the odd behaviors you're seeing.

First: Core Roles of the Two Middleware

  • AddOpenIdConnect(): Handles the full OpenID Connect authentication flow (like the authorization code flow you're using with ResponseType = Code). It manages redirecting users to your OIDC authority, exchanging the authorization code for tokens (ID Token, Access Token, Refresh Token), validating the ID Token, and storing user claims + tokens in an authentication cookie (when SaveTokens = true).
  • AddJwtBearer(): Designed for validating Access Tokens sent in the Authorization: Bearer header (typically used for API endpoints). It doesn't handle user login/redirects—it just checks that incoming JWTs are valid, signed by your authority, and match the expected audience/issuer.

Quick Side Note: Why Are You Seeing Requests to /.well-known/oidc-configuration and /.well-known/keys?

Both middleware automatically fetch this metadata on startup (or first request) to:

  1. Get OIDC authority details (token endpoints, supported scopes, etc.) from /.well-known/oidc-configuration
  2. Retrieve public signing keys from /.well-known/keys to verify the signature of JWTs (ID Tokens for OpenIdConnect, Access Tokens for JwtBearer)
    This is all handled internally by the middleware—you don't need to write code for these requests.

Your Specific Questions Answered

1. Will AddJwtBearer() automatically validate ID Tokens after proper configuration?

Short answer: No—AddJwtBearer() is built to validate Access Tokens, not ID Tokens. The ID Token validation is handled entirely by AddOpenIdConnect() as part of the OIDC flow.

For AddJwtBearer(), if you set a valid Authority and Audience, it will automatically:

  • Fetch the public keys from the authority's JWKS endpoint
  • Validate the Access Token's signature, issuer, audience, lifetime, and other parameters you set in TokenValidationParameters

The reason your ValidAudience change didn't break authentication is likely because your app is using the cookie authentication scheme (from AddOpenIdConnect()) by default, not the JwtBearer scheme. To trigger JwtBearer validation, you need to either:

  • Set it as the default authentication scheme (e.g., services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme))
  • Decorate your API controllers/actions with [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

2. If manual validation is needed, how to store JWKs fetched from /.well-known/keys?

You almost never need to manually store these—both middleware automatically cache the JWKs internally. If you do need access to them for custom logic, you can inject the IConfigurationManager<OpenIdConnectConfiguration> service into your code. For example:

private readonly IConfigurationManager<OpenIdConnectConfiguration> _configManager;

public YourService(IConfigurationManager<OpenIdConnectConfiguration> configManager)
{
    _configManager = configManager;
}

public async Task<IEnumerable<SecurityKey>> GetSigningKeysAsync()
{
    var config = await _configManager.GetConfigurationAsync(CancellationToken.None);
    return config.SigningKeys;
}

This gives you access to the same keys the middleware uses for validation.

3. How to get the Access/Refresh Token cookies and send the Refresh Token to the authority?

First, when you set SaveTokens = true in AddOpenIdConnect(), the tokens are stored encrypted in the authentication cookie (.AspNetCore.Cookies), which is why you don't see plaintext ey... JWTs in the cookie content. To retrieve them, use HttpContext.GetTokenAsync():

// Get Access Token
var accessToken = await HttpContext.GetTokenAsync("access_token");
// Get Refresh Token
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");

To refresh your tokens, send a POST request to your authority's token endpoint (you can get this from the OIDC metadata) with these parameters:

grant_type: refresh_token
refresh_token: [your_refresh_token]
client_id: [your_client_id]
client_secret: [your_client_secret]
scope: [your_scopes (optional, if you want the same scopes)]

You can use HttpClient to send this request, then update the stored tokens using HttpContext.SignInAsync() with the new tokens in AuthenticationProperties.

4. Can the middleware's options.Events solve these issues?

Absolutely—events let you hook into key parts of the auth flow to customize behavior:

  • For AddOpenIdConnect():
    • OnTokenReceived: Capture tokens right after they're retrieved from the authority
    • OnAuthenticationFailed: Debug why ID Token validation failed
    • OnAuthorizationCodeReceived: Customize the code exchange process
  • For AddJwtBearer():
    • OnTokenValidated: Add custom validation logic (e.g., check additional claims)
    • OnAuthenticationFailed: See why JWT validation failed (this would have told you why changing ValidAudience didn't trigger an error—if the scheme wasn't being used)
    • OnMessageReceived: Customize how the Access Token is retrieved from the request

For example, if you want to log JWT validation failures, you could add this to AddJwtBearer():

options.Events = new JwtBearerEvents
{
    OnAuthenticationFailed = context =>
    {
        // Log the error details
        Console.WriteLine($"JWT Validation Failed: {context.Exception.Message}");
        return Task.CompletedTask;
    }
};

5. What operations do these middleware handle automatically?

AddOpenIdConnect():

  • Redirects users to the OIDC authority's login page when an unauthenticated user accesses a protected resource
  • Handles the authorization code exchange to get ID Token, Access Token, and Refresh Token
  • Validates the ID Token's signature, issuer, audience, and lifetime automatically
  • Stores user claims in the authentication cookie
  • Saves tokens (when SaveTokens = true) in encrypted form in the cookie
  • Note: It does not automatically refresh tokens in the background—you need to handle this manually (using the Refresh Token and HttpContext.SignInAsync()) or use limited built-in refresh logic (triggered when RefreshOnIssuerKeyNotFound = true).

AddJwtBearer():

  • Automatically extracts the Access Token from the Authorization: Bearer header
  • Fetches and caches public signing keys from the OIDC authority's JWKS endpoint
  • Validates the Access Token's signature, issuer, audience, lifetime, and other parameters in TokenValidationParameters
  • Handles clock skew (via ClockSkew setting) to account for minor time differences between servers
  • Note: It doesn't handle token refresh or user login—its sole job is validating incoming Access Tokens.

内容的提问来源于stack exchange,提问作者deathcat05

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:23:43