/** * Create a new {@link ReactiveVaultTemplate} with a {@link VaultEndpointProvider}, * {@link ClientHttpConnector} and {@link VaultTokenSupplier}. * * @param endpointProvider must not be {@literal null}. * @param connector must not be {@literal null}. * @param vaultTokenSupplier must not be {@literal null}. */ public ReactiveVaultTemplate(VaultEndpointProvider endpointProvider, ClientHttpConnector connector, VaultTokenSupplier vaultTokenSupplier) { Assert.notNull(endpointProvider, "VaultEndpointProvider must not be null"); Assert.notNull(connector, "ClientHttpConnector must not be null"); Assert.notNull(vaultTokenSupplier, "AuthenticationSupplier 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(); })); this.statelessClient = ReactiveVaultClients.createWebClient(endpointProvider, connector); this.sessionClient = ReactiveVaultClients .createWebClient(endpointProvider, connector).mutate().filter(filter) .build(); }
/** * Create a {@link ClientHttpConnector} for the given {@link ClientOptions} and * {@link SslConfiguration}. * * @param options must not be {@literal null} * @param sslConfiguration must not be {@literal null} * @return a new {@link ClientHttpConnector}. */ public static ClientHttpConnector create(ClientOptions options, SslConfiguration sslConfiguration) { return new ReactorClientHttpConnector(builder -> { if (hasSslConfiguration(sslConfiguration)) { builder.sslSupport(sslContextBuilder -> { configureSsl(sslConfiguration, sslContextBuilder); }).poolResources( PoolResources.elastic("vault-http-" + POOL_COUNTER.incrementAndGet())); } builder.sslHandshakeTimeout(options.getConnectionTimeout()); builder.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(options.getConnectionTimeout().toMillis())); }); }
@Test public void justLoginRequestShouldLogin() { ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.POST, "/auth/cert/login"); MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); response.getHeaders().setContentType(MediaType.APPLICATION_JSON); response.setBody("{" + "\"auth\":{\"client_token\":\"my-token\", \"renewable\": true, \"lease_duration\": 10}" + "}"); ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then( Mono.just(response)); WebClient webClient = WebClient.builder().clientConnector(connector).build(); AuthenticationSteps steps = AuthenticationSteps.just(post("/auth/{path}/login", "cert").as(VaultResponse.class)); StepVerifier.create(login(steps, webClient)) .expectNext(VaultToken.of("my-token")).verifyComplete(); }
@Test public void justLoginShouldFail() { ClientHttpRequest request = new MockClientHttpRequest(HttpMethod.POST, "/auth/cert/login"); MockClientHttpResponse response = new MockClientHttpResponse( HttpStatus.BAD_REQUEST); ClientHttpConnector connector = (method, uri, fn) -> fn.apply(request).then( Mono.just(response)); WebClient webClient = WebClient.builder().clientConnector(connector).build(); AuthenticationSteps steps = AuthenticationSteps.just(post("/auth/{path}/login", "cert").as(VaultResponse.class)); StepVerifier.create(login(steps, webClient)).expectError().verify(); }
private WebClient createSSLWebClient() throws IOException { /* Create a Reactor connector and tell it to trust our certificate */ final File pemFile = pemResource.getFile(); final ClientHttpConnector clientConnector = new ReactorClientHttpConnector( options -> options.sslSupport(builder -> builder.trustManager(pemFile))); /* Build a WebClient with the custom connector */ return WebClient.builder() .baseUrl(String.format("https://127.0.0.1:%d", port)) .clientConnector(clientConnector) .build(); }
/** * Create a {@link WebClient} configured with {@link VaultEndpoint} and * {@link ClientHttpConnector}. The client accepts relative URIs without a leading * slash that are expanded to use {@link VaultEndpoint}. * <p> * Requires Jackson 2 for Object-to-JSON mapping. * * @param endpointProvider must not be {@literal null}. * @param connector must not be {@literal null}. * @return the configured {@link WebClient}. */ public static WebClient createWebClient(VaultEndpointProvider endpointProvider, ClientHttpConnector connector) { Assert.notNull(endpointProvider, "VaultEndpointProvider must not be null"); Assert.notNull(connector, "ClientHttpConnector must not be null"); UriBuilderFactory uriBuilderFactory = VaultClients .createUriBuilderFactory(endpointProvider); ExchangeStrategies strategies = ExchangeStrategies.builder() .codecs(configurer -> { CustomCodecs cc = configurer.customCodecs(); cc.decoder(new ByteArrayDecoder()); cc.decoder(new Jackson2JsonDecoder()); cc.decoder(StringDecoder.allMimeTypes(false)); cc.encoder(new ByteArrayEncoder()); cc.encoder(new Jackson2JsonEncoder()); }).build(); return WebClient.builder().uriBuilderFactory(uriBuilderFactory) .exchangeStrategies(strategies).clientConnector(connector).build(); }
/** * Create a {@link WebClient} configured with {@link VaultEndpoint} and * {@link ClientHttpConnector}. The client accepts relative URIs without a leading * slash that are expanded to use {@link VaultEndpoint}. * <p> * Requires Jackson 2 for Object-to-JSON mapping. * * @param endpoint must not be {@literal null}. * @param connector must not be {@literal null}. * @return the configured {@link WebClient}. */ public static WebClient createWebClient(VaultEndpoint endpoint, ClientHttpConnector connector) { return createWebClient(SimpleVaultEndpointProvider.of(endpoint), connector); }
/** * Create a {@link ClientHttpConnector} configured with {@link ClientOptions} and * {@link org.springframework.vault.support.SslConfiguration}. * * @return the {@link ClientHttpConnector} instance. * @see #clientOptions() * @see #sslConfiguration() */ protected ClientHttpConnector clientHttpConnector() { return ClientHttpConnectorFactory.create(clientOptions(), sslConfiguration()); }
/** * Create a new {@link ReactiveVaultTemplate} with a {@link VaultEndpoint}, * {@link ClientHttpConnector} and {@link VaultTokenSupplier}. * * @param vaultEndpoint must not be {@literal null}. * @param connector must not be {@literal null}. * @param vaultTokenSupplier must not be {@literal null}. */ public ReactiveVaultTemplate(VaultEndpoint vaultEndpoint, ClientHttpConnector connector, VaultTokenSupplier vaultTokenSupplier) { this(SimpleVaultEndpointProvider.of(vaultEndpoint), connector, vaultTokenSupplier); }