ASP.NET Identity+JWT问题:登录后User为空、IsAuthenticated为false
ASP.NET Core Identity + JWT 认证问题修复
问题现象
- 用户登录后成功生成JWT Token,但
User对象始终为Null,IsAuthenticated属性一直为false,无法通过HttpContext获取用户信息 - 给
Context接口添加[Authorize]特性后,服务器返回404错误
核心问题分析
- 认证方案冲突:
AddIdentity默认会注册Cookie认证作为默认方案,而JWT认证的配置未正确设置默认方案,导致系统优先使用Cookie认证而非JWT - Token验证参数错误:
TokenValidationParameters中错误设置了AuthenticationType = "ApplicationCookie",与JWT认证方案不匹配 - [Authorize]特性未指定认证方案:未明确告诉接口使用JWT认证,导致系统尝试用Cookie认证,因无有效Cookie触发未授权逻辑,最终返回404(而非预期的401)
修复步骤
1. 修改Startup.cs配置
调整认证服务配置
// 替换原AddAuthentication代码 services.AddAuthentication(options => { // 设置默认认证方案为JWT options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { LifetimeValidator = (before, expires, token, param) => { return expires > DateTime.UtcNow; }, // 若要严格验证Issuer/Audience,需与生成Token时的值一致,否则保持关闭 ValidateAudience = false, ValidateIssuer = false, ValidateActor = false, ValidateLifetime = true, IssuerSigningKey = SecurityKey, // 移除错误的AuthenticationType配置,或设置为JwtBearerDefaults.AuthenticationScheme // AuthenticationType = JwtBearerDefaults.AuthenticationScheme }; options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { Console.WriteLine(context.Exception); return Task.CompletedTask; }, }; });
注意事项
- 确保
SecurityKey的编码一致:生成Token时用的是Encoding.Default.GetBytes,验证时也要保持一致(建议统一用Encoding.UTF8避免编码问题)
2. 修改AccountController代码
修正Context接口的授权特性
// 明确指定使用JWT认证方案,或在Startup设置默认方案后直接用[Authorize] [HttpGet("context")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public JsonResult Context() { var userName = User.Identity?.Name; var userRole = User.FindFirstValue(ClaimTypes.Role); string tokenHeader = HttpContext.Request.Headers["Authorization"]; return Json(new { username = userName, role = userRole, auth = User.Identity?.IsAuthenticated ?? false, tokenHeader = tokenHeader }); }
修正Logout接口(JWT无状态,无需后端登出)
[HttpPost("logout")] [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public IActionResult Logout() { // JWT是无状态认证,后端无需处理登出,前端直接删除本地存储的Token即可 return Ok(new { message = "登出成功" }); }
移除JwtLogin接口中的无用返回值
// JwtLogin接口中,当前请求未携带Token,所以User.IsAuthenticated必然为false,无需返回 return Json(new { token = token });
3. 前端请求注意事项
- 请求需要携带Token时,需在请求头中添加
Authorization: Bearer {你的Token} - 确保Token没有过期,且签名密钥与后端一致
内容的提问来源于stack exchange,提问作者mattiamoneta
相关产品推荐
相关产品推荐

