I am trying to consume a REST API in my Spring Boot application using WebClient.
This particular API takes basic-auth username and password as parameters in the URL, in the format http://username:password@hostname:8080/api/route.
I am currently building the full URL including username, password and route and passing it to the webclient when I am making my request, but it appears like the WebClient is not correctly sending the authentication parameters.
My current setup is as follows:
URI url = new URI("http://username:password@hostname:8080/api/route");
WebClient.Builder webClientBuilder = WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
WebClient webClient = webClientBuilder.build(); // I also have a customizer to add logging to the requests and responses
String requestBody = ""; // The body does not matter for this example
try {
response = webClient.post()
.uri(url)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(String.class)
.toFuture()
.get();
} catch (Exception e) {
logger.error(e.toString());
}
I am receiving a 401 unauthorised every time I make a request using this setup. When I manually make the same request using the same URL in Postman I am able to receive an authorized response from the server. It seems to me like WebClient is stripping out the authentication parameters from the call.
I have a logging customizer (like this answer WebClient – how to get request body?) that logs the requests and response method, URI, body and headers. It is giving the URI as /api/route and the host header as host: localhost:8080. I cannot see from the output whether the authentication parameters are actually being passed to the server.
Does anyone know if there is something special I must do in order to pass authentication parameters as part of the URL in WebClient?
>Solution :
To pass basic authentication parameters in WebClient, you can use the BasicAuthenticationInterceptor class provided by Spring Security. Here’s how you can modify your code to include basic authentication:
URI url = new URI("http://hostname:8080/api/route");
String username = "username";
String password = "password";
WebClient.Builder webClientBuilder = WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.filter(basicAuthentication(username, password));
WebClient webClient = webClientBuilder.build();
String requestBody = ""; // The body does not matter for this example
try {
String response = webClient.post()
.uri(url)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(String.class)
.block(); // Use block() instead of toFuture().get()
// Process the response
} catch (Exception e) {
logger.error(e.toString());
}