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

如何在受保护API中获取IdentityServer的grant_type?

如何在IdentityServer保护的API中区分client_credentials与authorization_code授权请求

下面提供几种实用方案,帮你在API内判断当前请求的授权类型:

方案一:强制添加gty授权类型声明

IdentityServer默认不会在令牌中包含gty(grant type)声明,但可以通过自定义IProfileService来主动添加。实现这个接口后,在令牌生成阶段注入授权类型信息:

public class CustomProfileService : IProfileService
{
    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        // 从请求上下文获取授权类型
        var grantType = context.Request.GrantType;
        if (!string.IsNullOrWhiteSpace(grantType))
        {
            context.IssuedClaims.Add(new Claim("gty", grantType));
        }

        // 保留原有逻辑,添加其他必要的用户/客户端声明
        // ...
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;
    }
}

然后在IdentityServer的Startup类中注册这个自定义服务:

services.AddIdentityServer()
        // 其他配置(如AddInMemoryClients、AddInMemoryApiScopes等)
        .AddProfileService<CustomProfileService>();

之后生成的令牌就会携带gty声明,API端直接读取该声明的值即可判断是client_credentials还是authorization_code。

方案二:通过sub用户标识声明判断

这是最简便的方案,无需修改IdentityServer配置:

  • client_credentials是机器对机器授权,令牌中不会包含用户标识sub声明
  • authorization_code是用户授权流程,令牌中必然携带sub声明(对应用户的唯一标识)

在API中直接检查sub是否存在即可区分:

var userId = User.FindFirstValue("sub");
bool isMachineClient = string.IsNullOrEmpty(userId);

方案三:给不同客户端添加自定义声明

可以在IdentityServer的客户端配置中,为不同类型的客户端添加专属声明,以此作为区分标记:

  1. 配置M2M客户端(client_credentials):
new Client
{
    ClientId = "m2m-service-client",
    AllowedGrantTypes = GrantTypes.ClientCredentials,
    // 其他配置(如ClientSecrets、AllowedScopes等)
    Claims = new List<ClientClaim>
    {
        new ClientClaim("client_type", "machine")
    },
    AlwaysSendClientClaims = true // 确保客户端声明被包含在令牌中
}
  1. 配置用户端客户端(authorization_code):
new Client
{
    ClientId = "user-facing-client",
    AllowedGrantTypes = GrantTypes.Code,
    // 其他配置(如RedirectUris、AllowedScopes等)
    Claims = new List<ClientClaim>
    {
        new ClientClaim("client_type", "user")
    },
    AlwaysSendClientClaims = true
}

API端读取client_type声明的值,就能判断请求来自机器客户端还是用户客户端。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:47:17