ezpzlmnsqzy1
ezpzlmnsqzy1

Reputation: 41

Modify/Replace ClientHttpResponse body inside interceptor (ClientHttpRequestInterceptor)

I'm adding message level encryption (MLE) to an existing code base for outgoing requests. To do this, I simply wrote an interceptor that will catch outgoing requests, encrypt their bodies, and then send the request out. The response we get is also encrypted, and must be decrypted. This all is working fine for me. The only problem I'm having is that I must replace the ClientHttpResponse encrypted body with the now decrypted JSON. How can I do this? I don't see any methods that will let me alter the response body. Thanks in advance.

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
        throws IOException {
    ClientHttpResponse response;
    String bodyStr = new String(body);

    // Encrypt the body and send
    bodyStr = encrypt(bodyStr);
    try {
        response = execution.execute(request, bodyStr.getBytes());
    } catch (Exception e) {
        throw e;
    }

    // Decrypt the response body
    String decryptedResponseBody = decrypt(response.getBody());

    // Set the response body to the decrypted data (JSON)
    // response.setBody(decryptedResponseBody)?????????

    return response;
}

Upvotes: 4

Views: 2446

Answers (1)

lac_dev
lac_dev

Reputation: 1449

You will need to create an implementation of ClientHttpResponse which is not too hard since there are only a few methods to override, I added an example of how you would fix this. I hope this helps. I would suggest adding a named bean for this type of request, you don't want to have all your resttemplates being encrypted/decrypted.

restTemplate.getInterceptors().add( (ClientHttpRequestInterceptor)  
(request, body, execution) -> {
        ClientHttpResponse response;

        String bodyStr = new String(body);

        // Encrypt the body and send
        bodyStr = encrypt(bodyStr);

        try {
            response = execution.execute(request, bodyStr.getBytes());
            String text = IOUtils.toString(response.getBody(), StandardCharsets.UTF_8.name());

            // Decrypt the response body
            String decryptedResponseBody = decrypt(text);
            
        } catch (Exception e) {
            throw e;
        }

        InputStream inputStream = inputStream = new ByteArrayInputStream(decryptedResponseBody.getBytes());

        return new ClientHttpResponse() {

            @Override
            public HttpHeaders getHeaders() {
                return response.getHeaders();
            }

            @Override
            public InputStream getBody() throws IOException {
                return inputStream;
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return response.getStatusCode();
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return response.getRawStatusCode();
            }

            @Override
            public String getStatusText() throws IOException {
                return response.getStatusText();
            }

            @Override
            public void close() {
                response.close();
            }
        };
}))

Upvotes: 1

Related Questions