今日、.NETプロジェクトでポリシーベースの役割認証を使用している際に、401の問題に遭遇しました。以下のようなシナリオです:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var authConfig = new AuthConfig();
builder.Configuration.Bind("AuthConfig", authConfig);
builder.Services.AddSingleton(authConfig);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, opt =>
{
opt.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(authConfig.SecurityKey)),
ValidateIssuer = true,
ValidIssuer = authConfig.Issuer,
ValidateAudience = true,
ValidAudience = authConfig.Audience,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
ValidAlgorithms = new[] { SecurityAlgorithms.HmacSha512 }
};
});
builder.Services.AddAuthorization(opt =>
{
opt.AddPolicy("rolevalidate", policy => policy.RequireRole("user"));
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapPost("/login", ([FromServices] AuthConfig config, [FromBody] UserModel userModel) =>
{
if (userModel.UserName != "gsw" || userModel.Password != "111111")
{
return new { result = false, message = "ユーザー名またはパスワードが間違っています!", token = "" };
}
else
{
var token = new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(
issuer: config.Issuer,
audience: config.Audience,
claims: new[] {
new Claim(ClaimTypes.Role, "user")
},
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddSeconds(config.Expires),
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.SecurityKey)), SecurityAlgorithms.HmacSha512)
));
return new { result = true, message = "", token = token };
}
}).AllowAnonymous();
app.MapGet("/index", () =>
{
return "ログイン成功!";
}).RequireAuthorization("rolevalidate");
app.Run();
public class AuthConfig
{
public string Issuer { get; set; }
public string Audience { get; set; }
public int Expires { get; set; }
public string SecurityKey { get; set; }
}
public class UserModel
{
public string UserName { get; set; }
public string Password { get; set; }
}
appsettings.json
の内容は以下の通りです:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information"
}
},
"AllowedHosts": "*",
"AuthConfig": {
"Issuer": "https://www.demo.com",
"Audience": "https://www.demo.com",
"Expires": 86400,
"SecurityKey": "1234567890abcdefg1234567890abcdefg1234567890abcdefg1234567890abcdefg"
}
}
導入したNuGetパッケージは以下の通りです(Microsoft.IdentityModel.Tokens
パッケージは古い転送パッケージだと感じ、アップグレードしました)。
テストを開始し、まずログインしてトークンが正常に返されました:
その後、/indexにアクセスすると、401エラーが発生しました。
最初はAddAuthenticationとAddAuthorizationの方法が間違っていると思い、再試行しましたが成功しませんでした。他の原因ではないかとログを確認し、失敗の理由を見つけて分析を進めることにしました。Microsoft.AspNetCore.Authentication.JwtBearer
のログを有効にし、appsettings.json
のLogLevelに以下を追加しました:
"Microsoft.AspNetCore.Authentication.JwtBearer": "Information"
再び/indexをリクエストすると、エラーログが表示されました:
最終的に、Microsoft.IdentityModel.Tokens
の問題が考えられたため、インストールしたバージョンを削除し、転送可能なバージョン8.0.1にダウングレードしました。
再度テストし、正常に通過しました!
(Translated by GPT)
元のリンク:https://mp.weixin.qq.com/s/vkYuFtcvqVMObLKwjGJQ6w?token=1700701408&lang=zh_CN&wt.mc_id=MVP_325642