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

.Net6下OpenIddict请求为null及配置端点404问题求助

问题分析与修复方案

核心问题总结

你的代码存在3个关键问题,导致OpenIddict无法正确处理请求:

  • 未配置OpenID Connect发现端点,导致.well-known/openid-configuration返回404
  • 中间件顺序错误,且缺少OpenIddict依赖的认证中间件,使得GetOpenIddictServerRequest()始终返回null
  • 未配置加密/签名密钥,OpenIddict即使在降级模式下也需要密钥处理令牌逻辑

修复后的完整代码

using Microsoft.AspNetCore;
using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenIddict()
    .AddServer(options =>
    {
        // 启用授权码流并强制PKCE验证
        options.AllowAuthorizationCodeFlow()
               .RequireProofKeyForCodeExchange();

        // 配置核心端点URI,包含发现端点
        options.SetAuthorizationEndpointUris("/authorize")
               .SetTokenEndpointUris("/token")
               .SetConfigurationEndpointUris("/.well-known/openid-configuration");

        // 绑定AspNetCore管道,启用端点透传
        options.UseAspNetCore()
               .EnableAuthorizationEndpointPassthrough()
               .EnableTokenEndpointPassthrough();

        // 配置开发环境加密/签名密钥(生产环境需替换为正式证书)
        options.AddDevelopmentEncryptionCertificate()
               .AddDevelopmentSigningCertificate();

        // 启用降级模式,跳过数据库依赖
        options.EnableDegradedMode();
    });

// 添加认证中间件(OpenIddict核心逻辑依赖此中间件)
builder.Services.AddAuthentication();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

// 中间件顺序必须严格遵循:认证 → 路由 → 端点映射
app.UseAuthentication();
app.UseRouting();

// 授权端点处理逻辑
app.MapGet("/authorize", async (HttpContext context) =>
{
    var request = context.GetOpenIddictServerRequest();
    if (request is not null && request.IsAuthorizationCodeFlow())
    {
        await context.Response.WriteAsync("Call to /authorize received");
        return;
    }

    context.Response.StatusCode = StatusCodes.Status400BadRequest;
    await context.Response.WriteAsync("Invalid request");
});

// 令牌端点极简实现(仅用于测试验证)
app.MapPost("/token", async (HttpContext context) =>
{
    var request = context.GetOpenIddictServerRequest();
    if (request is not null && request.IsAuthorizationCodeFlow())
    {
        var response = await context.GenerateOpenIddictServerResponseAsync(options =>
        {
            options.Issuer = new Uri("https://localhost:5001");
            options.AccessToken = "mock-access-token";
            options.IdToken = "mock-id-token";
            options.TokenType = OpenIddictConstants.TokenTypes.Bearer;
            options.ExpiresIn = TimeSpan.FromMinutes(30);

            return Task.CompletedTask;
        });

        return Results.Ok(response);
    }

    context.Response.StatusCode = StatusCodes.Status400BadRequest;
    await context.Response.WriteAsync("Invalid token request");
});

app.Run();

关键修复点说明

  1. 启用发现端点:通过SetConfigurationEndpointUris配置标准的OpenID元数据端点,解决404问题
  2. 修正中间件顺序:将UseAuthentication()和UseRouting()前置,确保OpenIddict能正确解析请求上下文
  3. 添加密钥配置:开发环境使用内置的测试密钥,保证令牌处理逻辑能正常运行
  4. 调整端点映射位置:将MapGet("/authorize")移到UseRouting()之后,确保OpenIddict中间件先处理请求,request变量能获取到有效实例
  5. 补充令牌端点:添加极简的令牌返回逻辑,完整覆盖授权码流程的核心环节

验证方式

  1. 启动服务后,访问https://localhost:5001/.well-known/openid-configuration,可查看完整的OpenID元数据
  2. 发送符合授权码流规范的请求到/authorize(需携带client_id、response_type=code、redirect_uri、code_challenge等参数),此时request变量不再为null
  3. 发送POST请求到/token(需携带grant_type=authorization_code、code、redirect_uri、code_verifier等参数),可获取模拟令牌

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:16:02