发送带有授权标头和令牌的帖子请求未授权

时间:2019-03-17 08:45:23

标签: c# .net-core jwt

我正在尝试将jwt用作我的令牌,并使用它来访问授权的API。我使用Postman测试我的API并添加带有值Bearer MyToken的Authorization标头,但是服务器响应为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);
        }

2 个答案:

答案 0 :(得分:2)

您使用不同的编码:

// 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);
}

也许会对您有所帮助。

答案 1 :(得分:1)

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

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