如何检查当前请求实际使用的身份验证方案?
获取ASP.NET Core请求实际使用的身份验证方案
方案一:在认证Handler事件中注入方案到ClaimsPrincipal
每个身份验证方案的Handler在成功认证时会触发对应事件(比如JWT的OnAuthenticated、Cookie的OnValidatePrincipal),我们可以在这些事件中将当前方案名添加到ClaimsPrincipal的Claim中,后续直接从Claim读取即可。
配置示例:
services.AddAuthentication() .AddJwtBearer("Scheme1", options => { // 你的JWT配置(例如Authority、Audience等) options.Events = new JwtBearerEvents { OnAuthenticated = context => { // 向Principal添加标记实际认证方案的Claim context.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim("X-Auth-Scheme", context.Scheme.Name) })); return Task.CompletedTask; } }; }) .AddCookie("Scheme2", options => { // 你的Cookie配置(例如LoginPath等) options.Events = new CookieAuthenticationEvents { OnValidatePrincipal = context => { context.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim("X-Auth-Scheme", context.Scheme.Name) })); return Task.CompletedTask; } }; });
获取实际方案:
// 在控制器/视图/服务中,从User(HttpContext.User)读取 var actualScheme = User.FindFirstValue("X-Auth-Scheme");
这种方式单元测试非常友好,只需要构造包含对应Claim的ClaimsPrincipal即可:
// 单元测试模拟认证用户 var testUser = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("X-Auth-Scheme", "Scheme1") }, "Scheme1"));
方案二:通过AuthenticationFeature全局捕获
ASP.NET Core的IAuthenticationFeature特性中包含OriginalAuthenticationScheme字段,这个字段记录了实际用于认证的方案名。可以通过自定义中间件在认证完成后读取该值,并存到HttpContext.Items或直接注入到ClaimsPrincipal中。
中间件配置:
app.UseAuthentication(); app.UseAuthorization(); // 自定义中间件必须放在认证、授权中间件之后 app.Use(async (context, next) => { var authFeature = context.Features.Get<IAuthenticationFeature>(); if (authFeature != null && !string.IsNullOrEmpty(authFeature.OriginalAuthenticationScheme)) { // 方案1:存入HttpContext.Items供后续使用 context.Items["ActualAuthScheme"] = authFeature.OriginalAuthenticationScheme; // 方案2:注入到ClaimsPrincipal(和方案一效果一致) context.User.AddIdentity(new ClaimsIdentity(new[] { new Claim("X-Auth-Scheme", authFeature.OriginalAuthenticationScheme) })); } await next(); });
获取实际方案:
// 从HttpContext.Items读取 var actualScheme = HttpContext.Items["ActualAuthScheme"] as string;
为什么原方案效果不佳?
你之前使用的IAuthenticateResultFeature返回的是[Authorize]属性中指定的所有方案(逗号分隔的字符串),而非实际成功完成认证的单个方案。这是因为当配置多方案时,认证中间件会尝试所有允许的方案,只有实际通过认证的那个方案才会被记录在AuthenticationFeature.OriginalAuthenticationScheme或Handler的事件上下文里。
内容的提问来源于stack exchange,提问作者Animu
相关产品推荐
相关产品推荐

