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

IdentityServer4自定义令牌验证仅触发一次问题求助

解决密码修改后令牌失效及自定义验证不触发的问题

核心问题澄清

  • ICustomTokenRequestValidator 仅在**客户端向IdentityServer请求令牌(如调用token端点)**时生效,API后续请求验证令牌的阶段不会触发这个接口——这是你断点不触发的根本原因。
  • JWKS请求是API端用来获取公钥验证令牌签名的,默认会被缓存,后续重复请求不会触发刷新,但这和令牌是否失效没有直接关系,强制刷新JWKS无法解决令牌失效的需求。

可行解决方案

方案一:使用IdentityServer令牌撤销机制(推荐有Refresh Token的场景)

在密码修改完成后,主动调用IdentityServer的令牌撤销端点,将用户当前的Access Token和Refresh Token标记为无效:

  1. 在你的change-password服务中注入TokenRevocationService
  2. 执行撤销逻辑:
public async Task ChangePasswordAsync(string userId, string newPassword)
{
    // 处理密码修改逻辑...
    
    // 撤销用户的所有有效令牌(或指定令牌)
    var revocationResult = await _tokenRevocationService.RevokeTokenAsync(new TokenRevocationRequest
    {
        Token = userCurrentAccessToken, // 可从请求上下文或用户存储中获取
        TokenTypeHint = "access_token",
        SubjectId = userId
    });
    
    if (!revocationResult.IsError)
    {
        // 撤销成功
    }
}

方案二:实现令牌黑名单+API端实时验证(适合无Refresh Token或需立即失效的场景)

因为JWT本身是无状态的,需要通过黑名单机制主动校验令牌有效性:

  1. 密码修改时记录黑名单:将用户当前有效令牌的唯一标识(如jti声明,或sub+exp组合)存入缓存(如Redis),过期时间与令牌自身过期时间一致。
  2. API端添加自定义验证逻辑:在JwtBearer的验证事件中检查令牌是否在黑名单中:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 配置JWKS缓存(可选,按需设置过期时间)
        var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            "https://your-idsrv/.well-known/openid-configuration",
            new OpenIdConnectConfigurationRetriever(),
            new HttpDocumentRetriever());
        configManager.DefaultCacheDuration = TimeSpan.FromMinutes(5); // 缩短缓存时间
        options.ConfigurationManager = configManager;

        // 添加令牌黑名单校验
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = async context =>
            {
                var blacklistService = context.HttpContext.RequestServices.GetRequiredService<ITokenBlacklistService>();
                var jti = context.Principal.FindFirstValue(JwtRegisteredClaimNames.Jti);
                
                if (await blacklistService.IsTokenBlacklisted(jti))
                {
                    context.Fail("Token has been revoked due to password change");
                }
            }
        };
    });

方案三:调整自定义验证逻辑的作用阶段

如果你的TokenHashValidatorService是用来在令牌生成时绑定用户状态(比如密码哈希),可以:

  1. 在密码修改后,更新用户的关联哈希值
  2. 下次用户请求新令牌时,ICustomTokenRequestValidator会触发校验,拒绝基于旧密码生成的令牌请求
  3. 但旧令牌仍会有效,所以需要结合上述两种方案彻底失效旧令牌

关键提示

  • 不要试图通过强制刷新JWKS解决令牌失效问题,JWKS仅用于签名验证,和令牌的业务有效性无关。
  • 公开的change-password端点处理完成后,必须主动触发令牌失效逻辑,而非依赖“标记验证”——API请求的令牌验证是默认执行的,只是需要补充黑名单/撤销的校验步骤。

内容的提问来源于stack exchange,提问作者Danylo Parkhomenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:35:24