为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?

Posted

技术标签:

【中文标题】为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?【英文标题】:Why I'm getting a 401 unauthorized working with JWT in Asp.Net CORE?为什么我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权? 【发布时间】:2020-08-20 14:29:12 【问题描述】:

我正在尝试使用 JsonWebTokens(JWT) 在 Asp.net CORE 中进行用户身份验证。

当我在我的应用程序中运行登录方法时,令牌会正确生成,但是,当我尝试转到受 [Authorize] 属性限制的方法时,我会收到 401 未经授权的错误。

Bearer error=\"invalid_token\", error_description=\"签名无效\"

这就是我在Startup 中的ConfigureServices 方法中配置的方式:

services.AddAuthentication(x =>
        
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

        ).AddJwtBearer(x =>
        
            var key = Encoding.ASCII.GetBytes("asdwda1d8a4sd8w4das8d*w8d*asd@#");
            var signingKey = new SymmetricSecurityKey(key);

            x.RequireHttpsMetadata = false;
            x.SaveToken = true;
            x.TokenValidationParameters = new TokenValidationParameters()
            
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidAudience = "Audience",
                ValidIssuer= "Issuer",
                ValidateIssuer = false,
                ValidateAudience = false
            ;
        );

这就是我在Startup的配置中的配置方式:

app.UseAuthentication();

这是LoginController中的令牌生成:

                var tokenDescriptor = new SecurityTokenDescriptor
            
                Subject = new ClaimsIdentity(new Claim[]
                
                    new Claim("UserID", login.IdUsuario.ToString())
                ),
                Expires = DateTime.UtcNow.AddDays(1),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes("asdwda1d8a4sd8w4das8d*w8d*asd@#")), 
            SecurityAlgorithms.HmacSha256Signature)
            ;
            var tokenHandler = new JwtSecurityTokenHandler();
            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
            var token = tokenHandler.WriteToken(securityToken);

            return Ok( new  token  );

这是我限制的类,也是拒绝访问的类

[HttpGet]
[Authorize]
[Route("Profile")]
public IActionResult Profile()

     string userID = User.Claims.First(c => c.Type == "UserID").Value;
     var resultado = _Usuarioservicio.Profile(int.Parse(userID));
     return Ok(resultado);

我正在用邮递员测试这个,我已经添加了相应的标题。

非常感谢您花时间看这个!

【问题讨论】:

您是否尝试在您的令牌前面的标头中添加“Bearer”字样? @xray 错误表示签名无效,这意味着令牌即将到达服务器,但它没有有效的签名。仔细看代码,这里的key不匹配。 什么@PrateekKumarDalbehera 我相信它朝着正确的方向发展。我相信他说的是: SymmetricSecurityKey(Encoding.UTF8.GetBytes("1234567890123456") 这与 configureservices 中的内容不同 嗨,谢谢你的提问! 我已经在启动时添加了与控制器相同的签名,但错误仍在继续,是的,在测试中的令牌前添加单词 Bearer 【参考方案1】:

您的令牌中的key 与您在配置中设置的不匹配。它们必须完美匹配。

【讨论】:

您好,感谢您的回答!我已经在启动时添加了与控制器相同的签名,但错误仍在继续 您应该编辑您的问题,而不是发布答案。将您的签名算法更改为Hmac256 嘿,谢谢你的建议!我已经这样做了,我还继续使用 HmacSha256 而不是 HmacSha256Signature 但错误仍在继续【参考方案2】:

请在生成令牌和验证令牌时使用相同的对称密钥。从您共享的代码中,在生成令牌时,您将签名密钥用作“1234..”,但在 startup.cs 中进行验证时,您正在使用“ab de..”。这就是为什么,它抱怨签名无效,因为两个密钥都不匹配。

另外,请将密钥存储在安全的配置文件中。如果是实时的,请使用非对称密钥(公钥和私钥)

【讨论】:

您好,谢谢您的回答!我已经在控制器中添加了与启动时相同的签名,但错误仍在继续

以上是关于为啥我在 Asp.Net CORE 中使用 JWT 获得 401 未经授权?的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net Core、JWT 和 CORS 标头

ASP.NET Core 2.1 Jwt 设置自定义声明

ASP.NET Core JWT 和声明

为啥我的 Asp.Net Core 日志中出现“不支持 POST 请求”?

ASP.NET Core 2.2 JWT 身份验证

如何保护 ASP.NET Core Web API 免受被盗 JWT 令牌以进行模拟