Spring WebClient OAuth2设置ClientRegistrationId可运行示例求教
问题原因分析
- 报错
serverWebExchange cannot be null:默认的ServerOAuth2AuthorizedClientExchangeFilterFunction依赖响应式web请求上下文获取ServerWebExchange,仅适用于请求链路触发的WebClient调用,后台主动调用、定时任务等无请求上下文的场景会触发空指针。 - 报错
clientRegistrationId()方法未定义:该方法是ServerOAuth2AuthorizedClientExchangeFilterFunction提供的静态工具方法,需要手动静态导入后才能使用,也可以直接通过属性键赋值,不需要额外导入。
可行实现方案
步骤1:改造WebClient Bean配置,适配无请求上下文场景
自定义ReactiveOAuth2AuthorizedClientManager,替换默认依赖ServerWebExchange的实现,从根源解决空指针问题:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder; import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; import org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository; import org.springframework.web.reactive.function.client.WebClient; @Configuration public class WebClientConfig { @Bean public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( ReactiveClientRegistrationRepository clientRegistrationRepository, ServerOAuth2AuthorizedClientRepository authorizedClientRepository) { ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder() .clientCredentials() .build(); DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientRepository); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; } @Bean public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) { ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); // 不需要设置默认id,调用时动态传入即可 return WebClient.builder() .filter(oauthFilter) .build(); } }
步骤2:调用时动态传入ClientRegistrationId
两种写法均可实现动态传值:
写法1:直接通过属性键赋值(无需额外导入静态方法)
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; // 调用时直接传入你要使用的registrationId,对应application.properties中配置的id String targetRegId = "MyClRegId"; ResponseSpec responseSpec = this.webClient .get() .uri("/NumberOrders") .attributes(attr -> attr.put(ServerOAuth2AuthorizedClientExchangeFilterFunction.CLIENT_REGISTRATION_ID_ATTR_NAME, targetRegId)) .retrieve();
写法2:使用静态工具方法(需要先导入静态方法)
先导入静态引用:
import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId;
调用时代码如下:
ResponseSpec responseSpec = this.webClient .get() .uri("/NumberOrders") .attributes(clientRegistrationId("MyClRegId")) .retrieve();
多ClientRegistration配置说明
你可以在application.properties中配置多套客户端配置,调用时传入对应的registrationId即可自动切换,比如:
# 第一套配置 spring.security.oauth2.client.registration.MyClRegId.authorization-grant-type=client_credentials spring.security.oauth2.client.registration.MyClRegId.client-id=myteam spring.security.oauth2.client.registration.MyClRegId.client-secret=12349875 spring.security.oauth2.client.provider.MyClRegId.token-uri=https://something/token spring.security.oauth2.client.registration.MyClRegId.scope=OIDC # 第二套配置 spring.security.oauth2.client.registration.AnotherRegId.authorization-grant-type=client_credentials spring.security.oauth2.client.registration.AnotherRegId.client-id=otherteam spring.security.oauth2.client.registration.AnotherRegId.client-secret=abcdefg spring.security.oauth2.client.provider.AnotherRegId.token-uri=https://other/token spring.security.oauth2.client.registration.AnotherRegId.scope=OIDC
调用时传入MyClRegId或者AnotherRegId就可以自动使用对应的配置请求token。
内容的提问来源于stack exchange,提问作者TimeBandit
相关产品推荐
相关产品推荐

