我正在构建一个 ASP.NET Core Rest API(具有角度前端的核心 8.0)应用程序,该应用程序对某些路由使用 JWT 承载身份验证,对其他路由使用 Windows 身份验证(协商)。但是,我面临着两种身份验证方案似乎都在全局应用的问题,导致响应中出现不需要的 WWW-Authenticate 标头。具体来说:
对于 JWT 保护的路由,我看到 WWW-Authenticate: Bearer、Negotiate、NTLM,但我只想要 WWW-Authenticate: Bearer。 对于 Windows 保护的路由,我只需要 WWW-Authenticate: Negotiate。
我尝试过的 这是我的 Program.cs 配置:
// Authentication configuration
builder.Services.AddAuthentication()
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["Jwt:Key"]))
};
})
.AddNegotiate(); // Windows Authentication
// Authorization policies
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("JwtAuthPolicy", policy =>
{
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
options.AddPolicy("WinAuthPolicy", policy =>
{
policy.AuthenticationSchemes.Add(NegotiateDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
});
// Middleware configuration
app.UseAuthentication();
app.UseAuthorization();
我将
[Authorize(Policy = "JwtAuthPolicy")]
用于 JWT 路由,将 [Authorize(Policy = "WinAuthPolicy")]
用于 Windows 身份验证路由。但是,WWW-Authenticate 标头并不限于其各自的路由。
我需要什么 如何确保 WWW-Authenticate 标头仅根据路由通告相关方案(Bearer 或 Negotiate)? 有没有办法通过中间件或更好的配置方法来强制执行此行为? 任何指导或示例将不胜感激。谢谢!
即使我无法重现(我根据应用的策略在 WWW-Authenticate 中返回了一个方案),您也可以注册自定义 IAuthenticationService 实现并覆盖 ChallengeAsync -
class MyAuthenticationService : AuthenticationService
{
...
public override async Task ChallengeAsync(HttpContext context, string? scheme, AuthenticationProperties? properties)
{
await base.ChallengeAsync(context, scheme, properties);
context.Response.Headers.WWWAuthenticate = "your_custom_value";
}
}
builder.Services.AddScoped<IAuthenticationService, MyAuthenticationService>();