IdentityServer自定义kiosk扩展授权的令牌刷新方案咨询
IdentityServer Kiosk扩展授权的令牌刷新最佳实践
当前采用的「先刷新原始用户访问令牌,再换取新Kiosk模式令牌」流程存在冗余,本质是没有利用IdentityServer原生对扩展授权类型的刷新令牌支持,以下是可直接落地的最优方案,按推荐优先级排序:
方案1:为Kiosk授权类型原生签发刷新令牌(首选)
扩展授权类型默认和IdentityServer原生授权类型享有完全一致的刷新令牌能力,不需要为扩展授权单独实现刷新逻辑,仅需要补充自定义声明的注入规则即可。
这是最符合OAuth2.0规范、链路最短的实现方式,不需要客户端维护双令牌,也不需要多次请求,仅需3步配置:
- 客户端配置开启支持
给使用Kiosk模式的客户端配置中,把kiosk加入AllowedGrantTypes列表,同时开启AllowOfflineAccess = true允许签发刷新令牌。针对公共自助终端场景,建议把Kiosk模式刷新令牌的绝对有效期设置为不超过8小时,避免设备遗失导致的权限滥用。注意:公共自助终端场景不要配置滑动刷新令牌有效期,避免令牌被恶意无限续期。 - 自定义刷新令牌的声明注入逻辑
IdentityServer默认刷新令牌流程不会自动携带你在扩展授权校验器中添加的自定义声明,需要实现ICustomTokenRequestValidator拦截Kiosk来源的刷新请求,补充专属声明:
注册该实现到DI容器:public class KioskRefreshTokenClaimProvider : ICustomTokenRequestValidator { public Task ValidateAsync(CustomTokenRequestValidationContext context) { var request = context.Result.ValidatedRequest; // 仅拦截Kiosk授权对应的刷新令牌请求 if (request.GrantType == OidcConstants.GrantTypes.RefreshToken && request.RefreshToken?.GrantType == "kiosk") { // 注入Kiosk模式专属声明,可在此处追加权限二次校验逻辑 request.ClientClaims.Add(new Claim(ClaimTypes.Name, "kiosk")); } return Task.CompletedTask; } }builder.Services.AddTransient<ICustomTokenRequestValidator, KioskRefreshTokenClaimProvider>(); - 客户端调整刷新逻辑
首次通过kiosk授权类型换取令牌时,会同时拿到access_token和refresh_token,令牌过期时直接用标准的refresh_token授权类型请求新令牌即可,不需要再携带原始用户访问令牌。
方案2:存量令牌兼容过渡方案
如果已有大量已签发的Kiosk令牌未携带刷新令牌,无法快速切到方案1,可以临时调整现有KioskGrantValidator的校验逻辑:
- 额外注入
IRefreshTokenService依赖 - 当传入的用户token通过
ValidateAccessTokenAsync校验失败时,尝试将其作为刷新令牌解析,校验通过后同样可以签发新的Kiosk令牌 - 该方案仅作为临时过渡,长期使用会增加校验逻辑的分支复杂度,不建议长期保留。
现有双步刷新方案的明显缺陷
- 客户端需要同时维护原始用户令牌、Kiosk模式令牌两套生命周期逻辑,端侧代码复杂度高,容易出现令牌过期时序问题导致的鉴权失败
- 多一次HTTP往返,公共终端网络质量不稳定的场景下请求失败率会明显升高
- 若原始用户令牌来自移动端,跨设备/跨IP刷新时很容易触发IdentityServer默认的刷新令牌风控规则,导致刷新流程中断。
内容的提问来源于stack exchange,提问作者Nate
相关产品推荐
相关产品推荐

