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

AuthenticationMiddleware如何处理多种身份验证方案?为何仅默认方案生效?

关于ASP.NET Core AuthenticationMiddleware处理多身份验证方案的疑问

我们可以通过以下方式配置多种身份验证方案:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
        options => builder.Configuration.Bind("JwtSettings", options))
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
        options => builder.Configuration.Bind("CookieSettings", options));

但查看AuthenticationMiddleware的核心代码:

public async Task Invoke(HttpContext context)
{
    // ...
    var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
    foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
    {
        var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;
        if (handler != null && await handler.HandleRequestAsync())
        {
            return;
        }
    }

    var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
    if (defaultAuthenticate != null)
    {
        var result = await context.AuthenticateAsync(defaultAuthenticate.Name);
        // ...
    }

    await _next(context);
}

这段代码里的foreach循环只处理实现了IAuthenticationRequestHandler的方案,而我们通过AddCookie添加的CookieAuthenticationHandler的继承链如下,并未实现该接口:

public class CookieAuthenticationHandler : SignInAuthenticationHandler<CookieAuthenticationOptions>

public abstract class SignInAuthenticationHandler<TOptions> : SignOutAuthenticationHandler<TOptions>, IAuthenticationSignInHandler

// ...

那问题来了:AuthenticationMiddleware到底是如何处理多种身份验证方案并调用多个处理程序的?从代码看似乎只有默认方案会被执行?


核心结论

默认情况下,AuthenticationMiddleware确实只会自动执行默认验证方案的AuthenticateAsync逻辑。但这并不意味着其他方案完全没用,ASP.NET Core提供了多种方式触发非默认方案的验证。

具体解释

  1. IAuthenticationRequestHandler的作用
    这个接口是给那些需要主动接管请求流程的方案设计的(比如OAuth2的回调、OpenID Connect的登录回调),这类方案处理完请求后会直接返回,不会走后续中间件逻辑。而Cookie、JWT这类被动验证方案不需要实现它,它们只在被显式调用或通过策略指定时才会执行验证。

  2. 非默认方案的触发方式

    • 通过[Authorize]特性指定方案:在控制器或Action上标注[Authorize(AuthenticationSchemes = "Cookie,Bearer")],此时认证服务会依次执行指定的所有方案的验证逻辑,只要有一个验证通过就算认证成功。
    • 手动调用验证方法:在业务代码里显式调用context.AuthenticateAsync("Cookie")或context.AuthenticateAsync("Bearer"),主动触发对应方案的验证流程。
    • 通过授权策略指定多方案:在配置授权策略时,指定需要验证的多个方案,示例如下:
      builder.Services.AddAuthorization(options =>
      {
          options.AddPolicy("CookieOrJwt", policy =>
          {
              policy.AuthenticationSchemes.Add(CookieAuthenticationDefaults.AuthenticationScheme);
              policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
              policy.RequireAuthenticatedUser();
          });
      });
      
      之后在[Authorize(Policy = "CookieOrJwt")]中使用该策略即可触发多方案验证。
  3. 默认方案的意义
    默认方案是无显式指定时的 fallback 选项:比如单独使用[Authorize]特性时,会自动使用默认方案执行验证;另外,SignInAsync、SignOutAsync这类方法在不指定方案时,也会使用对应的默认登录/登出方案(可通过AddAuthentication的参数设置默认方案,也可单独配置DefaultSignInScheme、DefaultSignOutScheme等细分选项)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:30:08