如何在Duende的Client Credential Flow中自定义Token的Claim
基于Duende IdentityServer扩展Client Credential Flow的JWT声明
是的,基于ITokenResponseGenerator扩展是Client Credential Flow下自定义客户端JWT声明的正确方案——这个接口负责生成令牌响应,完全覆盖客户端凭证模式的令牌生成流程,能满足你添加、移除自定义声明的需求。
实现步骤
1. 自定义TokenResponseGenerator实现类
继承Duende提供的默认TokenResponseGenerator,重写GenerateAsync方法,在该方法中修改JWT声明:
using Duende.IdentityServer.Models; using Duende.IdentityServer.Services; using Duende.IdentityServer.Validation; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.IdentityModel.Tokens.Jwt; public class CustomClientTokenGenerator : TokenResponseGenerator { public CustomClientTokenGenerator(ISystemClock clock, ITokenService tokenService, IResourceStore resourceStore, IClientStore clientStore) : base(clock, tokenService, resourceStore, clientStore) { } public override async Task<TokenResponse> GenerateAsync(TokenRequestValidationResult validationResult) { // 获取原始令牌响应 var originalResponse = await base.GenerateAsync(validationResult); // 从请求中提取自定义GUID:支持form参数或请求头两种方式 var customGuid = validationResult.ValidatedRequest.Raw.Get("custom_guid") ?? validationResult.ValidatedRequest.HttpContext.Request.Headers["X-Custom-Guid"].FirstOrDefault(); if (!string.IsNullOrWhiteSpace(customGuid)) { // 解析原始JWT的声明集合 var jwtHandler = new JwtSecurityTokenHandler(); var originalJwt = jwtHandler.ReadJwtToken(originalResponse.AccessToken); var updatedClaims = new List<Claim>(originalJwt.Claims); // 1. 添加基于GUID的自定义声明 updatedClaims.Add(new Claim("custom_identifier", customGuid)); // 2. 移除指定的现有声明(示例为移除"example_claim_to_remove"类型的声明) updatedClaims.RemoveAll(claim => claim.Type == "example_claim_to_remove"); // 重新生成包含修改后声明的JWT令牌 var newAccessToken = await TokenService.CreateAccessTokenAsync(new TokenCreationRequest { Subject = new ClaimsPrincipal(new ClaimsIdentity(updatedClaims)), ValidatedRequest = validationResult.ValidatedRequest, Resources = validationResult.ValidatedResources }); // 更新响应中的AccessToken originalResponse.AccessToken = newAccessToken; } return originalResponse; } }
2. 替换DI容器中的默认实现
在IdentityServer的服务配置中,将默认的ITokenResponseGenerator替换为自定义实现:
// 在Program.cs或Startup.cs的服务注册阶段 builder.Services.AddTransient<ITokenResponseGenerator, CustomClientTokenGenerator>();
补充说明
- GUID传递方式:客户端请求令牌时,可通过POST表单参数(
custom_guid)或自定义请求头(X-Custom-Guid)传入GUID,根据业务场景选择即可。 - 声明修改限制:避免移除JWT的核心必要声明(如
iss、exp、client_id),否则会导致令牌验证失败。 - 可选优化:如果需要先验证GUID的合法性,可额外实现
ICustomTokenRequestValidator,在令牌请求验证阶段完成GUID校验,再在生成器中直接使用校验后的GUID。
内容的提问来源于stack exchange,提问作者Konrad Viltersten
相关产品推荐
相关产品推荐

