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

.NET Core Negotiate认证方案失效及AD用户Claims获取问题求助

.NET 7 认证授权部署问题排查与解决

项目配置

项目中认证与授权配置如下:

builder.Services.AddAuthentication()
    .AddNegotiate(NegotiateDefaults.AuthenticationScheme, _ => { })
    .AddCertificate(CertificateAuthenticationDefaults.AuthenticationScheme,
        options => {
            options.RevocationMode = X509RevocationMode.NoCheck;
            options.ValidateCertificateUse = true;
            options.ValidateValidityPeriod = true;
            options.Events = new CertificateAuthenticationEvents() {
                OnAuthenticationFailed = InvalidCertificates.InvalidCertificateHandler,
                OnCertificateValidated = ValidCertificates.ValidCertificateHandler
            };
        });

builder.Services.AddAuthorization(options => {
    options
        .AddPolicy(AuthorizationsConstants.AuthenticatedUser,
            policy => {
                policy.RequireAuthenticatedUser();
                policy.AuthenticationSchemes = new[] { NegotiateDefaults.AuthenticationScheme, CertificateAuthenticationDefaults.AuthenticationScheme };
                policy.Requirements.Add(new ValidCertificateRequirement());
            });
    options
        .AddPolicy(AuthorizationsConstants.ReportAuthorization,
        policy => {
            policy.Requirements.Add(new ReportAuthorizationRequirement());
        });
});

环境与问题现象

  • 本地环境:授权处理器的context.User包含ClaimsIdentity和WindowsIdentity两个身份,IClaimsTransformation会被调用两次(对应Negotiate和证书方案)。
  • 部署环境:IIS加入域,启用ClientCertificateMappingAuthentication,用户证书映射到AD账户。
    1. 初始部署报错:The Negotiate Authentication handler cannot be used on a server that directly supports Windows Authentication. Enable Windows Authentication for the server and the Negotiate Authentication handler will defer to it.
    2. 启用应用的Windows Authentication后错误消失,但context.User仅包含一个ClaimsIdentity,无法获取AD填充的用户Claims。
    3. IClaimsTransformation仅调用一次,推测Negotiate的AuthenticateAsync未执行;失败请求跟踪显示证书映射导致NTLM设为false,未触发Negotiate方案。

解决方案

1. 移除手动注册的Negotiate认证

在IIS已启用Windows Authentication的场景下,ASP.NET Core的Negotiate handler会自动委托给IIS的Windows Auth模块处理Negotiate/NTLM认证,无需手动注册AddNegotiate()。修改认证配置:

builder.Services.AddAuthentication()
    .AddCertificate(CertificateAuthenticationDefaults.AuthenticationScheme,
        options => {
            options.RevocationMode = X509RevocationMode.NoCheck;
            options.ValidateCertificateUse = true;
            options.ValidateValidityPeriod = true;
            options.Events = new CertificateAuthenticationEvents() {
                OnAuthenticationFailed = InvalidCertificates.InvalidCertificateHandler,
                OnCertificateValidated = ValidCertificates.ValidCertificateHandler
            };
        });

2. 调整授权策略的认证方案

将授权策略中的认证方案替换为IIS默认的Windows认证方案,确保兼容IIS传递的身份:

builder.Services.AddAuthorization(options => {
    options
        .AddPolicy(AuthorizationsConstants.AuthenticatedUser,
            policy => {
                policy.RequireAuthenticatedUser();
                // 替换为IIS Windows认证方案+证书认证方案
                policy.AuthenticationSchemes = new[] { 
                    IISDefaults.AuthenticationScheme, 
                    CertificateAuthenticationDefaults.AuthenticationScheme 
                };
                policy.Requirements.Add(new ValidCertificateRequirement());
            });
    options
        .AddPolicy(AuthorizationsConstants.ReportAuthorization,
        policy => {
            policy.Requirements.Add(new ReportAuthorizationRequirement());
        });
});

3. 配置IIS身份转发

确保IIS将Windows身份正确传递给ASP.NET Core应用:

builder.WebHost
    .UseIISIntegration(options => {
        options.ForwardWindowsAuthentication = true;
    });

4. 适配IClaimsTransformation逻辑

针对部署环境的单身份场景调整转换逻辑,确保从WindowsIdentity或证书认证身份中获取AD Claims:

public class ClaimsTransformer : IClaimsTransformation
{
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var identity = principal.Identity as ClaimsIdentity;
        
        // 处理Windows身份场景
        if (principal.Identity is WindowsIdentity windowsIdentity)
        {
            var adClaims = await FetchAdClaims(windowsIdentity.Name);
            foreach (var claim in adClaims)
            {
                identity.AddClaim(claim);
            }
        }
        // 处理证书认证场景
        else if (identity.AuthenticationType == CertificateAuthenticationDefaults.AuthenticationScheme)
        {
            var userName = identity.FindFirst(ClaimTypes.Name)?.Value;
            if (!string.IsNullOrEmpty(userName))
            {
                var adClaims = await FetchAdClaims(userName);
                foreach (var claim in adClaims)
                {
                    identity.AddClaim(claim);
                }
            }
        }
        return principal;
    }

    private async Task<IEnumerable<Claim>> FetchAdClaims(string userName)
    {
        // 实现从AD获取用户Claims的逻辑(例如使用DirectoryServices)
        var claims = new List<Claim>();
        // 示例:添加部门、角色等自定义Claims
        return claims;
    }
}

5. 验证IIS配置

  • 确认站点已启用Windows Authentication和Client Certificate Mapping Authentication。
  • 检查Windows Authentication的Providers包含Negotiate和NTLM。
  • 确认证书映射规则正确关联到AD用户(使用证书Subject或Thumbprint)。

关键说明

IIS启用Windows Authentication后,会直接处理Negotiate/NTLM认证并将WindowsIdentity传递给ASP.NET Core,此时无需手动维护Negotiate handler。结合证书认证逻辑,即可同时支持两种认证方式并获取AD填充的用户Claims。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:55:01