In Spring Web 6.0.13, with Apache HttpClient configured to provide credentials, posting a MultiValueMap to an endpoint protected using Digest Authentication works.

When Spring Web 6.1.0-RC2 is used, instead of responding to the authentication challenge, the 401 response is returned to the caller.

Demo repository: https://github.com/nwholloway/spring-web-bug

This contains a Docker Compose configuration to provide digest auth secured endpoint, and the demonstration Java code.

If you change the Spring Web version in build.gradle from 6.1.0-RC2 to 6.0.13 the expected 200 response is received.

Comment From: snicoll

Thanks for the report and the sample. We believe that some recent work in that area may have contributed to this problem. We'll look into it ASAP.

Comment From: poutsma

This is related to #30557. For digest authentication to work, the request body has to be written multiple times, due to redirects. Prior to 6.1, all request bodies were buffered into a byte array, which can be written multiple times. As of 6.1, we no longer do so in order to save memory.

If you still want to buffer the request body, just like in 6.0, you can wrap the HttpComponentsClientHttpRequestFactory in a BufferingClientHttpRequestFactory, like so:

ClientHttpRequestFactory requestFactory = new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));

return new RestTemplate(requestFactory);

Making the above change in Demo.java in your demo app fixes the issue in Spring Framework 6.1.0-RC2. See also #31449, wherein changes were made to support repeatable writes.

However, I believe that buffering all requests is a bit excessive, and should not be necessary. In the case of your demo app, for instance, the request body consists of a MultiValueMap which can safely be written to an output stream multiple times. Only read-once bodies, such as InputStream objects, cannot be written multiple times.

So I will make some additional changes to the HttpMessageConverter implementations and allow repeatable writes where it makes sense.

Comment From: poutsma

To be clear, with the changes made in 6dd93d4 that will be in 6.1.0, you should not have to wrap the request factory with a BufferingClientHttpRequestFactory anymore.