I want to create some authentication service to be used for WebClient
, so it automatically refresh the token when needed:
@Service
public class AuthService {
private String token;
private final WebClient webClient;
private final Map<String, String> bodyValues;
@Autowired
public AuthService(WebClient webClient) {
this.webClient = webClient;
this.bodyValues = new HashMap<>();
this.bodyValues.put("user", "myUser");
this.bodyValues.put("password", "somePassword");
}
public String getToken() {
if (this.token == null || this.isExpired(this.token) {
this.refreshToken();
}
return this.token;
}
private void refreshToken() {
this.token = webClient.post()
.uri("authEndpointPath")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(bodyValues))
.retrieve()
.bodyToMono(String.class)
.block();
}
private boolean isExpired() {
//implementation
}
}
It gets the token correctly when it is expired. Is there a way to use it ONLY ONCE, without injecting it to other services? I was thinking about defining the Bean
which uses authService.getToken()
method:
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.defaultHeader("Access-Token", authService.getToken())
.build()
}
}
But obviously it will get the token only once at Application startup. Is there a way to inject it somehow or to intercept all of the webclient request and add the token then?
CodePudding user response:
You can declare a custom WebClient
with filter that is applied on each request.
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.filter(ExchangeFilterFunction.ofRequestProcessor(
(ClientRequest request) -> Mono.just(
ClientRequest.from(request)
.header("Access-Token", authService.getToken())
.build()
)
))
.build();
}
}