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

在OpenIddict中配置多种令牌格式及端点的技术咨询

在OpenIddict中配置多种令牌格式及端点的技术咨询

嘿,针对你在OpenIddict 6.2.1里想要动态生成JWT(自包含)或引用令牌(不透明)的需求,我给你梳理两个实用方案,你可以根据业务场景选择~

方案一:基于客户端ID动态切换令牌格式

这个方案适合不同客户端有固定令牌格式偏好的场景,不需要新增端点,只需要在客户端配置和令牌生成环节做处理:

  1. 标记客户端的令牌格式偏好
    在创建客户端的时候,给客户端添加自定义属性来指定它需要的令牌类型,比如用Properties字段存储:
await manager.CreateAsync(new OpenIddictApplicationDescriptor
{
    ClientId = "client-reference",
    ClientSecret = "your-secret-here",
    RedirectUris = { new Uri("https://your-client-app.com/callback") },
    Permissions =
    {
        OpenIddictConstants.Permissions.Endpoints.Authorization,
        OpenIddictConstants.Permissions.Endpoints.Token,
        OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode
    },
    // 标记该客户端需要引用令牌
    Properties = { ["TokenFormat"] = "Reference" }
});
  1. 拦截令牌生成事件,动态选择令牌类型
    在OpenIddict的服务器配置中,添加事件拦截器,在令牌生成前根据客户端的属性决定生成JWT还是引用令牌:
builder.Services.AddOpenIddict()
    .AddCore(options =>
    {
        options.UseEntityFrameworkCore()
               .UseDbContext<ApplicationDbContext>();
    })
    .AddServer(options =>
    {
        // 保留现有端点配置
        options.SetAuthorizationEndpointUris("/connect/authorize")
               .SetTokenEndpointUris("/connect/token");

        // 启用授权码流
        options.AllowAuthorizationCodeFlow();

        // 同时开启JWT和引用令牌的支持
        options.UseJsonWebTokens()
               .UseReferenceTokens();

        // 拦截登录处理事件,动态设置令牌类型
        options.AddEventHandler<ProcessSignInContext>(builder =>
        {
            builder.UseInlineHandler(context =>
            {
                if (context.Application is null) return default;

                // 读取客户端的令牌格式偏好
                if (context.Application.Properties.TryGetValue("TokenFormat", out var tokenFormat) &&
                    string.Equals(tokenFormat, "Reference", StringComparison.OrdinalIgnoreCase))
                {
                    // 指定生成引用令牌
                    context.TokenType = OpenIddictConstants.TokenTypes.Reference;
                }
                else
                {
                    // 默认生成JWT令牌
                    context.TokenType = OpenIddictConstants.TokenTypes.JsonWebToken;
                }

                return default;
            });
        });

        // 配置JWT签名凭证(根据你的实际情况替换)
        options.AddSigningCertificate("your-signing-certificate");
    });

方案二:新增端点区分令牌类型

如果需要让同一客户端也能按需生成不同类型的令牌,或者想通过不同端点明确区分,可以新增专门的令牌端点:

  1. 添加新的令牌端点
    在OpenIddict服务器配置中,新增一个端点(比如/connect/token-reference):
options.SetTokenEndpointUris("/connect/token", "/connect/token-reference");
  1. 根据请求端点动态选择令牌类型
    同样通过事件拦截器,根据当前请求的端点路径来决定生成哪种令牌:
options.AddEventHandler<ProcessSignInContext>(builder =>
{
    builder.UseInlineHandler(context =>
    {
        var requestPath = context.Request.Path.Value;
        // 判断请求的是新增的引用令牌端点
        if (string.Equals(requestPath, "/connect/token-reference", StringComparison.OrdinalIgnoreCase))
        {
            context.TokenType = OpenIddictConstants.TokenTypes.Reference;
        }
        else
        {
            // 默认用原端点生成JWT
            context.TokenType = OpenIddictConstants.TokenTypes.JsonWebToken;
        }

        return default;
    });
});

额外小技巧:通过请求参数动态切换

如果不想新增端点,也可以在原/connect/token请求中添加自定义参数(比如token_format),然后在事件中读取参数来决定令牌类型:

// 先拦截令牌请求事件,读取参数并存储
options.AddEventHandler<ProcessTokenRequestContext>(builder =>
{
    builder.UseInlineHandler(context =>
    {
        if (context.Request.TryGetParameter("token_format", out var format) &&
            string.Equals(format.ToString(), "reference", StringComparison.OrdinalIgnoreCase))
        {
            context.SetProperty("TokenFormat", "Reference");
        }
        return default;
    });
});

// 再在登录处理事件中读取属性设置令牌类型
options.AddEventHandler<ProcessSignInContext>(builder =>
{
    builder.UseInlineHandler(context =>
    {
        if (context.TryGetProperty("TokenFormat", out var format) &&
            string.Equals(format.ToString(), "Reference", StringComparison.OrdinalIgnoreCase))
        {
            context.TokenType = OpenIddictConstants.TokenTypes.Reference;
        }
        else
        {
            context.TokenType = OpenIddictConstants.TokenTypes.JsonWebToken;
        }

        return default;
    });
});

注意事项

  • 引用令牌需要依赖持久化存储(比如Entity Framework Core),因为令牌本身是不透明的,授权服务器需要查询数据库验证令牌有效性。
  • JWT令牌必须配置正确的签名凭证,确保客户端能正常验证令牌的合法性。
  • 不管用哪种方案,都要确保客户端拥有对应的端点权限(比如Endpoints.Token)。

备注:内容来源于stack exchange,提问作者Fylix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:24:50