web-dev-qa-db-fra.com

Sécurité de printemps 5 Appelant OAuth2 API sécurisé dans l'application Runner Résultats dans IllegalargumentException

Compte tenu du code suivant, est-il possible d'appeler une API sécurisée d'informations d'identification client dans un coureur d'application?

@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);
            }
        };
    }

Le code échoue à cause de,

Java.lang.IllegalArgumentException: request cannot be null

Un paquet entier,

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]

Avec la méthode d'échec ressemblant à,

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);
}

Ce qui a du sens, car il n'y a pas HttpServletRequest pour qu'il soit utilisé, il est appelé le démarrage de l'application.

Y a-t-il des solutions de contournement autres que de faire mon propre no-op OAuth2AuthorizedClientRepository?

//Éditer,

Ce n'est pas une pile entièrement réactive. C'est une pile Web de printemps avec la webclient étant utilisée avec elle.

Je suis bien conscient du ServerOAuth2AuthorizedClientExchangeFilterFunction qui s'applique à une pile entièrement réactive et nécessite ReactiveClientRegistrationRepository et ReactiveOauth2AuthorizedClient qui ne sont pas disponibles en raison de cet être dans une application construite sur le dessus de la pile de servlet, non réactives.

15
Darren Forsythe

J'ai fini par poser à cela à l'équipe de sécurité de printemps,

https://github.com/spring-projects/spring-security/issues/668

Malheureusement, si vous êtes sur la pile de servlets et que vous appelez aux ressources OAUTH2 avec une sécurité de printemps pur 5 API dans un fil de fond, il n'y a pas de OAuth2AuthorizedClientRepository disponible.

Réalisme, il y a deux options,

  1. Implémenter une version entièrement no-op,
 var oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrationRepo,
                        new OAuth2AuthorizedClientRepository() {
                            @Override
                            public <T extends OAuth2AuthorizedClient> T loadAuthorizedClient(String s,
                                    Authentication authentication, HttpServletRequest httpServletRequest) {
                                return null;
                            }

                            @Override
                            public void saveAuthorizedClient(OAuth2AuthorizedClient oAuth2AuthorizedClient,
                                    Authentication authentication, HttpServletRequest httpServletRequest,
                                    HttpServletResponse httpServletResponse) {

                            }

                            @Override
                            public void removeAuthorizedClient(String s, Authentication authentication,
                                    HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

                            }
                        });
  1. Implémenter une version de servlet de UnAuthenticatedServerOAuth2AuthorizedClientRepository. nauthentiatedServeroauth2authorizedClientRepository Github Source qui a une fonctionnalité de base qu'un pure no-op.

Fournir des commentaires sur la question GITUB pourrait aider l'équipe de sécurité de printemps à évaluer l'acceptation d'un PR et de conserver une version de servlet de l'UnAuthenticatedServerOAuth2AuthorizedClientRepository

J'ai contacté l'équipe de sécurité du printemps numéro de sécurité de printemps 668 et à l'arrière de cette version de servlet de la ServerOAuth2AuthorizedClientExchangeFilterFunction sera ajouté dans Security Spring 5.2 pour une utilisation sur des fils non http.

1
Darren Forsythe