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

如何在IdentityServer4中实现自定义grant type解决跨身份源API访问问题

实现方案

1. 核心思路说明

你提到的两个操作都是需要做的:实现IExtensionGrantValidator扩展授权验证,以及在保护API的IdentityServer(下称目标IdSvr)中信任原有登录用的IdentityServer(下称源IdSvr)的签名。
这个方案的本质是让目标IdSvr认可源IdSvr签发的用户身份凭证,给应用换发能访问当前域API的令牌,避免用户二次登录。

2. 具体实现步骤

2.1 源IdSvr侧配置

  • 确保源IdSvr给应用签发的id_token或者access_token包含足够的用户身份声明(比如sub、name、email等你需要传递的字段)
  • 导出源IdSvr的签名公钥(一般是JWKS格式的公钥,注意不要泄露私钥)

2.2 目标IdSvr侧实现

第一步:注册源IdSvr的签名密钥

把源IdSvr的签名公钥添加到目标IdSvr的信任签名密钥列表中,用于验证源IdSvr签发的令牌合法性,避免伪造的凭证被用于兑换令牌。
你可以直接在目标IdSvr启动时配置:

builder.Services.AddIdentityServer()
    // 原有其他配置
    .AddValidationKey(sourceIdSvrPublicKey); // 这里传入你导出的源IdSvr公钥

第二步:实现IExtensionGrantValidator自定义授权验证

自定义扩展授权类型,比如命名为source_idsvr_token,验证逻辑如下:

  • 接收应用传过来的源IdSvr签发的有效令牌
  • 验证令牌的签名、有效期、签发者、受众等核心参数是否合法
  • 从合法令牌中提取用户声明,构造目标IdSvr的用户身份
  • 返回验证通过结果,生成目标IdSvr签发的access_token给应用
    示例代码框架:
public class SourceIdSvrGrantValidator : IExtensionGrantValidator
{
    public string GrantType => "source_idsvr_token";

    private readonly ITokenValidator _tokenValidator;

    public SourceIdSvrGrantValidator(ITokenValidator tokenValidator)
    {
        _tokenValidator = tokenValidator;
    }

    public async Task ValidateAsync(ExtensionGrantValidationContext context)
    {
        var sourceToken = context.Request.Raw.Get("source_token");
        if (string.IsNullOrEmpty(sourceToken))
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "missing source token");
            return;
        }

        // 验证源IdSvr签发的令牌
        var validationResult = await _tokenValidator.ValidateAccessTokenAsync(sourceToken);
        if (validationResult.IsError)
        {
            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid source token");
            return;
        }

        // 提取用户声明,构造目标域的用户身份
        var claims = validationResult.Claims.ToList();
        // 可以在这里按需添加、转换声明,适配目标IdSvr的业务要求

        context.Result = new GrantValidationResult(
            subject: validationResult.Subject.FindFirst("sub").Value,
            authenticationMethod: "source_idsvr",
            claims: claims);
    }
}

然后在目标IdSvr中注册这个验证器:

builder.Services.AddIdentityServer()
    // 原有其他配置
    .AddExtensionGrantValidator<SourceIdSvrGrantValidator>();

另外还要在目标IdSvr的客户端配置中,给对应的应用开放这个自定义授权类型的使用权限。

2.3 应用侧适配

应用拿到源IdSvr的登录令牌后,向目标IdSvr发起令牌请求,使用自定义的source_idsvr_token授权类型,传入源令牌,兑换目标IdSvr的access_token,之后就可以用这个新令牌访问受保护的API。

3. 可选优化方案

如果两个身份服务器都是你可控的,也可以考虑用联邦身份认证的方式,把源IdSvr配置为目标IdSvr的外部身份提供商,用户跳转一次完成登录即可,不需要自定义扩展授权。不过这种方式适合用户还没在源IdSvr登录的场景,你当前已经有应用持有源IdSvr的有效令牌,用扩展授权的方式体验更好,不需要跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:39:02