Spring Security OAuth2客户端如何在请求头中设置JWT Token
存在开箱即用的原生组件,完全不需要手动编写请求头注入逻辑,Spring Security OAuth2 Client模块已经封装了令牌获取、过期刷新、请求头注入的全流程能力,针对不同的HTTP客户端提供了对应的实现类:
WebClient(含Servlet/响应式栈)
核心实现类是ServletOAuth2AuthorizedClientExchangeFilterFunction(适用于Servlet技术栈)、ServerOAuth2AuthorizedClientExchangeFilterFunction(适用于WebFlux响应式栈),属于WebClient的扩展过滤器,配置后会自动在请求发出前获取有效JWT,拼接为Authorization: Bearer <token>格式注入请求头。
最小配置示例:
@Bean WebClient oauth2WebClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Filter = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); // 开启后默认绑定当前请求上下文中的已认证客户端令牌 oauth2Filter.setDefaultOAuth2AuthorizedClient(true); return WebClient.builder() .apply(oauth2Filter.oauth2Configuration()) .build(); }
配置完成后直接注入该WebClient发起请求即可,无需手动处理令牌:
// 发起请求时自动携带合法JWT请求头 String resp = oauth2WebClient.get() .uri("你的资源服务器接口路径") .retrieve() .bodyToMono(String.class) .block();
如果需要指定固定的OAuth2客户端,而非使用当前上下文绑定的客户端,只需要在请求时通过属性指定registrationId即可,不需要手动获取令牌:
String resp = oauth2WebClient.get() .uri("你的资源服务器接口路径") .attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("你配置的客户端registrationId")) .retrieve() .bodyToMono(String.class) .block();
RestTemplate(传统Servlet栈)
核心实现类是OAuth2AuthorizedClientInterceptor,属于RestTemplate的请求拦截器,逻辑和上述WebClient的过滤器完全一致。
最小配置示例:
@Bean RestTemplate oauth2RestTemplate(OAuth2AuthorizedClientManager authorizedClientManager) { RestTemplate restTemplate = new RestTemplate(); restTemplate.setInterceptors(List.of( new OAuth2AuthorizedClientInterceptor(authorizedClientManager) )); return restTemplate; }
上述组件已经内置处理了所有边界逻辑:包括令牌不存在时自动触发授权流程申请令牌、令牌临近过期时自动刷新、多客户端场景下的令牌隔离、Bearer前缀自动拼接,不需要额外编写冗余逻辑。前提是你已经在配置文件/配置类中正确填写了OAuth2客户端的注册信息(clientId、clientSecret、授权类型、令牌端点地址等)。
内容的提问来源于stack exchange,提问作者zilcuanu

