Skip to content

Commit cf3196e

Browse files
committed
Merge branch '7.0.x'
2 parents 80e9e4f + 1e843fd commit cf3196e

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
package org.springframework.web.reactive.function.client;
1818

1919
import java.nio.charset.Charset;
20+
import java.nio.charset.StandardCharsets;
2021
import java.util.function.Function;
2122
import java.util.function.Predicate;
2223

24+
import org.jspecify.annotations.Nullable;
2325
import reactor.core.publisher.Mono;
2426

2527
import org.springframework.core.io.buffer.DataBufferUtils;
@@ -34,6 +36,7 @@
3436
* @author Rob Winch
3537
* @author Arjen Poutsma
3638
* @author Sam Brannen
39+
* @author Kai Zander
3740
* @since 5.0
3841
*/
3942
public abstract class ExchangeFilterFunctions {
@@ -76,14 +79,35 @@ public static ExchangeFilterFunction statusError(Predicate<HttpStatusCode> statu
7679
* Return a filter that applies HTTP Basic Authentication to the request
7780
* headers via {@link HttpHeaders#setBasicAuth(String)} and
7881
* {@link HttpHeaders#encodeBasicAuth(String, String, Charset)}.
82+
* <p>{@linkplain StandardCharsets#ISO_8859_1 ISO-8859-1} is used to convert
83+
* the credentials into an octet sequence.
7984
* @param username the username
8085
* @param password the password
8186
* @return the filter to add authentication headers with
87+
* @see #basicAuthentication(String, String, Charset)
8288
* @see HttpHeaders#encodeBasicAuth(String, String, Charset)
8389
* @see HttpHeaders#setBasicAuth(String)
8490
*/
8591
public static ExchangeFilterFunction basicAuthentication(String username, String password) {
86-
String encodedCredentials = HttpHeaders.encodeBasicAuth(username, password, null);
92+
return basicAuthentication(username, password, null);
93+
}
94+
95+
/**
96+
* Return a filter that applies HTTP Basic Authentication to the request
97+
* headers via {@link HttpHeaders#setBasicAuth(String)} and
98+
* {@link HttpHeaders#encodeBasicAuth(String, String, Charset)}.
99+
* @param username the username
100+
* @param password the password
101+
* @param charset the charset to use to convert the credentials into an octet
102+
* sequence. Defaults to {@linkplain StandardCharsets#ISO_8859_1 ISO-8859-1}.
103+
* @return the filter to add authentication headers with
104+
* @since 7.0.8
105+
* @see #basicAuthentication(String, String)
106+
* @see HttpHeaders#encodeBasicAuth(String, String, Charset)
107+
* @see HttpHeaders#setBasicAuth(String)
108+
*/
109+
public static ExchangeFilterFunction basicAuthentication(String username, String password, @Nullable Charset charset) {
110+
String encodedCredentials = HttpHeaders.encodeBasicAuth(username, password, charset);
87111
return (request, next) ->
88112
next.exchange(ClientRequest.from(request)
89113
.headers(headers -> headers.setBasicAuth(encodedCredentials))

spring-webflux/src/test/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctionsTests.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* Tests for {@link ExchangeFilterFunctions}.
4444
*
4545
* @author Arjen Poutsma
46+
* @author Kai Zander
4647
*/
4748
class ExchangeFilterFunctionsTests {
4849

@@ -104,7 +105,7 @@ void basicAuthenticationUsernamePassword() {
104105

105106
ExchangeFunction exchange = r -> {
106107
assertThat(r.headers().containsHeader(HttpHeaders.AUTHORIZATION)).isTrue();
107-
assertThat(r.headers().getFirst(HttpHeaders.AUTHORIZATION)).startsWith("Basic ");
108+
assertThat(r.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Basic Zm9vOmJhcg==");
108109
return Mono.just(response);
109110
};
110111

@@ -114,6 +115,23 @@ void basicAuthenticationUsernamePassword() {
114115
assertThat(result).isEqualTo(response);
115116
}
116117

118+
@Test // gh-36777
119+
void basicAuthenticationUsernameAndUnicodePassword() {
120+
ClientRequest request = ClientRequest.create(HttpMethod.GET, DEFAULT_URL).build();
121+
ClientResponse response = mock();
122+
123+
ExchangeFunction exchange = r -> {
124+
assertThat(r.headers().containsHeader(HttpHeaders.AUTHORIZATION)).isTrue();
125+
assertThat(r.headers().getFirst(HttpHeaders.AUTHORIZATION)).isEqualTo("Basic Zm9vOvCfkqk=");
126+
return Mono.just(response);
127+
};
128+
129+
ExchangeFilterFunction auth = ExchangeFilterFunctions.basicAuthentication("foo", "\ud83d\udca9", StandardCharsets.UTF_8);
130+
assertThat(request.headers().containsHeader(HttpHeaders.AUTHORIZATION)).isFalse();
131+
ClientResponse result = auth.filter(request, exchange).block();
132+
assertThat(result).isEqualTo(response);
133+
}
134+
117135
@Test
118136
void basicAuthenticationInvalidCharacters() {
119137
ClientRequest request = ClientRequest.create(HttpMethod.GET, DEFAULT_URL).build();

0 commit comments

Comments
 (0)