英文:
Not authorized using jwt?
问题
I am trying to make a HelloWorld-ish identity server.
我正在尝试创建一个类似HelloWorld的身份验证服务器。
I am trying for the service to generate jwt tokens and use them to authenticate users as well as configuring policies to authorize users.
我正在尝试使服务生成JWT令牌并使用它们来验证用户,同时配置策略来授权用户。
I am already capable to generate tokens, but I keep getting an Unauthorized response when reaching for an endpoint that has the [Authorize]
attribute.
我已经能够生成令牌,但是当访问带有[Authorize]
属性的端点时,我不断收到未经授权的响应。
英文:
I am trying to make a HelloWorld-ish identity server.
I am trying for the service to generate jwt tokens and use them to authenticate users as well as configuring policies to authorize users.
I am already capable to generate tokens, but I keep getting an Unauthorized response when reaching for an endpoint that has the [Authorize]
attribute.
> DISCLAIMER:
> The following secrets and tokens below are dummy generated. You should never share (or even worst, post in an internet forum, any secrets or jwt or sensitive data). I am doing it because this app won't event reach production. (I am doing it for learning purposes).
Program.cs
...
// Authorization
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.ASCII.GetBytes("26837a75-3199-4e7d-8c31-2c3f53f42e83")),
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
ValidateIssuerSigningKey = false,
ValidateActor = false,
ValidateSignatureLast = false,
ValidateTokenReplay = false,
ValidateWithLKG = false
};
});
// HTTP request pipeline
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseAuthentication();
app.MapControllers();
app.MapHealthChecks("/healthz");
app.Run();
My token factory (I omit putting the entire controller because this already generates the bearer token):
public string CreateToken(
MetaToken metaToken)
{
var tokenDuration = GetTokenDuration(metaToken);
var expiresAt = DateTime.UtcNow.Add(tokenDuration);
var tokenDescriptor = new SecurityTokenDescriptor
{
Expires = expiresAt,
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(JwtRegisteredClaimNames.Exp, expiresAt.Ticks.ToString()),
new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToString()),
new Claim(JwtRegisteredClaimNames.Iat, metaToken.CreatedAt.Ticks.ToString()),
new Claim(JwtRegisteredClaimNames.Jti, metaToken.Id.ToString())
})
};
return CreateTokenInternal(tokenDescriptor);
}
private string CreateTokenInternal(SecurityTokenDescriptor tokenDescriptor)
{
// Setup signing credentials
var secretBytes = Encoding.ASCII.GetBytes("26837a75-3199-4e7d-8c31-2c3f53f42e83");
var key = new SymmetricSecurityKey(secretBytes);
var algorithm = SecurityAlgorithms.HmacSha256Signature;
tokenDescriptor.SigningCredentials = new SigningCredentials(key, algorithm);
// Create the token
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
答案1
得分: 0
你需要按正确顺序排列中间件,先将Authorization
中间件放在Authentication
之前,否则它找不到适当的声明。请按如下方式修改:
// 首先验证令牌并检索声明
app.UseAuthentication();
// 使用在认证步骤中检索到的声明
app.UseAuthorization();
英文:
You need to order your middlewares in the right way, so already the Authorization
middleware before Authentication
and it couldn't find appropriate claims. make it like this:
// first validate token and retrieve the claims
app.UseAuthentication();
// will use the claims that retrieved in the authentication step
app.UseAuthorization();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论