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

Identity Server 分布式缓存无法正常工作问题求助

核心问题原因

1. 组件作用匹配错误

AddOidcStateDataFormatterCache是给作为OIDC客户端的应用设计的,用于缓存OIDC授权请求过程中的state、nonce、code_verifier等临时数据。你当前的服务是IDS4身份提供方(IDP)本身,注册的AddIdentityServerAuthentication仅用于保护当前服务的API接口,并不会作为客户端发起OIDC授权流程,因此这个扩展无论是否指定Scheme,都不会在你的登录流程中被触发。

2. Cookie存储逻辑认知偏差

ASP.NET Core Identity默认签发的登录Cookie是自包含的加密票证,所有用户身份信息加密后直接存储在客户端Cookie中,服务端默认不会将票证副本写入分布式缓存。你看到有数据写入的dbo.PersistedGrants表仅存储IDS4的授权码、刷新令牌、参考令牌等授权相关数据,和登录Cookie无关。

3. 分布式缓存本身配置正常

你手动注入IDistributedCache写入数据成功,说明数据库分布式缓存的基础配置完全正确,问题是没有相关组件在登录流程中主动调用缓存写入接口。


解决方案

根据你的实际需求选择对应配置即可:

场景1:需要将登录Cookie票证存储到分布式缓存(实现服务端主动失效Cookie的能力)

给Identity的ApplicationCookie显式配置基于分布式缓存的ITicketStore实现,示例代码如下:

// 先实现分布式缓存票证存储类
public class DistributedCacheTicketStore : ITicketStore
{
    private readonly IDistributedCache _cache;
    private readonly ITicketDataFormat _format;
    private const string KeyPrefix = "AuthTicket_";

    public DistributedCacheTicketStore(IDistributedCache cache, ITicketDataFormat format)
    {
        _cache = cache;
        _format = format;
    }

    public async Task<string> StoreAsync(AuthenticationTicket ticket)
    {
        var key = KeyPrefix + Guid.NewGuid().ToString("N");
        var ticketData = _format.Protect(ticket);
        await _cache.SetStringAsync(key, ticketData, new DistributedCacheEntryOptions
        {
            AbsoluteExpiration = ticket.Properties.ExpiresUtc
        });
        return key;
    }

    public async Task<AuthenticationTicket> RetrieveAsync(string key)
    {
        var ticketData = await _cache.GetStringAsync(key);
        return ticketData == null ? null : _format.Unprotect(ticketData);
    }

    public async Task RenewAsync(string key, AuthenticationTicket ticket)
    {
        var ticketData = _format.Protect(ticket);
        await _cache.SetStringAsync(key, ticketData, new DistributedCacheEntryOptions
        {
            AbsoluteExpiration = ticket.Properties.ExpiresUtc
        });
    }

    public async Task RemoveAsync(string key)
    {
        await _cache.RemoveAsync(key);
    }
}

// 然后在ConfigureApplicationCookie中注册
services.ConfigureApplicationCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromSeconds(55);
    options.SlidingExpiration = false;
    // 新增配置,使用分布式缓存存票证
    options.SessionStore = new DistributedCacheTicketStore(
        services.BuildServiceProvider().GetRequiredService<IDistributedCache>(),
        new TicketDataFormat(
            services.BuildServiceProvider().GetRequiredService<IDataProtectionProvider>()
                .CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", 
                    IdentityConstants.ApplicationScheme, "v2"))
    );
});

配置后客户端Cookie仅存储票证ID,完整票证内容会自动写入你配置的分布式缓存表。

场景2:需要将IDS4内部临时数据存储到分布式缓存

IDS4默认使用内存缓存存储授权请求上下文、登出上下文等临时数据,你只需要在IDS4注册配置中添加AddDistributedCacheTokenStorage扩展即可:

services.AddIdentityServer(Ids4Options())
    .AddAspNetIdentity<AppUser>()
    .AddOperationalStore(OperationOptions())
    .AddConfigurationStore(ConfigOptions())
    .AddProfileService<ProfileService>()
    .AddDeveloperSigningCredential()
    // 新增这行,配置IDS4用分布式缓存存临时数据
    .AddDistributedCacheTokenStorage();

配置后IDS4的相关临时数据会自动写入分布式缓存表。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:45:03