ASP.NET实现JWT登录成功后访问[Authorize]接口返回401问题求解
问题排查点
- 中间件顺序错误
检查Startup.cs/Program.cs中的中间件注册顺序必须严格按照UseAuthentication()在前,UseAuthorization()在后,顺序颠倒会直接导致所有JWT验证失败返回401,正确顺序示例:app.UseRouting(); // 先启用身份验证 app.UseAuthentication(); // 后启用授权验证 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); - Token有效期时区不匹配
生成Token时使用的DateTime.Now为本地时区时间,而JWT默认验证使用UTC时间,时区差会导致系统判定Token未生效/已过期。修改JwtHandler.cs中GenerateTokenOptions方法的expires参数:expires: DateTime.UtcNow.AddMinutes(Convert.ToDouble(_jwtSettings.GetSection("expiryInMinutes").Value)), - 密钥长度不足
HMAC-SHA256算法要求密钥长度至少为32字节(256位),当前配置的securityKey长度不足会导致签名验证失败。将appsettings.json中的securityKey替换为长度≥32位的字符串即可。 - 请求头格式错误
访问带[Authorize]接口时,请求头Authorization必须严格按照Bearer {token}格式填写,Bearer和token之间必须有空格,缺少空格会直接返回401。使用Swagger测试时需要先配置Swagger支持JWT授权,否则输入的Token不会自动带入请求头。 - 配置拼写校验
检查appsettings.json中JWTSettings节点的键名是否和代码中读取的JwtSettings完全一致,同时核对validIssuer、validAudience的取值和请求地址完全匹配,无拼写错误。 - 登录逻辑校验缺失
当前登录接口没有判断用户是否存在、密码是否正确,就算密码输入错误也会返回无效Token,调整后的正确逻辑参考:[HttpPost] [Route("Login")] public async Task<IActionResult> Login(UserDto userDto) { var user = await _userManager.FindByNameAsync(userDto.Email); // 校验用户是否存在 if (user == null) return Unauthorized(new AuthResponseDto { IsAuthSuccessful = false, ErrorMessage = "无效的用户名或密码" }); // 校验密码是否正确 var signInResult = await _signInManager.PasswordSignInAsync(userDto.Email, userDto.Password, false, false); if (!signInResult.Succeeded) return Unauthorized(new AuthResponseDto { IsAuthSuccessful = false, ErrorMessage = "无效的用户名或密码" }); var signingCredentials = _jwtHandler.GetSigningCredentials(); var claims = await _jwtHandler.GetClaims(user); var tokenOptions = _jwtHandler.GenerateTokenOptions(signingCredentials, claims); var token = new JwtSecurityTokenHandler().WriteToken(tokenOptions); return Ok(new AuthResponseDto {IsAuthSuccessful = true, Token = token}); }
内容的提问来源于stack exchange,提问作者Rogal
相关产品推荐
相关产品推荐

