如何通过Spring WebClient实现OAuth Token自动缓存与过期刷新?
问题解答:Spring WebClient缓存OAuth2 Token并自动刷新
当然可以通过Spring原生机制实现OAuth2 Token的缓存与过期自动刷新,你的当前配置存在冗余逻辑,导致每次请求都重新获取Token,以下是修正方案和原理说明:
问题根源
你在DelegatingOAuth2AuthorizedClientProvider中添加了RefreshTokenOAuth2AuthorizedClientProvider,但Client Credentials模式下授权服务器不会返回refresh token,这个Provider完全多余,反而会干扰默认的Token复用逻辑。此外,你注释掉了用OAuth2AuthorizedClientProviderBuilder构建的标准Client Credentials Provider,改用手动组合的Provider,也可能导致逻辑异常。
修正后的配置
1. 正确配置OAuth2AuthorizedClientManager
@Bean public OAuth2AuthorizedClientManager clientManager( @Qualifier("proxyCpClientRegistrationRepository") ClientRegistrationRepository proxyCpClientRegistrationRepository, OAuth2AuthorizedClientService clientService) { // 仅构建Client Credentials模式的授权客户端Provider OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .clientCredentials() .build(); AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager( proxyCpClientRegistrationRepository, clientService); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; }
2. 简化WebClient配置
@Bean public WebClient client(OAuth2AuthorizedClientManager proxyCpAuthorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(proxyCpAuthorizedClientManager); oauth.setDefaultClientRegistrationId(CP_CLIENT); return WebClient.builder() .filter(oauth) .baseUrl(getUrl()) .defaultHeader(HttpHeaders.USER_AGENT, "service") .build(); }
原生缓存与自动刷新逻辑说明
- Token缓存:
AuthorizedClientServiceOAuth2AuthorizedClientManager依赖OAuth2AuthorizedClientService存储已授权的客户端信息(包含Token、过期时间等)。默认使用InMemoryOAuth2AuthorizedClientService,会在内存中缓存Token,单实例应用直接可用;多实例分布式场景可替换为RedisOAuth2AuthorizedClientService(需引入Spring Data Redis和Spring Security OAuth2 Client依赖)。 - 自动刷新:
ClientCredentialsOAuth2AuthorizedClientProvider会自动检查Token的过期时间,当Token已过期或即将过期时,会自动向授权服务器发起新的Token请求,并更新缓存中的Token,无需手动干预。
内容的提问来源于stack exchange,提问作者kantesh
相关产品推荐
相关产品推荐

