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

IdentityServer4令牌本地存储及重启后过期令牌续期问题咨询

关于IdentityServer4 In-Memory存储下令牌续期的问题解答

嘿,这个问题问到点子上了!先直接给你结论:如果用In-Memory存储搭建IdentityServer4,服务重启后,它无法识别之前颁发的令牌,也没法完成续期操作。

为什么会这样?

In-Memory存储的特点是所有数据都存在应用进程的内存里——包括客户端配置、资源定义,以及最重要的:颁发的刷新令牌记录、授权码等操作数据。一旦服务重启,这些内存里的数据会被完全清空。当旧令牌过期,你拿着之前获取的刷新令牌去请求续期时,IdentityServer根本找不到对应的刷新令牌记录,自然无法验证其有效性,更别说颁发新令牌了。

实现令牌续期的思路

要解决这个问题,核心是把IdentityServer的数据从内存迁移到持久化存储,再配合正确的配置和客户端逻辑,具体步骤如下:

1. 改用持久化存储(核心步骤)

IdentityServer4官方提供了Entity Framework Core的扩展包,支持将配置数据(客户端、身份资源、API资源)和操作数据(刷新令牌、授权码、撤销记录)存储到关系型数据库(比如SQL Server、MySQL、PostgreSQL等)。

示例代码(在Program.cs/Startup.cs中配置):

var connectionString = "你的数据库连接字符串";

services.AddIdentityServer()
    // 替换In-Memory配置为数据库存储
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = b => 
            b.UseSqlServer(connectionString, opt => opt.MigrationsAssembly(typeof(Program).Assembly.FullName));
    })
    // 配置操作数据的持久化存储(存刷新令牌等)
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = b => 
            b.UseSqlServer(connectionString, opt => opt.MigrationsAssembly(typeof(Program).Assembly.FullName));
        // 开启自动清理过期的令牌/授权码数据
        options.EnableTokenCleanup = true;
        options.TokenCleanupInterval = 3600; // 每小时清理一次
    })
    // 生产环境请使用持久化签名证书,不要用这个开发用的
    .AddDeveloperSigningCredential();

配置完成后,需要通过EF迁移初始化数据库:

# 初始化配置存储迁移
dotnet ef migrations add InitialIdentityServerConfiguration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/Configuration
# 初始化操作存储迁移
dotnet ef migrations add InitialIdentityServerOperational -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/Operational
# 应用迁移到数据库
dotnet ef database update -c ConfigurationDbContext
dotnet ef database update -c PersistedGrantDbContext

2. 配置客户端支持刷新令牌

确保你的客户端配置里开启了离线访问权限,允许使用刷新令牌:

new Client
{
    ClientId = "your-web-app-client",
    ClientSecrets = { new Secret("your-client-secret".Sha256()) },
    AllowedGrantTypes = GrantTypes.Code,
    RedirectUris = { "https://your-web-app.com/signin-oidc" },
    PostLogoutRedirectUris = { "https://your-web-app.com/signout-callback-oidc" },
    AllowedScopes = { 
        "openid", 
        "profile", 
        "your-api-scope", 
        "offline_access" // 必须添加这个scope才能获取刷新令牌
    },
    AllowOfflineAccess = true, // 开启离线访问,允许续期
    // 可选:配置刷新令牌的过期策略
    RefreshTokenExpiration = TokenExpiration.Sliding,
    SlidingRefreshTokenLifetime = 1296000, // 15天滑动过期
    AbsoluteRefreshTokenLifetime = 2592000 // 30天绝对过期,防止无限续期
}

3. 客户端侧实现续期逻辑

当你的Web应用检测到访问令牌过期时,要主动使用刷新令牌向IdentityServer的/connect/token端点请求新的访问令牌。请求参数示例:

POST /connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=你的刷新令牌&
client_id=your-web-app-client&
client_secret=your-client-secret&
scope=openid profile your-api-scope

如果使用OIDC中间件(比如ASP.NET Core的OpenID Connect中间件),它会自动处理令牌续期逻辑,你只需要确保中间件配置正确即可。

4. 生产环境额外注意事项

  • 签名证书:不要在生产环境使用AddDeveloperSigningCredential,要使用持久化的签名证书(比如从文件、Azure Key Vault或其他密钥管理服务加载)。否则服务重启后签名密钥变更,之前颁发的令牌会无法验证。
  • 令牌清理:确保OperationalStore的自动清理功能开启,定期删除过期数据,避免数据库膨胀。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:59:04