VS Code中ASP.NET Core角色处理器Windows身份验证失效问题
ASP.NET Core 6 + Kestrel 下Windows身份验证异常:Claims转换器正常但授权Handler中用户信息为空
在VS Code中使用Kestrel运行ASP.NET Core 6项目时,遇到Windows身份验证异常:
- Claims转换器(
IClaimsTransformation实现类)中能正常获取登录用户的identity.Name,且IsAuthenticated为true - 但在自定义授权Handler(
AuthenticatedRoleHandler)中,context.User的Claims为空,也获取不到用户名 - 该功能在Visual Studio 2019 + ASP.NET Core 5(使用IIS Express)环境下完全正常,仅在VS Code + Kestrel环境下失效
排查过程与解决结果
排查更新1:用Fiddler抓包分析请求,发现第二次请求已完成身份验证,请求头中存在带Negotiate的有效Authorization头,说明Windows身份验证流程本身正常,但请求返回400(请求格式错误)。
排查更新2:最终定位问题仍在身份验证环节,创建服务主体名称(SPN)后问题完全解决。Fiddler中明确显示:
Authorization Header (Negotiate) appears to contain a Kerberos ticket:
相关代码示例
身份验证配置及Claims转换器代码
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); public class MyClaimsTransformer : IClaimsTransformation { public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { ClaimsIdentity identity = principal.Identity as ClaimsIdentity; string userName = identity.Name.ToLower(); bool auth = identity.IsAuthenticated; string[] roles = new string[]{"admin"}; foreach (string role in roles) { identity.AddClaim(new Claim(ClaimTypes.Role, role)); } return Task.FromResult(principal); } }
自定义授权Handler代码
public class AuthenticatedRoleHandler : AuthorizationHandler<AuthenticatedRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthenticatedRequirement requirement) { ClaimsPrincipal user = context.User; if (user != null && user.Identity.IsAuthenticated) { context.Succeed(requirement); } else { context.Fail(); } return Task.CompletedTask; } }
Program.cs完整配置代码
string CorsPolicy = "CorsPolicy"; WebApplicationBuilder? builder = WebApplication.CreateBuilder(args); builder.WebHost.UseKestrel(); ConfigurationManager _configuration = builder.Configuration; // Add services to the container. IServiceCollection? services = builder.Services; services.AddTransient<IActiveDirectoryUserService, ActiveDirectoryUserService>(); services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); services.AddControllersWithViews(); services.AddScoped<IClaimsTransformation, MyClaimsTransformer>();//仅在身份验证通过后执行,但此前未触发验证 services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; options.AddPolicy("AuthenticatedOnly", policy => { policy.Requirements.Add(new AuthenticatedRequirement(true)); }); }); services.AddSingleton<IAuthorizationHandler, AppUserRoleHandler>(); services.AddSingleton<IAuthorizationHandler, AuthenticatedRoleHandler>(); services.AddCors(options => { options.AddPolicy(CorsPolicy, builder => builder .WithOrigins("https://localhost:7021","https://localhost:44414") //注意:URL不能以斜杠结尾 .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); WebApplication app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseHsts(); } app.UseAuthentication(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting();
内容的提问来源于stack exchange,提问作者Charles Owen
相关产品推荐
相关产品推荐

