ASP.NET Core 3.1添加认证方案后用户身份为何被隐藏?
问题解析:为何指定认证方案后中间件创建的身份不被识别
这个问题的核心在于ASP.NET Core授权系统在策略指定AddAuthenticationSchemes后的行为逻辑,我来帮你拆解清楚:
背后的原理
当你在授权策略中通过policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme)指定具体认证方案时,授权组件会跳过当前HttpContext.User中已有的身份,主动触发该指定方案的完整认证流程。
简单来说:
- 没加
AddAuthenticationSchemes时,授权系统直接复用HttpContext.User里已有的身份(只要这个身份的IsAuthenticated = true),接着检查角色等授权要求即可。 - 加了
AddAuthenticationSchemes后,授权系统会调用对应方案的认证Handler(这里就是Cookie认证Handler)重新验证身份——它会去请求里查找标准的Cookie(比如默认的.AspNet.Cookies),但你的测试中间件只是手动创建了ClaimsIdentity并赋值给HttpContext.User,并没有实际生成对应的Cookie,所以Cookie认证Handler找不到有效凭证,自然返回未认证结果,导致授权失败。
解决思路
根据你的测试场景,有几种可选的处理方式:
- 保留现有测试中间件:如果你的测试不需要严格模拟真实Cookie认证流程,那就不要在授权策略中指定
AddAuthenticationSchemes,直接依赖HttpContext.User里的身份做授权验证即可——这也是你注释掉那行代码后能正常工作的原因。 - 模拟真实Cookie认证流程:如果必须在策略中指定认证方案,测试中间件需要模拟真实的Cookie生成逻辑——比如用
CookieAuthenticationOptions里的TicketDataFormat加密生成Cookie值,再添加到请求的Cookie集合中,让Cookie认证Handler能识别到有效凭证。 - 使用测试专用认证Handler:在集成测试项目中,替换真实的Cookie认证方案,改用ASP.NET Core测试库提供的
AddTestAuthHandler,这样既能注入预设身份,又能兼容策略中指定的认证方案。
举个测试Handler的简单示例:
// 测试项目的Startup配置中 services.AddAuthentication("smart") .AddPolicyScheme("smart", "Bearer Authorization or Cookie", options => { // 保持原有转发逻辑配置 options.ForwardDefaultSelector = context => { var requestPath = context.Request.Path; if (CookiePolicyPathRegex.IsMatch(requestPath)) { return CookieAuthenticationDefaults.AuthenticationScheme; } return JwtBearerDefaults.AuthenticationScheme; }; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme) // 添加测试Handler关联Cookie认证方案 .AddTestAuthHandler<CookieAuthenticationDefaults.AuthenticationScheme>(options => { options.Claims = new[] { new Claim(ClaimTypes.Role, Roles.Access) }; }) .AddOAuthServiceScheme(Configuration);
这样既保留了策略中指定的认证方案,又能在测试中直接注入预设身份,无需手动操作Cookie或HttpContext.User。
内容的提问来源于stack exchange,提问作者Tamás Szabó
相关产品推荐
相关产品推荐

