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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:35:16