我想使用 [Authorize] 装饰器保护以下 API 端点:
[Authorize]
[Route("[controller]")]
public class FastaController : Controller
{
[HttpGet()]
public async Task<IActionResult> Get(int page = 1, string search = "", int pageSize = 25)
{
// retrieve data here
}
}
调用此端点时,会在代码进入方法之前返回 401 Unauthorized。
我的appsettings.json文件的JwtTokenSettings如下:
"JwtTokenSettings": {
"Key": "fc746b61cde4f6665d3f9791446cd5395661860c0075a905ed9810b7391af467",
"Issuer": "Comply",
"Audience": "comply",
"ExpiryHours": 24
}
我还有一个 JwtTokenSettings 的配置设置类,它具有相同的名称,JwtTokenSettings(未显示)。
JWT 令牌是通过从我编写的 JwtTokenService 调用GenerateToken 创建的:
public class JwtTokenService : IJwtTokenService
{
private readonly IOptions<JwtTokenSettings> jwtTokenSettings;
public JwtTokenService(IOptions<JwtTokenSettings> jwtTokenSettings)
{
this.jwtTokenSettings = jwtTokenSettings;
}
public string GenerateToken(Guid userId, string userEmail)
{
string secretKey = jwtTokenSettings.Value.Key;
string issuer = jwtTokenSettings.Value.Issuer;
string audience = jwtTokenSettings.Value.Audience;
var expiryHours = jwtTokenSettings.Value.ExpiryHours;
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()),
new Claim(JwtRegisteredClaimNames.Email, userEmail),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
issuer: issuer,
audience: audience,
claims: claims,
expires: DateTime.UtcNow.AddHours(expiryHours),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
最后,Microsoft JwtService、JwtTokenService 和 JwtTokenSettings 安装在 Program.cs 中,如下所示:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<JwtTokenSettings>(
configuration.GetSection("JwtTokenSettings")
);
var jwtSettings = builder.Configuration.GetSection("JwtTokenSettings");
var key = Encoding.UTF8.GetBytes(jwtSettings["Key"]);
builder.Services.AddSingleton<IJwtTokenService, JwtTokenService>();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings["Issuer"],
ValidAudience = jwtSettings["Audience"],
IssuerSigningKey = new SymmetricSecurityKey(key)
};
});
如果我从控制器中删除 [Authorize] 装饰器,用户可以成功访问 API 端点。此外,可以使用控制器的 Get 方法(端点)内的以下代码正确识别用户。
var services = this.HttpContext.RequestServices;
var httpContextAccessor = (IHttpContextAccessor)services.GetService(typeof(IHttpContextAccessor));
var userId = httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
因此,即使 JWTService“知道”用户是谁,它也不会对其进行身份验证。
我希望所有相关的内容都在这里。有人能够帮助发现问题吗?我真的很感谢您的帮助!
解决方案可以在
找到JWT 持有者令牌授权无法工作 asp net core web api
在 Program.cs 中我有
// This is the correct order
app.UseAuthentication();
app.UseAuthorization();
顺序错误。