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

ASP.NET 8中Windows身份验证结合自定义策略授权致HandleRequirementAsync调用两次

问题分析与解决方案

为什么授权处理器会被调用两次?

这是Negotiate(NTLM/Kerberos)认证的挑战-响应机制导致的:

  • 第一次请求:客户端未携带认证凭证,服务器返回401挑战,此时授权流程会执行一次,但用户还未完成认证,所以IsAuthenticated为false。
  • 第二次请求:客户端收到401后,自动携带认证凭证发起请求,此时认证完成,授权流程再次执行,IsAuthenticated为true。

这属于该认证方式的正常行为,并非代码bug。

优化方案:避免未认证时的无效授权调用

修改授权策略配置,强制要求用户先完成认证,再执行自定义授权逻辑:

builder.Services.AddAuthorization(options =>
{
  options.AddPolicy("CanGetWeather", policy =>
  {
    policy.RequireAuthenticatedUser(); // 新增:仅允许已认证用户进入授权逻辑
    policy.Requirements.Add(new CanGetWeatherRequirement());
  });
});

这样只有当用户认证通过后,才会触发你的自定义授权处理器,避免第一次未认证时的无效调用。

另外,你的授权处理器代码有个潜在风险:context.User.Identities.First()可能会在用户无身份标识时抛出空引用异常,建议调整为:

protected override async Task HandleRequirementAsync(
  AuthorizationHandlerContext context,
  CanGetWeatherRequirement requirement
)
{
  var identity = context.User.Identity;
  if (identity?.IsAuthenticated == true)
  {
    if (await UserCanGetWeatherAsync())
      context.Succeed(requirement);
  }
}

额外说明

如果使用Bearer Token这类认证方式,客户端会在第一次请求就携带认证凭证,不会出现两次授权调用的情况。而Negotiate认证依赖HTTP的挑战-响应流程,两次请求是其固有特性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:10:57