这就是我的 Jwt 配置的样子:
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<DatabaseContext>()
.AddDefaultTokenProviders();
services
.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.SaveToken = true;
cfg.RequireHttpsMetadata = false;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = jwtSettings.Audience,
ValidIssuer = jwtSettings.Issuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Secret))
};
});
这就是 JwtBearerSettings
"JwtBearerSettings": {
"Issuer": "https://localhost:7032/",
"Audience": "https://localhost:7032/",
"Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr"
}
这就是我登录用户的方式
public override async Task<CommandResult> Handle(SignInCommand command, CancellationToken cancellationToken)
{
var user = await _userManager.FindByEmailAsync(command.Email);
if (user == null)
return await FailAsync(ErrorCode.NotFound);
var signInResult = await _signInManager.PasswordSignInAsync(user.UserName,
user.Password,
command.RememberMe,
false);
if (!signInResult.Succeeded)
return await FailAsync();
var accessToken = GenerateAccessToken(user);
return await OkAsync(accessToken);
}
private string GenerateAccessToken(User user)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtBearerSettings.Secret));
var token = new JwtSecurityToken(
issuer: _jwtBearerSettings.Issuer,
audience: _jwtBearerSettings.Audience,
expires: DateTime.Now.AddHours(3),
claims: claims,
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
return accessToken;
}
但是Authorize属性还是不起作用。它给了我 401 错误
我尝试将 ValidateIssuer 和 ValidateAudience 添加为 false,但仍然不起作用。 Jwt 配置部分位于从 Program.cs 调用的 DependencyResolver 类内部 之后在 Program.cs 中我使用 services.Authenticate 和 services.Authorize 方法
请允许我在这里展示带有变量的代码,以便我们能够以良好的格式看到它。
我在我这边尝试了你的代码,在生成令牌并使用令牌调用 API 时效果很好。唯一的区别是参数值,因为有些人使用变量,因此首先检查变量。这是我的测试结果。
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.SaveToken = true;
cfg.RequireHttpsMetadata = false;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = false,
ValidateAudience = false,
ValidAudience = "Test.com",
ValidIssuer = "Test.com",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this is my custom Secret key for authentication"))
};
});
private string GenerateAccessToken()
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Name, "username1"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("this is my custom Secret key for authentication"));
var token = new JwtSecurityToken(
issuer: "Test.com",
audience: "Test.com",
expires: DateTime.Now.AddHours(3),
claims: claims,
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
return accessToken;
}
顺便说一句,您还分享了一个看起来与令牌反序列化相关的异常,您能分享一下您是如何解码代码的吗?