繁体   English   中英

spring webclient 签署一个正文请求

[英]spring webclient sign a body request

我需要签署一个在 Spring 中使用 WebClient 发送的正文请求。

现在,问题是我无法以“原始”方式获取正文(发送到远程服务器的确切正文)并从该正文计算签名。

我有两个场景,一个对象的帖子和一个 FormData 的帖子。 在第一天,我可能可以使用 ObjectMapper 来模拟 WebClient 的作用(直到 WebClient 更改它,并且一切都中断了)但是对于 FormData,模拟它会很棘手。

如果我发送 a = b, e = xi 必须处理编码和参数顺序(从 http 的角度来看)它不是强制性的,所以 a=b, e=x 它与 e=x,a=b 相同,但是对于 sha1(string) 更改的签名而言,情况并非如此

使用过滤器,我得到了 body() 但它是一个 BodyInserter 并且它似乎不能转换为 String 或 byte[]

对正文进行签名需要以序列化形式进行,但序列化发生在发送数据之前,因此需要对其进行拦截。

假设您将数据作为 JSON 发送,您可以通过创建自己的 JsonEncoder(例如包装现有的Jackson2JsonEncoder )并在构建WebClient时将其作为ExchangeStrategies传递来实现。 截获序列化数据后,就可以注入headers了。 但是 Encoder 没有对ClientHttpRequest的引用,因此您需要在HttpConnector捕获此对象并将其传递到SubscriberContext

BodyInserters自动选择消息编写器来编写消息,并且在编码/序列化(如 Json)的情况下,这会像我建议的包装编码器一样传递编解码器。
(如果您不发送 JSON,请告诉我们什么格式,因为其他内容类型的解决方案会有所不同,例如 url 编码形式等。)

这篇博文解释了这个过程: https : //andrew-flower.com/blog/Custom-HMAC-Auth-with-Spring-WebClient#s-post-data-signing

例如,您的WebClient创建步骤可能如下所示,其中MessageCapturingHttpConnector是捕获ClientHttpRequestBodyCapturingJsonEncoder的连接器

Signer signer = new Signer(clientId, secret);
MessageSigningHttpConnector httpConnector = new MessageSigningHttpConnector();
BodyCapturingJsonEncoder bodyCapturingJsonEncoder
    = new BodyCapturingJsonEncoder(signer);

WebClient client
    = WebClient.builder()
               .exchangeFunction(ExchangeFunctions.create(
                       httpConnector,
                       ExchangeStrategies
                              .builder()
                               .codecs(clientDefaultCodecsConfigurer -> {
                                   clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(bodyCapturingJsonEncoder);
                                   clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
                               })
                               .build()
               ))
               .baseUrl(String.format("%s://%s/%s", environment.getProtocol(), environment.getHost(), environment.getPath()))
               .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
               .build();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM