.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账户。- 初始部署报错:
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. - 启用应用的Windows Authentication后错误消失,但
context.User仅包含一个ClaimsIdentity,无法获取AD填充的用户Claims。 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
相关产品推荐
相关产品推荐

