@Test public void captureAndClaim() { ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test"); ClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then(Mono.just(response)); ClientRequest clientRequest = ClientRequest.create(HttpMethod.GET, URI.create("/test")) .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); WiretapConnector wiretapConnector = new WiretapConnector(connector); ExchangeFunction function = ExchangeFunctions.create(wiretapConnector); function.exchange(clientRequest).block(ofMillis(0)); WiretapConnector.Info actual = wiretapConnector.claimRequest("1"); ExchangeResult result = actual.createExchangeResult(Duration.ZERO, null); assertEquals(HttpMethod.GET, result.getMethod()); assertEquals("/test", result.getUrl().toString()); }
private Mono<OAuth2AuthorizedClient> authorizeWithRefreshToken(ClientRequest request, ExchangeFunction next, OAuth2AuthorizedClient authorizedClient) { ClientRegistration clientRegistration = authorizedClient .getClientRegistration(); String tokenUri = clientRegistration .getProviderDetails().getTokenUri(); ClientRequest refreshRequest = ClientRequest.create(HttpMethod.POST, URI.create(tokenUri)) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(refreshTokenBody(authorizedClient.getRefreshToken().getTokenValue())) .build(); return next.exchange(refreshRequest) .flatMap(response -> response.body(oauth2AccessTokenResponse())) .map(accessTokenResponse -> new OAuth2AuthorizedClient(authorizedClient.getClientRegistration(), authorizedClient.getPrincipalName(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken())) .map(result -> { Authentication principal = (Authentication) request.attribute( AUTHENTICATION_ATTR_NAME).orElse(new PrincipalNameAuthentication(authorizedClient.getPrincipalName())); HttpServletRequest httpRequest = (HttpServletRequest) request.attributes().get( HTTP_SERVLET_REQUEST_ATTR_NAME); HttpServletResponse httpResponse = (HttpServletResponse) request.attributes().get( HTTP_SERVLET_RESPONSE_ATTR_NAME); this.authorizedClientRepository.saveAuthorizedClient(result, principal, httpRequest, httpResponse); return result; }) .publishOn(Schedulers.elastic()); }
@Test public void build() { ClientRequest result = ClientRequest.create(GET, URI.create("http://example.com")) .header("MyKey", "MyValue") .cookie("foo", "bar") .build(); MockClientHttpRequest request = new MockClientHttpRequest(GET, "/"); ExchangeStrategies strategies = mock(ExchangeStrategies.class); result.writeTo(request, strategies).block(); assertEquals("MyValue", request.getHeaders().getFirst("MyKey")); assertEquals("bar", request.getCookies().getFirst("foo").getValue()); StepVerifier.create(request.getBody()).expectComplete().verify(); }
@Bean public CommandLineRunner tweetBot(TwitterOAuth twitterOAuth, ReactiveTweetRepository tweetRepo) { return args -> { MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); String tracks = "#cltjug,#FathersDay"; if (args.length > 0) { log.info("Using arguments as tracks"); tracks = String.join(",", args); } log.info("Filtering tracks [{}]", tracks); body.add("track", tracks); WebClient webClient = WebClient.create() .filter((currentRequest, next) -> next.exchange(ClientRequest.from(currentRequest) .header(HttpHeaders.AUTHORIZATION, twitterOAuth.oAuth1Header( currentRequest.url(), currentRequest.method(), body.toSingleValueMap())) .build())); Flux<Tweet> tweets = webClient .post() .uri(TwitterApiEndpoint.TWITTER_STREAM_API_STATUS_FILTER_URL) .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(BodyInserters.fromFormData(body)) .exchange() .flatMapMany(clientResponse -> clientResponse.bodyToFlux(Tweet.class)); tweetRepo.saveAll(tweets).subscribe(System.out::println); }; }
private Mono<OAuth2AuthorizedClient> refreshAuthorizedClient(ClientRequest request, ExchangeFunction next, OAuth2AuthorizedClient authorizedClient) { ClientRegistration clientRegistration = authorizedClient .getClientRegistration(); String tokenUri = clientRegistration .getProviderDetails().getTokenUri(); ClientRequest refreshRequest = ClientRequest.create(HttpMethod.POST, URI.create(tokenUri)) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(refreshTokenBody(authorizedClient.getRefreshToken().getTokenValue())) .build(); return next.exchange(refreshRequest) .flatMap(response -> response.body(oauth2AccessTokenResponse())) .map(accessTokenResponse -> new OAuth2AuthorizedClient(authorizedClient.getClientRegistration(), authorizedClient.getPrincipalName(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken())) .map(result -> { Authentication principal = (Authentication) request.attribute( AUTHENTICATION_ATTR_NAME).orElse(new PrincipalNameAuthentication(authorizedClient.getPrincipalName())); HttpServletRequest httpRequest = (HttpServletRequest) request.attributes().get( HTTP_SERVLET_REQUEST_ATTR_NAME); HttpServletResponse httpResponse = (HttpServletResponse) request.attributes().get( HTTP_SERVLET_RESPONSE_ATTR_NAME); this.authorizedClientRepository.saveAuthorizedClient(result, principal, httpRequest, httpResponse); return result; }) .publishOn(Schedulers.elastic()); }
private Mono<OAuth2AuthorizedClient> refreshAuthorizedClient(ExchangeFunction next, OAuth2AuthorizedClient authorizedClient, OAuth2AuthorizedClientResolver.Request r) { ServerWebExchange exchange = r.getExchange(); Authentication authentication = r.getAuthentication(); ClientRegistration clientRegistration = authorizedClient .getClientRegistration(); String tokenUri = clientRegistration .getProviderDetails().getTokenUri(); ClientRequest refreshRequest = ClientRequest.create(HttpMethod.POST, URI.create(tokenUri)) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(refreshTokenBody(authorizedClient.getRefreshToken().getTokenValue())) .build(); return next.exchange(refreshRequest) .flatMap(refreshResponse -> refreshResponse.body(oauth2AccessTokenResponse())) .map(accessTokenResponse -> new OAuth2AuthorizedClient(authorizedClient.getClientRegistration(), authorizedClient.getPrincipalName(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken())) .flatMap(result -> this.authorizedClientRepository.saveAuthorizedClient(result, authentication, exchange) .thenReturn(result)); }
@Bean WebClient githubWebClient(final GithubProperties props) { return WebClient.builder() .baseUrl(props.getBaseUrl()) .filter((request, next) -> next.exchange( ClientRequest.from(request) .header(AUTHORIZATION, basicAuthorization(props.getToken())) .build())) .build(); }
@Test public void requestUriIsNotChangedWhenItHasAHost() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("https://api.example.com:4567/test?foo=bar#baz")) .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); ExchangeFunction exchangeFunction = mock(ExchangeFunction.class); this.configurer.filter(request, exchangeFunction); ArgumentCaptor<ClientRequest> requestCaptor = ArgumentCaptor .forClass(ClientRequest.class); verify(exchangeFunction).exchange(requestCaptor.capture()); assertThat(requestCaptor.getValue().url()) .isEqualTo(URI.create("https://api.example.com:4567/test?foo=bar#baz")); }
@Test public void requestUriHasDefaultsAppliedWhenItHasNoHost() { ClientRequest request = ClientRequest .create(HttpMethod.GET, URI.create("/test?foo=bar#baz")) .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); ExchangeFunction exchangeFunction = mock(ExchangeFunction.class); this.configurer.filter(request, exchangeFunction); ArgumentCaptor<ClientRequest> requestCaptor = ArgumentCaptor .forClass(ClientRequest.class); verify(exchangeFunction).exchange(requestCaptor.capture()); assertThat(requestCaptor.getValue().url()) .isEqualTo(URI.create("http://localhost:8080/test?foo=bar#baz")); }
@Test public void configurationCanBeRetrievedButOnlyOnce() { ClientRequest request = ClientRequest.create(HttpMethod.GET, URI.create("/test")) .header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build(); this.configurer.filter(request, mock(ExchangeFunction.class)); assertThat(WebTestClientRestDocumentationConfigurer .retrieveConfiguration(request.headers())).isNotNull(); assertThat(WebTestClientRestDocumentationConfigurer .retrieveConfiguration(request.headers())).isNull(); }
private Mono<OAuth2AuthorizedClient> authorizeWithRefreshToken(ExchangeFunction next, OAuth2AuthorizedClient authorizedClient, OAuth2AuthorizedClientResolver.Request r) { ServerWebExchange exchange = r.getExchange(); Authentication authentication = r.getAuthentication(); ClientRegistration clientRegistration = authorizedClient .getClientRegistration(); String tokenUri = clientRegistration .getProviderDetails().getTokenUri(); ClientRequest refreshRequest = ClientRequest.create(HttpMethod.POST, URI.create(tokenUri)) .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(refreshTokenBody(authorizedClient.getRefreshToken().getTokenValue())) .build(); return next.exchange(refreshRequest) .flatMap(refreshResponse -> refreshResponse.body(oauth2AccessTokenResponse())) .map(accessTokenResponse -> new OAuth2AuthorizedClient(authorizedClient.getClientRegistration(), authorizedClient.getPrincipalName(), accessTokenResponse.getAccessToken(), accessTokenResponse.getRefreshToken())) .flatMap(result -> this.authorizedClientRepository.saveAuthorizedClient(result, authentication, exchange) .thenReturn(result)); }
@Test public void filterWhenExistingAuthorizationThenSingleAuthorizationHeader() { OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration, "principalName", this.accessToken); ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com")) .header(HttpHeaders.AUTHORIZATION, "Existing") .attributes(oauth2AuthorizedClient(authorizedClient)) .build(); this.function.filter(request, this.exchange).block(); HttpHeaders headers = this.exchange.getRequest().headers(); assertThat(headers.get(HttpHeaders.AUTHORIZATION)).containsOnly("Bearer " + this.accessToken.getTokenValue()); }
@Test public void filterWhenExistingAuthorizationThenSingleAuthorizationHeader() { OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(this.registration, "principalName", this.accessToken); ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com")) .header(HttpHeaders.AUTHORIZATION, "Existing") .attributes(oauth2AuthorizedClient(authorizedClient)) .build(); this.function.filter(request, this.exchange).block(); HttpHeaders headers = this.exchange.getRequest().headers(); assertThat(headers.get(HttpHeaders.AUTHORIZATION)).containsOnly("Bearer " + this.accessToken.getTokenValue()); }
@Test public void shouldApplyExchangeFilter() { prepareResponse(response -> response.setHeader("Content-Type", "text/plain") .setBody("Hello Spring!")); WebClient filteredClient = this.webClient.mutate() .filter((request, next) -> { ClientRequest filteredRequest = ClientRequest.from(request).header("foo", "bar").build(); return next.exchange(filteredRequest); }) .build(); Mono<String> result = filteredClient.get() .uri("/greeting?name=Spring") .retrieve() .bodyToMono(String.class); StepVerifier.create(result) .expectNext("Hello Spring!") .expectComplete() .verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> assertEquals("bar", request.getHeader("foo"))); }
@Test public void from() throws URISyntaxException { ClientRequest other = ClientRequest.create(GET, URI.create("http://example.com")) .header("foo", "bar") .cookie("baz", "qux").build(); ClientRequest result = ClientRequest.from(other) .headers(httpHeaders -> httpHeaders.set("foo", "baar")) .cookies(cookies -> cookies.set("baz", "quux")) .build(); assertEquals(new URI("http://example.com"), result.url()); assertEquals(GET, result.method()); assertEquals(1, result.headers().size()); assertEquals("baar", result.headers().getFirst("foo")); assertEquals(1, result.cookies().size()); assertEquals("quux", result.cookies().getFirst("baz")); }