首页 新闻 会员 周边 捐助

.NET Minimal API 遇到 PAT(Personal Access Token) 身份认证失败的问题

0
悬赏园豆:20 [已解决问题] 解决于 2025-11-16 23:40

在一个 ASP.NET Core 10 项目中,基于 Controller 实现的 API 可以正常通过 PAT 进行身份认证,但基于 Minimal API 实现的 API 却认证失败

Minimal API endpoint 添加了 RequireAuthorization

public static void MapPostsOpenApis(this IEndpointRouteBuilder app)
{
    var api = app.NewVersionedApi()
        .MapGroup("/openapi/v{version:apiVersion}/posts")
        .HasApiVersion(1)
        .RequireAuthorization();
    api.MapCreatePost();
}

带 PAT 的 HttpClient 请求代码如下

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Add("authorization-type", "pat");
var response = await httpClient.PostAsJsonAsync(
    "/openapi/v1/posts",
    new { Title = "Test" , Body = "Test"});
Console.WriteLine($"Status code: {(int)response.StatusCode}({response.StatusCode})");

返回的状态码是 401(Unauthorized)

dudu的主页 dudu | 高人七级 | 园豆:24466
提问于:2025-11-16 20:11
< >
分享
最佳答案
0

是项目中的 PolicySchemeOptions 配置代码造成 PAT 认证时使用的 authentication scheme 不对引起的

services.Configure<PolicySchemeOptions>(
    CnblogsAuthenticationDefaults.AuthenticationScheme,
    op =>
    {
        op.ForwardDefaultSelector = ctx =>
        {
            var authType = ctx.Request.Headers.GetOrDefault("Authorization-Type", string.Empty);
            if (ctx.Request.Headers.TryGetValue(HeaderNames.Authorization, out var bearerHeader)
                && ctx.Request.Path.StartsWithSegments("/api"))
            {
                if (bearerHeader.FirstOrDefault()?.StartsWith("Bearer ") ?? false)
                {
                    return string.Equals("pat", authType, StringComparison.OrdinalIgnoreCase)
                        ? OAuth2IntrospectionDefaults.AuthenticationScheme
                        : "jwt";
                }
            }

            return CookieAuthenticationDefaults.AuthenticationScheme;
        };
    });

ctx.Request.Path.StartsWithSegments("/api")

改为

ctx.Request.Path.StartsWithSegments("/api") || ctx.Request.Path.StartsWithSegments("/openapi"))

解决了

dudu | 高人七级 |园豆:24466 | 2025-11-16 23:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册