【发布时间】:2022-08-22 22:38:00
【问题描述】:
我是菜鸟,想做智威汤逊这最简单的.NET Core 6 Web API 项目的可能方式,但我什至无法让它工作。
要求:需要登录才能调用GetProductList API。
(我正在项目附带的 Swagger 上对此进行测试)
仅供参考,我的登录控制器:(按预期工作)
[HttpPost(\"login\")]
public async Task<ActionResult> Login(LoginDto request)
{
var user = GetUserFromRequest(request);
if (user == null)
return BadRequest(\"Invalid credentials.\");
string jwt = CreateJwtToken(user.Id.ToString());
Response.Cookies.Append(COOKIE_JWT, jwt, _cookieOptions);
return Ok();
}
[HttpGet(\"user\")]
public IActionResult GetUser()
{
try
{
var jwt = Request.Cookies[COOKIE_JWT];
var userId = VerifyJwtAndGetUserId(jwt);
return Ok(GetUserById(userId));
}
catch(Exception ex)
{
return Unauthorized();
}
}
public static string CreateJwtToken(string userId)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY));
var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);
var token = new JwtSecurityToken(
issuer: userId,
expires: DateTime.Now.AddDays(365),
signingCredentials: cred
);
var jwt = new JwtSecurityTokenHandler().WriteToken(token);
return jwt;
}
public static string VerifyJwtAndGetUserId(string jwt)
{
var tokenHandler = new JwtSecurityTokenHandler();
tokenHandler.ValidateToken(jwt, new TokenValidationParameters {
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY)),
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = false
}, out SecurityToken validatedToken);
string userId = validatedToken.Issuer;
return userId;
}
问题是,如何使[Authorize] 属性起作用?
[HttpGet(\"list\")]
//[Authorize]
public async Task<ActionResult<List<Product>>> GetProductList()
{
return Ok(GetProducts());
}
以上工作,但添加[Authorize] 属性给出了401带有以下标题:(虽然上面的 GetUser 很好)
content-length: 0
date: Mon,13 Jun 2022 23:27:32 GMT
server: Kestrel
www-authenticate: Bearer
这就是我的程序.cs:(也许这是错误的?)
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters { // similar to the one in controller
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY)),
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = false
};
options.Events = new JwtBearerEvents { // https://spin.atomicobject.com/2020/07/25/net-core-jwt-cookie-authentication/
OnMessageReceived = ctx => {
ctx.Token = ctx.Request.Cookies[\"jwt\"];
return Task.CompletedTask;
}
};
});
解决方案:
将app.UseAuthentication(); 移动到app.UserAuthorization(); 上方。
-
您的端点需要一个不记名令牌,您的请求需要添加一个授权不记名 HTTP 标头
-
issuer: userId<-- 这是非常不正确的。您将sub(主题)声明与issuer声明混淆了。 -
谢谢毛毛虫和戴。有什么方法可以快速解决这个问题,让它正常工作吗?我是 JWT 的菜鸟,示例代码真的很有帮助
-
@JeremyLakeman 谢谢!这似乎是我需要的,但它仍然不起作用(Swagger 中的相同 401 错误)
标签: c# asp.net-core jwt asp.net-core-webapi authorize-attribute