Spring Boot 3.2.1 OAuth2客户端令牌请求添加自定义Header
解决方案
1. 自定义令牌请求客户端
定义自定义的ClientCredentialsTokenResponseClient(适用于客户端凭证模式),在令牌请求中注入自定义Header:
import org.springframework.security.oauth2.client.endpoint.DefaultClientCredentialsTokenResponseClient; import org.springframework.security.oauth2.client.endpoint.OAuth2ClientCredentialsGrantRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.web.reactive.function.client.WebClient; public class CustomTokenResponseClient extends DefaultClientCredentialsTokenResponseClient { private final String foobarUuid; public CustomTokenResponseClient(String foobarUuid) { this.foobarUuid = foobarUuid; // 替换默认WebClient,添加自定义Header拦截器 WebClient webClient = WebClient.builder() .filter((request, next) -> next.exchange( request.mutate() .header("FOOBAR UUID", foobarUuid) .build() )) .build(); setWebClient(webClient); } @Override public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest grantRequest) { return super.getTokenResponse(grantRequest); } }
2. 注册自定义TokenResponseClient到Spring容器
在配置类中读取配置文件的UUID值,注册自定义Bean:
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.endpoint.ClientCredentialsTokenResponseClient; @Configuration public class OAuth2ClientConfig { @Value("${foobar.uuid}") private String foobarUuid; @Bean public ClientCredentialsTokenResponseClient customTokenResponseClient() { return new CustomTokenResponseClient(foobarUuid); } }
3. 配置WebClient关联自定义OAuth2客户端
让WebClient使用自定义的令牌请求客户端,确保获取令牌时携带指定Header:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class WebClientConfig { @Bean public WebClient foobarWebClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Filter = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); oauth2Filter.setDefaultClientRegistrationId("foobar"); // 对应配置文件中的客户端ID return WebClient.builder() .apply(oauth2Filter.oauth2Configuration()) .build(); } @Bean public OAuth2AuthorizedClientManager authorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository, ClientCredentialsTokenResponseClient customTokenResponseClient) { OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .clientCredentials(c -> c.tokenResponseClient(customTokenResponseClient)) .build(); DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; } }
4. application.yml配置示例
确保客户端及自定义UUID配置正确:
spring: security: oauth2: client: registration: foobar: client-id: your-client-id client-secret: your-client-secret authorization-grant-type: client_credentials scope: read,write provider: foobar: token-uri: https://foobar-api.com/oauth/token # 令牌请求地址 foobar: uuid: xxxxx # 你的自定义UUID值
如果使用授权码模式等其他OAuth2流程,只需替换对应的TokenResponseClient(比如AuthorizationCodeTokenResponseClient),用同样的方式添加Header拦截器即可。
内容的提问来源于stack exchange,提问作者Conner
相关产品推荐
相关产品推荐

