"principalName", accessToken, null); ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com")) .attributes(oauth2AuthorizedClient(authorizedClient)) .build();
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()); }
private Mono<ClientResponse> redirectIfNecessary(ClientRequest request, ExchangeFunction next, ClientResponse response) { URI location = response.headers().asHttpHeaders().getLocation(); String host = request.url().getHost(); String scheme = request.url().getScheme(); if (location != null) { String redirectUrl = location.toASCIIString(); if (location.getHost() == null) { redirectUrl = scheme+ "://" + host + location.toASCIIString(); } ClientRequest redirect = ClientRequest.method(HttpMethod.GET, URI.create(redirectUrl)) .headers(headers -> headers.addAll(request.headers())) .cookies(cookies -> cookies.addAll(request.cookies())) .attributes(attributes -> attributes.putAll(request.attributes())) .build(); return next.exchange(redirect).flatMap( r -> redirectIfNecessary(request, next, r)); } return Mono.just(response); } }
@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); }; }
/** * Create a session-bound {@link WebClient} to be used by {@link VaultTemplate} for * Vault communication given {@link VaultEndpointProvider} and * {@link ClientHttpConnector} for calls that require an authenticated context. * {@link VaultEndpointProvider} is used to contribute host and port details for * relative URLs typically used by the Template API. Subclasses may override this * method to customize the {@link WebClient}. * * @param endpointProvider must not be {@literal null}. * @param connector must not be {@literal null}. * @return the {@link WebClient} used for Vault communication. * @since 2.1 */ protected WebClient doCreateSessionWebClient(VaultEndpointProvider endpointProvider, ClientHttpConnector connector) { Assert.notNull(endpointProvider, "VaultEndpointProvider must not be null"); Assert.notNull(connector, "ClientHttpConnector must not be null"); ExchangeFilterFunction filter = ofRequestProcessor(request -> vaultTokenSupplier .getVaultToken().map(token -> { return ClientRequest.from(request).headers(headers -> { headers.set(VaultHttpHeaders.VAULT_TOKEN, token.getToken()); }).build(); })); return doCreateWebClient(endpointProvider, connector).mutate().filter(filter) .build(); }
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()); }
@Override public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) { URI originalUrl = request.url(); String serviceId = originalUrl.getHost(); if(serviceId == null) { String msg = String.format("Request URI does not contain a valid hostname: %s", originalUrl.toString()); logger.warn(msg); return Mono.just(ClientResponse.create(HttpStatus.BAD_REQUEST).body(msg).build()); } //TODO: reactive lb client ServiceInstance instance = this.loadBalancerClient.choose(serviceId); if(instance == null) { String msg = String.format("Load balancer does not contain an instance for the service %s", serviceId); logger.warn(msg); return Mono.just(ClientResponse.create(HttpStatus.SERVICE_UNAVAILABLE).body(msg).build()); } URI uri = this.loadBalancerClient.reconstructURI(instance, originalUrl); ClientRequest newRequest = ClientRequest.method(request.method(), uri) .headers(headers -> headers.addAll(request.headers())) .cookies(cookies -> cookies.addAll(request.cookies())) .attributes(attributes -> attributes.putAll(request.attributes())) .body(request.body()) .build(); return next.exchange(newRequest); }
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)); }
@Override public void subscribe(CoreSubscriber<? super ClientResponse> subscriber) { final ClientRequest.Builder builder = ClientRequest.from(this.request); Context context = subscriber.currentContext(); this.next.exchange(builder.build()).subscribe(new WebClientTracerSubscriber( subscriber, context, findOrCreateSpan(builder), this)); }
public void printAllPeople() { URI uri = URI.create(String.format("http://%s:%d/person", Server.HOST, Server.PORT)); ClientRequest request = ClientRequest.method(HttpMethod.GET, uri).build(); Flux<Person> people = exchange.exchange(request) .flatMapMany(response -> response.bodyToFlux(Person.class)); Mono<List<Person>> peopleList = people.collectList(); System.out.println(peopleList.block()); }
public void createPerson() { URI uri = URI.create(String.format("http://%s:%d/person", Server.HOST, Server.PORT)); Person jack = new Person("Jack Doe", 16); ClientRequest request = ClientRequest.method(HttpMethod.POST, uri) .body(BodyInserters.fromObject(jack)).build(); Mono<ClientResponse> response = exchange.exchange(request); System.out.println(response.block().statusCode()); }
@Override public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) { URI originalUrl = request.url(); String serviceId = originalUrl.getHost(); if(serviceId == null) { String msg = String.format("Request URI does not contain a valid hostname: %s", originalUrl.toString()); logger.warn(msg); return Mono.just(ClientResponse.create(HttpStatus.BAD_REQUEST).body(msg).build()); } //TODO: reactive lb client ServiceInstance instance = this.loadBalancerClient.choose(serviceId); if(instance == null) { String msg = String.format("Load balancer does not contain an instance for the service %s", serviceId); logger.warn(msg); return Mono.just(ClientResponse.create(HttpStatus.SERVICE_UNAVAILABLE).body(msg).build()); } URI uri = this.loadBalancerClient.reconstructURI(instance, originalUrl); ClientRequest newRequest = ClientRequest.method(request.method(), uri) .headers(headers -> headers.addAll(request.headers())) .cookies(cookies -> cookies.addAll(request.cookies())) .attributes(attributes -> attributes.putAll(request.attributes())) .body(request.body()) .build(); return next.exchange(newRequest); }
private ClientRequest applyUriDefaults(ClientRequest request) { URI requestUri = request.url(); if (!StringUtils.isEmpty(requestUri.getHost())) { return request; } try { requestUri = new URI("http", requestUri.getUserInfo(), "localhost", 8080, requestUri.getPath(), requestUri.getQuery(), requestUri.getFragment()); return ClientRequest.from(request).url(requestUri).build(); } catch (URISyntaxException ex) { throw new IllegalStateException(ex); } }
@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(); }
"principalName", this.accessToken, refreshToken); ClientRequest request = ClientRequest.create(GET, URI.create("https://example.com")) .attributes(oauth2AuthorizedClient(authorizedClient)) .attributes(authentication(this.authentication)) .build();