首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpringSecurity5在应用程序运行程序中调用OAuth2安全API会导致IllegalArgumentException

SpringSecurity5在应用程序运行程序中调用OAuth2安全API会导致IllegalArgumentException
EN

Stack Overflow用户
提问于 2019-03-22 23:10:48
回答 1查看 9.9K关注 0票数 18

给定以下代码,是否可以在应用程序运行程序中调用客户端凭据安全API?

代码语言:javascript
复制
@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);
            }
        };
    }

代码失败是因为

代码语言:javascript
复制
java.lang.IllegalArgumentException: request cannot be null

一叠一叠

代码语言:javascript
复制
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]

如果失败的方法看起来像,

代码语言:javascript
复制
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可供使用,它在启动应用程序时被调用。

除了做我自己的非op OAuth2AuthorizedClientRepository之外,还有其他的解决办法吗?

//编辑,

这不是一个完全反应的堆栈。它是一个Spring堆栈,其中使用的是WebClient。

我非常了解ServerOAuth2AuthorizedClientExchangeFilterFunction,它适用于完全反应的堆栈,并且需要ReactiveClientRegistrationRepositoryReactiveOauth2AuthorizedClient,因为这是在Servlet堆栈之上构建的应用程序中,而不是在反应性的应用程序中。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-12 18:32:31

由于我也偶然发现了这个问题,我将详细介绍一下达伦·福塞斯更新的答案,以便让其他人更容易找到:

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

在HttpServletRequest上下文之外操作,例如在调度/后台线程和/或服务层中操作。

(从官方文件上)

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

在我的示例中,如下所示:

代码语言:javascript
复制
@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();
}
票数 33
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55308918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档