如何在受保护API中获取IdentityServer的grant_type?
下面提供几种实用方案,帮你在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的客户端配置中,为不同类型的客户端添加专属声明,以此作为区分标记:
- 配置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 // 确保客户端声明被包含在令牌中 }
- 配置用户端客户端(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
相关产品推荐
相关产品推荐

