Как получить доступ к телу запроса с помощью WebFlux и Netty HttpClient

Мне нужно вычислить какой-то дайджест тела запроса с помощью WebClient Webflux, и этот дайджест должен быть установлен в заголовке HTTP. Использовать старый добрый Spring MVC ClientHttpRequestInterceptor легко, поскольку тело запроса предоставляется в виде массива байтов.

Функция ExchangeFilterFunction не предоставляет доступ к телу запроса.

Тело отправляется как JSon, а Spring использует Jackson для сериализации объектов Java, поэтому можно сериализовать мой объект в Json и вычислить по нему дайджест, но у этой стратегии есть два недостатка:

  • мой код будет повторять то, что будет делать Spring, когда запрос действительно будет отправлен
  • нет гарантии, что фактические байты, отправленные Spring в качестве запроса, равны тому, что я передал в функцию дайджеста

Я полагаю, что мне следует использовать какой-то низкоуровневый API Netty, но я не могу найти ни одного примера.


person Claudio Tasso    schedule 01.01.2021    source источник
comment
github.com/spring-projects/spring-framework/issues/24262   -  person Toerktumlare    schedule 01.01.2021


Ответы (2)


Я реализовал решение, предложенное @rewolf, и оно сработало, но я столкнулся с проблемой из-за многопоточности WebFlux.

Фактически, возможно, что клиентский запрос сохраняется в локальной карте потока одним потоком, но другой поток пытается его получить, поэтому возвращается нулевое значение.

Например, это происходит, если подписываемый запрос создается внутри метода контроллера Rest, который имеет Mono в качестве параметра тела запроса:

@PostMapping
public String execute(@RequestBody Mono<MyBody> body){

    Mono<OtherBody> otherBody = body.map(this::transformBodyIntoOtherBody);

    ...
    webClient.post()
    .body(otherBody)
    .exchange();
    ...
    
}

Согласно спецификациям Reactor, следует использовать контекст Reactor вместо Thread Local.

Я разветвил проект @rewolf и реализовал решение на основе Reactor Context: https://github.com/taxone/blog-hmac-auth-webclient

person Claudio Tasso    schedule 09.01.2021
comment
Это отличный момент. На прошлой неделе мне в голову пришла проблема параллелизма, но вскоре я забыл про нее. Если вы сделаете пул-реквест, я объединю его и обновлю сообщение в блоге, указав ваше имя. - person rewolf; 13.01.2021
comment
@rewolf запрос на слияние: github.com/rewolf/blog-hmac- auth-webclient / pull / 1 - person Claudio Tasso; 15.01.2021

В настоящее время это непросто сделать с помощью WebClient. Но есть способы сделать это путем перехвата пост-сериализации тела. Это можно сделать, зарегистрировав настраиваемый кодировщик, который перехватывает данные после кодирования и передает их настраиваемому HttpConnector для вставки в качестве заголовка.

В этом сообщении в блоге объясняется один способ добиться этого: https://andrew-flower.com/blog/Custom-HMAC-Auth-with-Spring-WebClient

Изменить: в настоящее время в этом сообщении блога не учитываются одновременные запросы. См. Принятый ответ Claodio для измененного подхода.

person rewolf    schedule 04.01.2021