You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenIddict交换授权码获取Token时遭遇401未授权问题

问题排查与修复方案

1. 未启用Windows身份认证

你的服务配置中缺少Windows身份认证的注册逻辑,导致RequireAuthorization()无法触发正确的Windows身份验证流程。需要添加以下配置:

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
    .AddNegotiate();

同时在应用管道中确保认证、授权中间件的顺序正确:

app.UseAuthentication();
app.UseAuthorization();

2. Token端点未处理OpenIddict请求验证

你启用了EnableTokenEndpointPassthrough(),但自定义的/token端点没有先让OpenIddict完成请求合法性校验(比如客户端凭证、授权码有效性验证),导致请求被OpenIddict中间件直接拦截返回401。正确的处理逻辑需要先完成OpenIddict的请求校验,再生成令牌:

app.MapPost("/token", async (HttpContext context) =>
{
    // 获取OpenIddict的请求对象
    var request = await context.GetOpenIddictServerRequestAsync();
    if (request is null)
    {
        return Results.BadRequest("无效的请求");
    }

    // 查找并验证客户端
    var applicationManager = context.RequestServices.GetRequiredService<IOpenIddictApplicationManager>();
    var application = await applicationManager.FindByClientIdAsync(request.ClientId);
    if (application is null || !await applicationManager.ValidateClientSecretAsync(application, request.ClientSecret))
    {
        return Results.Unauthorized();
    }

    // 验证授权码有效性
    var authorizationManager = context.RequestServices.GetRequiredService<IOpenIddictAuthorizationManager>();
    var authorization = await authorizationManager.FindByTokenAsync(request.Code, OpenIddictConstants.TokenTypes.AuthorizationCode);
    if (authorization is null || !await authorizationManager.ValidateTokenAsync(authorization, request.Code))
    {
        return Results.Unauthorized();
    }

    // 生成身份标识与令牌凭证
    var identity = new ClaimsIdentity(TokenValidationParameters.DefaultAuthenticationType);
    identity.AddClaim(OpenIddictConstants.Claims.Subject, await authorizationManager.GetSubjectAsync(authorization));
    identity.SetDestinations(_ => new[] { OpenIddictConstants.Destinations.AccessToken });

    var ticket = new AuthenticationTicket(
        new ClaimsPrincipal(identity),
        new AuthenticationProperties(),
        OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
    
    ticket.SetScopes(request.GetScopes());
    ticket.SetResources(await context.RequestServices.GetRequiredService<IOpenIddictScopeManager>().ListResourcesAsync(request.GetScopes()));

    return Results.SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
});

3. 应用注册配置不完整

你的应用注册未指定客户端类型,且包含了授权码流程不需要的权限:

await manager.CreateAsync(new OpenIddictApplicationDescriptor
{
    ClientId = "console_app",
    ClientType = ClientTypes.Public, // 明确客户端类型(Postman属于公共客户端)
    RedirectUris =
    {
        new Uri("https://oauth.pstmn.io/v1/callback")
    },
    Permissions =
    {
        Permissions.Endpoints.Authorization,
        Permissions.Endpoints.Token,
        Permissions.GrantTypes.AuthorizationCode,
        Permissions.ResponseTypes.Code
        // 移除Permissions.ResponseTypes.Token,授权码流程无需该权限
    }
});

4. 管道中间件顺序错误

确保认证、授权中间件在端点映射之前执行:

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

// 之后再映射端点
app.MapGet("/authorize", ...);
app.MapPost("/token", ...);

app.Run();

内容的提问来源于stack exchange,提问作者Zulander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:22:49