'Spring Web-client: Basic Authentication Using Bearer token
I am trying to to write a web-client where the Bearer token is attached to web-client call like OAUT2 mentioned here https://www.baeldung.com/spring-webclient-oauth2
Here is the flow.
First Call to get token:
Post:/auth/token
Request Body: form-url-encode ex: name=john&[email protected]
Headers: Authorization : Basic "{HardCode TokenHere}"
Second to call to external service uisng the token got from above.
Service Url:
GET: /service/getUserInfo?email={email}
Headers:
Authorization:Basic {Token Received from first call above}
Currently I followed manual approach . I just have the token, i don't have clientId and client secret.
@Autowired
WebClient client;
public Mono<String> obtainSecuredResource() {
Mono<String> resource = client.post()
.uri("localhost:8085/oauth/token")
.header("Authorization", "Basic " + {TOKEN_HERE})
.body(BodyInserters.fromFormData("grant_type", "client_credentials"))
.retrieve()
.bodyToMono(JsonNode.class)
.flatMap(tokenResponse -> {
String accessTokenValue = tokenResponse.get("access_token")
.textValue();
return client.get()
.uri("localhost:8084/retrieve-resource")
.headers(h -> h.setBearerAuth(accessTokenValue))
.retrieve()
.bodyToMono(String.class);
});
return resource.map(res ->
"Retrieved the resource using a manual approach: " + res);
Does spring webflux provides any good way to get token and pass to web-client,like using OAuth2Filter and pass reqgistartionId?
Solution 1:[1]
The best way would be to use ServerOAuth2AuthorizedClientExchangeFilterFunction that you could customize to satisfy your needs. In this case token will be updated automatically behind the scene.
If you are looking for "manual" approach, you just need to combine 2 requests.
public Mono<String> obtainSecuredResource() {
return getToken()
.flatMap(token -> getResource(token));
}
private Mono<String> getResource(String authToken) {
return client.get()
.uri("localhost:8084/retrieve-resource")
.headers(h -> h.setBearerAuth(authToken))
.retrieve()
.bodyToMono(String.class);
}
private Mono<String> getToken() {
return client.post()
.uri("localhost:8085/oauth/token")
.header("Authorization", "Basic " + {TOKEN_HERE})
.body(BodyInserters.fromFormData("grant_type", "client_credentials"))
.retrieve()
.bodyToMono(JsonNode.class)
.map(tokenResponse ->
tokenResponse.get("access_token").textValue()
);
}
In this case you will always execute 2 requests and get token for every resource request.
Usually token has expiration and you could save some requests by caching getToken() Mono.
private Mono<String> tokenRequest = getToken().cache(Duration.ofMinutes(30));
public Mono<String> obtainSecuredResource() {
return tokenRequest
.flatMap(token -> getResource(token));
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alex |
