【问题标题】:Sending post request with Authorization header and token returns unauthorized发送带有 Authorization 标头和令牌的 post 请求返回未经授权
【发布时间】:2019-08-07 20:58:09
【问题描述】:

我正在尝试使用 jwt 作为我的令牌并使用它来访问授权的 API。我使用Postman 来测试我的API 并使用值Bearer MyToken 添加授权标头,但服务器响应是401 UnAuthorized。 这是我创建令牌的方式: 在我的启动中:

 services.AddAuthentication (JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer (options => {
                    options.TokenValidationParameters = new TokenValidationParameters {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey (Encoding.ASCII
                    .GetBytes (Configuration.GetSection ("AppSettings:Token").Value)),
                    ValidateIssuer = false,
                    ValidateAudience = false
                    };
                });
app.UseAuthentication ();

我已将[Authorize]放在我的控制器顶部。这是我创建令牌的部分:

class JWTToken {

        public static object CreateToken (string Guid) {
            var claims = new [] { new Claim (ClaimTypes.NameIdentifier, Guid) };
            var key = new SymmetricSecurityKey (Encoding.UTF8.GetBytes ("Super secret key"));
            var creds = new SigningCredentials (key, SecurityAlgorithms.HmacSha512Signature);
            var tokenDescriptor = new SecurityTokenDescriptor {
                Subject = new ClaimsIdentity (claims), Expires = DateTime.Now.AddYears (2), SigningCredentials = creds
            };
            var tokenHandler = new JwtSecurityTokenHandler ();
            var token = tokenHandler.CreateToken (tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }

【问题讨论】:

    标签: c# .net-core jwt


    【解决方案1】:

    您使用不同的编码:

    // Here you use ASCII
    IssuerSigningKey = new SymmetricSecurityKey (Encoding.ASCII
                        .GetBytes (Configuration.GetSection ("AppSettings:Token").Value))
    
    // Here you use UTF8
    var key = new SymmetricSecurityKey (Encoding.UTF8.GetBytes ("Super secret key"));
    

    还要确保您的 Configuration.GetSection ("AppSettings:Token").Value 与您用于创建 JWT 的 "Super secret key" 相同。

    编辑: 这是我的有效配置:

    // In ConfigureServices
    var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Token:SigningKey"]));
                services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(config =>
                {
    
                    config.RequireHttpsMetadata = false;
                    config.SaveToken = true;
                    config.TokenValidationParameters = new TokenValidationParameters
                    {
                        IssuerSigningKey = signingKey,
                        ValidateAudience = true,
                        ValidAudience = this.Configuration["Token:Audience"],
                        ValidateIssuer = true,
                        ValidIssuer = this.Configuration["Token:Issuer"],
                        RequireExpirationTime = true,
                        RequireSignedTokens = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ClockSkew = TimeSpan.FromMinutes(3)
                    };
                });
    
    // In token controller
    private string GetToken(AppUser user)
    {
        var utcNow = DateTime.UtcNow;
    
        var claims = new Claim[]
        {
                new Claim(JwtRegisteredClaimNames.Sub, user.Id),
                new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
                new Claim(JwtRegisteredClaimNames.Email, user.Email),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Iat, utcNow.ToString())
            };
    
            var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Token:SigningKey"]));
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            var jwt = new JwtSecurityToken(
                signingCredentials: signingCredentials,
                claims: claims,
                notBefore: utcNow,
                expires: utcNow.AddSeconds(_configuration.GetValue<int>("Token:Lifetime")),
                audience: _configuration["Token:Audience"],
                issuer: _configuration["Token:Issuer"]
            );
        return new JwtSecurityTokenHandler().WriteToken(jwt);
    }
    

    也许对你有帮助。

    【讨论】:

    • 我已经更正了编码,是的 jwt 键是一样的,结果还是一样的
    【解决方案2】:

    您需要验证令牌签名。您将 ValidateIssuersigningKey 设置为 true,但您是否分配了正确的密钥来验证它?您也可以尝试实现自定义验证方法。

    中间件,如果它认为令牌无效,将响应 401,因为它无法被授权 (Unauthotized)

    【讨论】:

    • 是的,密钥在 appsettings.json 中并且是“超级密钥”,我在 ValidateIssuersigningKey 之后的下一行验证它
    猜你喜欢
    • 2021-03-24
    • 2017-10-16
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 2015-11-27
    • 2020-02-13
    • 2015-04-24
    • 2015-12-06
    相关资源
    最近更新 更多