IdentityServer4 同一客户端下如何为不同用户自定义RefreshToken生命周期
你之前使用ICustomTokenRequestValidator无法实现自定义RefreshToken的原因是:该扩展点处于令牌请求的验证阶段,当你首次调用/connect/token获取令牌(密码模式、授权码模式等)时,RefreshToken还未生成,因此request.RefreshToken自然为空;只有当你使用RefreshToken发起刷新请求时,这个属性才会有值,这个扩展点本身的设计目的也不是用于生成自定义RefreshToken。
正确的实现方式如下:
实现方案
针对同client下多用户差异化RefreshToken的需求,需要替换IdentityServer默认的IRefreshTokenService扩展点实现,具体步骤如下:
步骤1:实现自定义RefreshToken服务
继承默认的DefaultRefreshTokenService,重写创建RefreshToken的方法,在方法内根据当前用户信息做差异化配置:
using IdentityServer4.Models; using IdentityServer4.Services; using IdentityModel; using System.Security.Claims; public class CustomRefreshTokenService : DefaultRefreshTokenService { public CustomRefreshTokenService( IRefreshTokenStore refreshTokenStore, IProfileService profile, ISystemClock clock, ILogger<DefaultRefreshTokenService> logger) : base(refreshTokenStore, profile, clock, logger) { } public override async Task<RefreshToken> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client) { // 调用基类生成默认RefreshToken var refreshToken = await base.CreateRefreshTokenAsync(subject, accessToken, client); // 读取当前用户标识做差异化配置 var userId = subject.FindFirstValue(JwtClaimTypes.Subject); // 示例:不同用户设置不同的RefreshToken有效期 refreshToken.Lifetime = userId switch { // 普通用户有效期7天 "001" => 3600 * 24 * 7, // 高级用户有效期30天 "002" => 3600 * 24 * 30, _ => refreshToken.Lifetime }; // 也可以往RefreshToken中添加用户专属的自定义数据 refreshToken.Description = $"用户{userId}专属RefreshToken"; return refreshToken; } // 若需要自定义RefreshToken的字符串值本身,可额外重写该方法 // public override Task<string> CreateRefreshTokenHandleAsync(RefreshToken refreshToken) // { // // 自定义生成逻辑返回字符串即可 // return Task.FromResult(Guid.NewGuid().ToString("N")); // } }
步骤2:替换默认服务
在IdentityServer的服务注册配置中,替换默认的RefreshToken服务即可生效:
builder.Services.AddIdentityServer() .AddInMemoryClients(Config.Clients) .AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryApiScopes(Config.ApiScopes) .AddTestUsers(Config.TestUsers) // 注册自定义RefreshToken服务 .AddRefreshTokenService<CustomRefreshTokenService>();
补充说明
如果你需要在用户发起RefreshToken刷新请求时调整已有RefreshToken的属性,可以结合ICustomTokenRequestValidator使用,此时刷新请求的context.Result.ValidatedRequest.RefreshToken会返回当前待刷新的令牌实例,可直接修改属性。
内容的提问来源于stack exchange,提问作者Tan Vu
相关产品推荐
相关产品推荐

