Spring Security OAuth2非servlet环境下获取自动刷新access token的方法
核心能力说明
Spring生态已经内置了你需要的access token自动获取、过期自动刷新能力,不需要自行实现token有效期校验、刷新逻辑,对应能力由ReactiveOAuth2AuthorizedClientManager及其配套组件提供,你当前配置的WebClient过滤器已经依赖了这套能力。
最优实现方案(无需手动获取token)
你配置的ServerOAuth2AuthorizedClientExchangeFilterFunction过滤器会自动在请求发起前获取有效access token、自动添加Authorization: Bearer {token}请求头,token过期时也会自动刷新后再发起请求,不需要你手动处理token相关逻辑,直接按以下方式调用即可:
webClient .method(HttpMethod.POST) .uri("<目标URI>") // 移除手动加Authorization头的代码,过滤器会自动处理 .bodyValue(你的JSON请求参数) .exchangeToMono(response -> response.bodyToMono(String.class));
注意:把你配置WebClient时注释掉的
oauth.setDefaultOAuth2AuthorizedClient(true);取消注释,非servlet无UI的客户端调用场景下该配置可以确保过滤器自动使用默认的客户端注册信息获取token。
手动获取有效access token的方案
如果确实有特殊场景需要手动读取WebClient管理的有效token,按以下步骤配置即可:
- 首先注册
ReactiveOAuth2AuthorizedClientManagerBean,该组件会自动处理token的获取、刷新逻辑:
@Bean public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( ReactiveClientRegistrationRepository clientRegistrationRepository, ReactiveOAuth2AuthorizedClientService authorizedClientService) { // 配置支持的授权模式和刷新能力 ReactiveOAuth2AuthorizedClientProvider provider = ReactiveOAuth2AuthorizedClientProviderBuilder .builder() .clientCredentials() // 按你实际使用的授权模式开启,客户端凭证模式用这个 .refreshToken() // 开启自动刷新能力 .build(); DefaultReactiveOAuth2AuthorizedClientManager manager = new DefaultReactiveOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientService); manager.setAuthorizedClientProvider(provider); return manager; }
- 在需要使用token的地方注入该Bean,调用即可获取实时有效的access token:
// 注入ReactiveOAuth2AuthorizedClientManager authorizedClientManager public Mono<String> getValidToken() { OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest .withClientRegistrationId("id-name") .principal("anonymous") // 无用户上下文的客户端场景直接填anonymous即可 .build(); return authorizedClientManager.authorize(request) .map(OAuth2AuthorizedClient::getAccessToken) .map(OAuth2AccessToken::getTokenValue); }
拿到token后再按你之前的方式手动设置到请求头即可,不会再出现过期导致的401问题。
常见401问题排查
- 确认你的
ClientRegistration中配置的authorizationGrantType和实际授权服务要求的一致,客户端凭证模式请使用AuthorizationGrantType.CLIENT_CREDENTIALS - 手动加header时请确认key为
Authorization,值为Bearer {token},注意Bearer和token之间有空格 - 确认客户端id、密钥、scope配置和授权服务要求的一致
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

