gpt4 book ai didi

java - Spring Security 5 在 Application Runner 中调用 OAuth2 Secured API 导致 IllegalArgumentException

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:35:20 25 4
gpt4 key购买 nike

给定以下代码,是否可以在应用程序运行器中调用受客户端凭据保护的 API?

@Bean
public ApplicationRunner test(
WebClient.Builder builder,
ClientRegistrationRepository clientRegistrationRepo,
OAuth2AuthorizedClientRepository authorizedClient) {
return args -> {
try {
var oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrationRepo,
authorizedClient);
oauth2.setDefaultClientRegistrationId("test");
var response = builder
.apply(oauth2.oauth2Configuration())
.build()
.get()
.uri("test")
.retrieve()
.bodyToMono(String.class)
.block();
log.info("Response - {}", response);
} catch (Exception e) {
log.error("Failed to call test.", e);
}
};
}

代码失败是因为,

java.lang.IllegalArgumentException: request cannot be null

全栈,

java.lang.IllegalArgumentException: request cannot be null
at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizedClientRepository.loadAuthorizedClient(HttpSessionOAuth2AuthorizedClientRepository.java:47) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.populateDefaultOAuth2AuthorizedClient(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:364) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.lambda$null$2(ServletOAuth2AuthorizedClientExchangeFilterFunction.java:209) ~[spring-security-oauth2-client-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:234) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at org.springframework.web.reactive.function.client.DefaultWebClient$DefaultRequestBodyUriSpec.attributes(DefaultWebClient.java:153) ~[spring-webflux-5.1.5.RELEASE.jar:5.1.5.RELEASE]

失败的方法看起来像,

public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(
String clientRegistrationId, Authentication principal, HttpServletRequest request){

Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
Assert.notNull(request, "request cannot be null");
return (OAuth2AuthorizedClient)this
.getAuthorizedClients(request)
.get(clientRegistrationId);
}

这是有道理的,因为没有 HttpServletRequest 供它使用,它在应用程序启动时被调用。

除了制作我自己的空操作 OAuth2AuthorizedClientRepository 之外,还有其他解决方法吗?

//编辑,

这不是一个完全响应式(Reactive)的堆栈。它是一个 Spring Web 堆栈,其中包含 WebClient。

我很清楚 ServerOAuth2AuthorizedClientExchangeFilterFunction 适用于完全响应式堆栈并需要 ReactiveClientRegistrationRepositoryReactiveOauth2AuthorizedClient 由于此原因不可用处于构建在 Servlet 堆栈之上的应用程序中,而不是 react 性的。

最佳答案

由于我也偶然发现了这个问题,所以我将详细说明 Darren Forsythe's更新的答案,让其他人更容易找到:

OP 提交的问题导致 OAuth2AuthorizedClientManager 的实现能够

operating outside of a HttpServletRequest context, e.g. in a scheduled/background thread and/or in the service-tier

( from the official docs )

所述实现,AuthorizedClientServiceOAuth2AuthorizedClientManager,被传递给 ServletOAuth2AuthorizedClientExchangeFilterFunction 以替换默认的。

在我的示例中,它看起来像这样:

@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService clientService)
{

OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();

AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clientRegistrationRepository, clientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

return authorizedClientManager;
}

@Bean
WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager)
{
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth2.setDefaultClientRegistrationId("keycloak");
return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
}

关于java - Spring Security 5 在 Application Runner 中调用 OAuth2 Secured API 导致 IllegalArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55308918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com