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.
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,
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) { } });
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.