Я новичок в загрузочном и реактивном программировании Spring.
Я использую веб-клиент Spring Webflux для внешнего API-сервиса.Мне нужно получить токен авторизации и установить его в заголовке
WebClient.builder()
.baseUrl(baseUrl)
.filter((request, next) -> {
return next.exchange(request)
.flatMap((Function<ClientResponse, Mono<ClientResponse>>) clientResponse -> {
if (clientResponse.statusCode().value() == 401) {
return authenticate().map(token -> {
Token accessToken = authenticate().block();
ClientRequest retryRequest = ClientRequest.from(request).header("Authorisation", "Bearer " + accessToken.getAccessToken()).build();
return next.exchange(retryRequest);
}).
} else {
return Mono.just(clientResponse);
}
});
})
.defaultHeader("Authorization", "Bearer " + authToken.getAccessToken())
.build();
private Mono<Token> authenticate() {
MultiValueMap<String, String> params = new LinkedMultiValueMap();
params.add("client_id", clientId);
params.add("client_secret", clientSecret);
params.add("grant_type", "password");
params.add("username", username);
params.add("password", password);
WebClient client = WebClient.create(baseUrl);
return client
.post()
.uri(tokenUri)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.syncBody(params)
.retrieve()
.bodyToMono(Token.class);
}
private static class Token {
@JsonProperty("access_token")
private String accessToken;
public String getAccessToken() { return accessToken; }
}
. Во время запуска приложения я получу токен доступа и установлю его в построителе веб-клиента.Я создал фильтр для обработки ошибок аутентификации после истечения срока действия токена.Но приведенный выше код выдает ошибку, потому что я использовал block (), который не должен использоваться в потоке реактора.Как еще я могу справиться с этим?Я использую поток предоставления пароля владельца ресурса oauth2.Есть ли другой способ справиться с потоком?