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

IdentityServer4负载均衡故障排查:是否因未持久化刷新令牌?

排查IdentityServer4多实例负载均衡失效与OperationalStore无数据问题

首先,你遇到的负载均衡失效问题确实和未持久化授权数据直接相关——全内存存储时,授权码、刷新令牌等数据只存在单个实例的内存中,多实例请求分发到不同节点时,后续请求(比如刷新令牌)找不到对应数据就会失败。接下来针对你的代码和问题逐一排查:

1. 自定义IPersistedGrantStore与官方AddOperationalStore冲突

你的代码中同时做了两件冲突的事:

  • 调用identityServerBuilder.AddOperationalStore(...):这会自动注册官方基于数据库的IPersistedGrantStore实现(类名恰好也是PersistedGrantStore)
  • 手动注册services.AddTransient<IPersistedGrantStore, PersistedGrantStore>():这会直接覆盖官方的数据库实现

如果你的自定义PersistedGrantStore没有正确使用PersistedGrantDbContext读写数据库,自然不会有数据存入DB。解决方法:

  • 删除手动注册IPersistedGrantStore的代码,让AddOperationalStore提供的默认实现生效
  • 若确实需要自定义持久化逻辑,确保你的PersistedGrantStore正确注入PersistedGrantDbContext并实现完整的CRUD方法

2. 验证AddOperationalStore配置与数据库迁移

确认以下细节:

  • 检查dbSettings.ConnectionString是否正确指向PostgreSQL,数据库用户具备读写权限
  • 查看应用启动日志,确认PersistedGrantDbContext.Database.Migrate()是否成功执行,有没有抛出连接失败、迁移脚本缺失等异常
  • 确认migrationsAssembly是否正确获取到包含迁移文件的程序集(你的代码中this.GetType().Assembly.GetName().Name是正确的,只要迁移文件在当前项目中)

3. 确认客户端配置允许离线访问

只有当客户端配置中AllowOfflineAccess = true,且请求令牌时携带offline_access scope,IdentityServer才会生成刷新令牌并持久化到数据库。检查你的JsonFileClientStore中的客户端配置,确保需要刷新令牌的客户端开启了这个配置。

4. 验证负载均衡环境的PublicOrigin配置

你的代码中设置了iso.PublicOrigin = applicationSettings.PublicOriginUri,这在负载均衡场景下至关重要——务必确保这个地址是负载均衡器的公网入口地址,否则IdentityServer生成的令牌中的回调地址、issuer会和实际请求不匹配,导致验证失败。

修复后的关键代码示例

移除自定义的IPersistedGrantStore注册后,ConfigureServices中相关部分应如下:

var identityServerBuilder = services
    .AddIdentityServer(iso => {
        if (!String.IsNullOrEmpty(applicationSettings.PublicOriginUri)) 
            iso.PublicOrigin = applicationSettings.PublicOriginUri;
        // 其他IdentityServer配置...
    });

// 签名凭证配置(开发/生产环境逻辑)...

// 启用数据库存储操作数据(授权码、令牌、同意信息)
identityServerBuilder.AddOperationalStore(options => {
    options.ConfigureDbContext = builder => 
        builder.UseNpgsql(dbSettings.ConnectionString, 
            sql => sql.MigrationsAssembly(migrationsAssembly));
    options.EnableTokenCleanup = true;
    options.TokenCleanupInterval = 10; // 测试用短间隔,生产建议调长
});

// 移除这行冲突代码:services.AddTransient<IPersistedGrantStore, PersistedGrantStore>();

// 其他服务注册...

测试验证步骤

  1. 启动单个实例,发起授权请求并获取刷新令牌
  2. 查看PostgreSQL的persisted_grants表,确认是否有数据存入
  3. 启动第二个实例,用同一个刷新令牌请求新的访问令牌
  4. 若能成功获取令牌,说明多实例间的数据共享正常,负载均衡问题解决

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:09:22