我正在尝试将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);
}
答案 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
)