之前是好的,是在最近升级后遇到的,目前不确定是 asp.net core 的 authentication 机制更新还是依赖的某个 nuget 包引起的,使用的 asp.net core 版本是 9.0
升级之前可以正常工作时的 authentication 配置
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = webApiOptions.Authority;
options.ApiName = webApiOptions.ApiName;
options.RequireHttpsMetadata = webApiOptions.RequireHttpsMetadata;
options.ForwardDefaultSelector = Selector.ForwardReferenceToken(_introspectionScheme);
});
AddIdentityServerAuthentication
来自 IdentityServer4.AccessTokenValidation
升级后通过 access token 请求对应的 web api
const req = await fetch(url, {
headers: {
authorization: `Bearer ${token}`,
'content-type': 'application/json'
},
})
响应状态码是 401
终于定位到是 Microsoft.AspNetCore.Authentication.JwtBearer
的版本引起的,7.0
没问题,8.0
(对应.NET 8)与 9.0
(对应 .NET 9)都有这个问题
401 错误是应用中下面的代码抛异常引起的
public static Guid GetUserId(this ClaimsPrincipal user) =>
Guid.TryParse(user.FindFirstValue(JwtClaimTypes.Subject), out var userId) && userId != default
? userId
: throw new AuthorizationException();
将 JwtClaimTypes.Subject
改为 ClaimTypes.NameIdentifier
就解决了
后来去掉了 AddIdentityServerAuthentication,改为直接使用 JWT Bearer Authentication
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = webApiOptions.Authority;
options.Audience = webApiOptions.ApiName;
options.RequireHttpsMetadata = webApiOptions.RequireHttpsMetadata;
options.EventsType = typeof(CnblogsJwtBearerEvents);
options.ForwardDefaultSelector = Selector.ForwardReferenceToken(_introspectionScheme);
});