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

如何在Spring Security中缓存OAuth2令牌introspection请求?

解决Spring Boot OAuth2资源服务器Opaque Token Introspection缓存问题

针对第三方认证服务器不稳定导致的频繁401错误,你可以通过自定义带缓存逻辑的Token校验器来减少introspection请求次数,具体实现步骤如下:


1. 实现带缓存的OpaqueTokenIntrospector

通过委托模式包装默认的Nimbus校验器,结合@Cacheable注解缓存校验成功的token结果:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionException;

public class CachingOpaqueTokenIntrospector implements OpaqueTokenIntrospector {

    private final OpaqueTokenIntrospector delegate;

    public CachingOpaqueTokenIntrospector(String introspectionUri, String clientId, String clientSecret) {
        this.delegate = new NimbusOpaqueTokenIntrospector(introspectionUri, clientId, clientSecret);
    }

    @Override
    @Cacheable(value = "oauth2Introspection", key = "#token", condition = "#result != null && #result.isAuthenticated()")
    public OAuth2AuthenticatedPrincipal introspect(String token) {
        try {
            return this.delegate.introspect(token);
        } catch (OAuth2IntrospectionException e) {
            // 认证服务器异常时不缓存,直接抛出异常
            throw e;
        }
    }
}

说明:

  • condition确保只缓存认证成功的token结果,避免缓存无效token
  • 捕获OAuth2IntrospectionException,防止第三方服务异常时错误结果被缓存

2. 在安全配置中替换默认校验器

将自定义的缓存校验器注册为Bean,并替换原有的opaqueToken配置:

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;

@EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {

    private final String introspectionUri;
    private final String clientId;
    private final String clientSecret;

    // 通过构造注入配置参数
    public ResourceServerConfig(String introspectionUri, String clientId, String clientSecret) {
        this.introspectionUri = introspectionUri;
        this.clientId = clientId;
        this.clientSecret = clientSecret;
    }

    @Bean
    public OpaqueTokenIntrospector cachingOpaqueTokenIntrospector() {
        return new CachingOpaqueTokenIntrospector(introspectionUri, clientId, clientSecret);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .oauth2ResourceServer(oauth2 -> oauth2
                .opaqueToken(token -> token.introspector(cachingOpaqueTokenIntrospector()))
            );
    }
}

3. 配置缓存管理器

确保Spring Cache已正确配置,推荐使用Caffeine作为缓存实现(轻量且性能优异):

添加Maven依赖

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

配置缓存过期时间(application.yml)

spring:
  cache:
    type: caffeine
    caffeine:
      spec: expireAfterWrite=10m  # 过期时间建议短于token有效期,避免缓存过期token

关键注意事项

  • 缓存时间需匹配token的实际有效期,避免缓存过期token导致的授权问题
  • 仅缓存认证成功的结果,失败请求直接转发到第三方服务器,保证错误状态实时性
  • 若使用Redis等分布式缓存,需确保OAuth2AuthenticatedPrincipal可序列化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 12:25:17