【发布时间】:2020-11-13 12:42:10
【问题描述】:
我已经为让 Spring WebClient 针对(大概)OAuth2 端点验证我的服务而苦苦挣扎了 2 天。流程很简单,我需要从某个端点获取令牌并将其设置为授权标头。我认为springboot可以透明地做到这一点。
这是配置我的网络客户端的一段代码:
private static final String SALES_FORCE = "sf";
@Bean
public WebClient salesforceClient(@Value("${salesforce.url}") String salesforceUrl,
ReactiveClientRegistrationRepository clientRegistrationRepository, ReactiveOAuth2AuthorizedClientService clientService) {
var clientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, clientService);
var oauth2Client = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientManager);
oauth2Client.setDefaultClientRegistrationId(SALES_FORCE);
return WebClient.builder()
.baseUrl(salesforceUrl)
.filter(oauth2Client)
.build();
}
这是我的透明身份验证配置:
spring.security.oauth2.client.registration.sf.client-id=<secret_id>
spring.security.oauth2.client.registration.sf.client-secret=<secret_key>
spring.security.oauth2.client.registration.sf.authorization-grant-type=refresh_token
spring.security.oauth2.client.registration.sf.user-info-authentication-method=form
spring.security.oauth2.client.provider.sf.token-uri=https://auth.exacttargetapis.com/v1/requestToken
我花了一段时间才弄清楚要使用哪些 oauth2 类,但最终应用程序启动了。我用 localhost 上的 WireMock 替换了 token-uri ,结果发现 Spring 甚至没有尝试检索令牌。然后,我将目标服务器替换为 WireMock 并返回 401,假设这会触发令牌检索或刷新,但 Spring 仍然没有获取令牌。
我已经开始考虑手动管理这个令牌检索/过期,因为 Spring 对我来说似乎太神奇了。
我做错了什么?
PS。
根据 ServerOAuth2AuthorizedClientExchangeFilterFunction 的 javadoc 建议,我还尝试了第二个构造函数,它(大概)也自动管理令牌过期。
private static final String SALES_FORCE = "sf";
@Bean
public WebClient salesforceClient(@Value("${salesforce.url}") String salesforceUrl,
ReactiveClientRegistrationRepository clientRegistrationRepository
, ServerOAuth2AuthorizedClientRepository clientRepository) {
var oauth2Client = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepository, clientRepository);
oauth2Client.setDefaultClientRegistrationId(SALES_FORCE);
return WebClient.builder()
.baseUrl(salesforceUrl)
.filter(oauth2Client)
.build();
}
但在这里我的请求立即失败
java.lang.IllegalArgumentException: serverWebExchange cannot be null
at org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager.lambda$authorize$4(DefaultReactiveOAuth2AuthorizedClientManager.java:131)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ Request to POST null [DefaultWebClient]
Stack trace:
at ....
总而言之,与手动管理安全令牌相比,我觉得 springboot WebClient 的配置和使用过于复杂。
【问题讨论】:
标签: spring-boot oauth-2.0 spring-webflux wiremock