ASP.NET Core 3.1多Cookie认证场景下读取Claims为空如何解决
问题排查与解决步骤
1. 修正异步登录方法的await调用
你当前代码里的HttpContext.SignInAsync是异步方法,未加await关键字会导致Cookie写入逻辑还未执行完成就提前返回响应,客户端没有拿到正确的认证Cookie,后续请求自然无法读取到Claims。
修改登录方法代码:
// 方法签名增加async关键字,返回值改为Task<ActionResult> [HttpPost] public async Task<ActionResult> Login([FromBody] UserLogin userLogin) { string hash_password = Crypto.EncryptString(userLogin.Password); Users user = databaseLogic.Users.Where(x => x.Login == userLogin.Login && x.Password == hash_password).FirstOrDefault(); if (user != null) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.Login), new Claim(ClaimTypes.Role, "Administrator"), new Claim(CustomClaimTypes.UserId, user.ID.ToString()) }; var claimsIdentity = new ClaimsIdentity(claims,"owncms"); var authProperties = new AuthenticationProperties { ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10), }; var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); // 增加await关键字等待异步方法执行完成 await HttpContext.SignInAsync("owncms", new ClaimsPrincipal(claimsIdentity), authProperties); return Json(new { status = true }); } return Json(new { status = false, message = "Login not posible" }); }
2. 明确指定认证方案
你配置了两套Cookie认证方案,但没有设置全局默认认证方案,框架不会自动加载对应Scheme的身份信息,可选择任意一种方式解决:
- 方式一:设置全局默认认证方案,修改
ConfigureServices中的注册代码:
// AddAuthentication参数指定全局默认使用的Scheme services.AddAuthentication("owncms") .AddCookie("owncms", options => { options.LoginPath = "/OwnCMS/Login"; options.Cookie.Name = "owncms"; }) .AddCookie("main", options => { options.LoginPath = "/Auth/Index"; options.Cookie.Name = "main"; });
- 方式二:在需要身份校验的Controller/Action上通过
[Authorize]特性指定对应Scheme:
// 明确指定该接口使用owncms方案校验身份 [Authorize(AuthenticationSchemes = "owncms")] public ActionResult GetUserInfo() { var identity = (ClaimsIdentity)User.Identity; IEnumerable<Claim> claims = identity.Claims; // 业务逻辑 }
如果需要同时支持两套认证方案,用逗号分隔Scheme即可:[Authorize(AuthenticationSchemes = "owncms,main")]
3. 检查中间件注册顺序
确认Startup.cs的Configure方法中,中间件注册顺序符合要求,UseAuthentication必须放在UseAuthorization和UseMvc之前,否则认证信息不会被提前加载:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件:异常处理、静态文件、CORS等 app.UseSession(); app.UseAuthentication(); // 认证中间件必须在前 app.UseAuthorization(); app.UseMvc(); }
4. 辅助排查手段
- 登录请求完成后检查浏览器Cookie存储,确认是否成功生成了名为
owncms的Cookie - 读取Claims前先判断
User.Identity.IsAuthenticated是否为true,若为false说明当前请求未通过对应方案的身份校验 - 可手动指定Scheme主动读取认证信息:
var authResult = await HttpContext.AuthenticateAsync("owncms"); if (authResult.Succeeded) { var claims = authResult.Principal.Claims; }
内容的提问来源于stack exchange,提问作者Robert Mostowski
相关产品推荐
相关产品推荐

