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

如何在ASP.NET Core中复现AAD B2C SecurityTokens的缓存刷新机制?

在ASP.NET Core中复现OpenIdConnectCachingSecurityTokenProvider的缓存刷新行为

当然可以!在ASP.NET Core里,虽然没有直接对应旧ASP.NET中OpenIdConnectCachingSecurityTokenProvider的现成组件,但我们可以通过自定义令牌验证逻辑结合缓存服务,轻松实现“缓存SecurityToken 1分钟后再刷新”的需求。下面是具体的实现方案:

核心思路

我们的目标是对验证过的令牌结果进行缓存,在1分钟内重复使用缓存结果,超过时间后重新执行令牌验证(相当于刷新缓存)。主要通过以下两步实现:

  • 配置缓存服务(内存缓存或分布式缓存)
  • 自定义JWT令牌处理器,在验证逻辑中加入缓存判断

具体实现步骤

1. 添加缓存服务

首先在Program.cs中注册缓存服务,这里先以内存缓存为例:

builder.Services.AddMemoryCache();

如果你的API是多实例部署,建议改用分布式缓存(比如Redis),只需要替换成对应的缓存注册代码即可,逻辑核心是一致的。

2. 自定义带缓存的令牌处理器

创建一个继承自JwtSecurityTokenHandler的自定义处理器,注入IMemoryCache来实现缓存逻辑:

public class CachingJwtSecurityTokenHandler : JwtSecurityTokenHandler
{
    private readonly IMemoryCache _cache;
    // 设置缓存有效期为1分钟
    private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(1);

    public CachingJwtSecurityTokenHandler(IMemoryCache cache)
    {
        _cache = cache ?? throw new ArgumentNullException(nameof(cache));
    }

    public override ClaimsPrincipal ValidateToken(string token, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
        // 用令牌哈希值作为缓存键,确保唯一性同时避免长字符串占用空间
        var cacheKey = $"ValidatedToken_{token.GetHashCode()}";

        // 先尝试从缓存获取已验证的结果
        if (_cache.TryGetValue(cacheKey, out (ClaimsPrincipal Principal, SecurityToken Token) cachedResult))
        {
            // 刷新缓存过期时间(滑动过期,活跃令牌不会过早失效)
            _cache.Set(cacheKey, cachedResult, _cacheExpiration);
            validatedToken = cachedResult.Token;
            return cachedResult.Principal;
        }

        // 缓存未命中,执行原生令牌验证
        var principal = base.ValidateToken(token, validationParameters, out validatedToken);
        
        // 将验证结果存入缓存
        _cache.Set(cacheKey, (principal, validatedToken), _cacheExpiration);
        
        return principal;
    }
}

这里我们把ClaimsPrincipal和SecurityToken一起缓存,同时使用滑动过期策略——每次命中缓存时都会重新设置1分钟的过期时间,确保活跃的令牌不会过早过期。

3. 注册自定义处理器到认证服务

在Program.cs的认证配置中,替换默认的令牌验证器为我们自定义的缓存版本:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 配置你的OpenID Connect参数,比如身份提供者地址、受众等
        options.Authority = "https://your-identity-provider.com";
        options.Audience = "your-api-resource-audience";
        
        // 清除默认的验证器,添加自定义的缓存处理器
        options.SecurityTokenValidators.Clear();
        options.SecurityTokenValidators.Add(new CachingJwtSecurityTokenHandler(
            builder.Services.BuildServiceProvider().GetRequiredService<IMemoryCache>()));
    });

额外说明

  • 如果需要绝对过期(不管是否访问,1分钟后强制刷新),可以在设置缓存时使用MemoryCacheEntryOptions指定AbsoluteExpirationRelativeToNow,替代滑动过期逻辑。
  • 缓存键的生成方式可以根据实际需求调整,比如结合令牌的exp字段,避免缓存已过期的令牌。
  • 对于分布式场景,只需将内存缓存替换为Redis等分布式缓存服务,代码逻辑不需要大的改动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:53:31