Changed Basic Authentication consumer to setBasicAuth method
This commit changes the Basic Authentication Consumer<HttpHeaders> to a basic setBasicAuth(String, String) method. Issue: SPR-16913
This commit is contained in:
@@ -41,8 +41,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -710,6 +708,48 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the {@linkplain #AUTHORIZATION Authorization} header to
|
||||
* Basic Authentication based on the given username and password.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @since 5.1
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7617">RFC 7617</a>
|
||||
*/
|
||||
public void setBasicAuth(String username, String password) {
|
||||
setBasicAuth(username, password, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the {@linkplain #AUTHORIZATION Authorization} header to
|
||||
* Basic Authentication based on the given username and password.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @param charset the charset to use to convert the credentials into an octet sequence. Defaults
|
||||
* to {@linkplain StandardCharsets#ISO_8859_1 ISO-8859-1}
|
||||
* @since 5.1
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7617">RFC 7617</a>
|
||||
*/
|
||||
public void setBasicAuth(String username, String password, @Nullable Charset charset) {
|
||||
Assert.notNull(username, "Username must not be null");
|
||||
Assert.notNull(password, "Password must not be null");
|
||||
if (charset == null) {
|
||||
charset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
CharsetEncoder encoder = charset.newEncoder();
|
||||
if (!encoder.canEncode(username) || !encoder.canEncode(password)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Username or password contains characters that cannot be encoded to " +
|
||||
charset.displayName());
|
||||
}
|
||||
|
||||
String credentialsString = username + ":" + password;
|
||||
byte[] encodedBytes = Base64.getEncoder().encode(credentialsString.getBytes(charset));
|
||||
String encodedCredentials = new String(encodedBytes, charset);
|
||||
set(HttpHeaders.AUTHORIZATION, "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a configured {@link CacheControl} instance as the
|
||||
* new value of the {@code Cache-Control} header.
|
||||
@@ -1569,80 +1609,4 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
||||
return (headers.readOnly ? headers : new HttpHeaders(headers, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code HttpHeaders} consumer that adds Basic Authentication.
|
||||
* More specifically: a consumer that adds an {@linkplain #AUTHORIZATION
|
||||
* Authorization} header based on the given username and password.
|
||||
* Meant to be used in combination with
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec#headers(java.util.function.Consumer)}.
|
||||
* <p>Note that Basic Authentication only supports characters in the
|
||||
* {@linkplain StandardCharsets#ISO_8859_1 ISO-8859-1} character set.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @return a consumer that adds a Basic Authentication header
|
||||
* @since 5.1
|
||||
*/
|
||||
public static Consumer<HttpHeaders> basicAuthenticationConsumer(String username, String password) {
|
||||
return basicAuthenticationConsumer(() -> username, () -> password);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code HttpHeaders} consumer that adds Basic Authentication.
|
||||
* More specifically: a consumer that adds an {@linkplain #AUTHORIZATION
|
||||
* Authorization} header based on the given username and password
|
||||
* suppliers. Meant to be used in combination with
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec#headers(java.util.function.Consumer)}.
|
||||
* <p>Note that Basic Authentication only supports characters in the
|
||||
* {@linkplain StandardCharsets#ISO_8859_1 ISO-8859-1} character set.
|
||||
* @param usernameSupplier supplier for the username
|
||||
* @param passwordSupplier supplier for the password
|
||||
* @return a consumer that adds a Basic Authentication header
|
||||
* @since 5.1
|
||||
*/
|
||||
public static Consumer<HttpHeaders> basicAuthenticationConsumer(
|
||||
Supplier<String> usernameSupplier, Supplier<String> passwordSupplier) {
|
||||
|
||||
Assert.notNull(usernameSupplier, "Username Supplier must not be null");
|
||||
Assert.notNull(passwordSupplier, "Password Supplier must not be null");
|
||||
return new BasicAuthenticationConsumer(usernameSupplier, passwordSupplier);
|
||||
}
|
||||
|
||||
|
||||
private static class BasicAuthenticationConsumer implements Consumer<HttpHeaders> {
|
||||
|
||||
private final Supplier<String> usernameSupplier;
|
||||
|
||||
private final Supplier<String> passwordSupplier;
|
||||
|
||||
public BasicAuthenticationConsumer(Supplier<String> usernameSupplier, Supplier<String> passwordSupplier) {
|
||||
this.usernameSupplier = usernameSupplier;
|
||||
this.passwordSupplier = passwordSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(HttpHeaders httpHeaders) {
|
||||
String username = this.usernameSupplier.get();
|
||||
String password = this.passwordSupplier.get();
|
||||
Assert.state(username != null, "Supplied username is null");
|
||||
Assert.state(password != null, "Supplied password is null");
|
||||
checkIllegalCharacters(username, password);
|
||||
|
||||
String credentialsString = username + ":" + password;
|
||||
byte[] credentialBytes = credentialsString.getBytes(StandardCharsets.ISO_8859_1);
|
||||
byte[] encodedBytes = Base64.getEncoder().encode(credentialBytes);
|
||||
String encodedCredentials = new String(encodedBytes, StandardCharsets.ISO_8859_1);
|
||||
httpHeaders.set(HttpHeaders.AUTHORIZATION, "Basic " + encodedCredentials);
|
||||
}
|
||||
|
||||
private static void checkIllegalCharacters(String username, String password) {
|
||||
// Basic authentication only supports ISO 8859-1
|
||||
CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
|
||||
if (!encoder.canEncode(username) || !encoder.canEncode(password)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Username or password contains characters that cannot be encoded to ISO-8859-1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
@@ -532,22 +531,22 @@ public class HttpHeadersTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicAuthenticationConsumer() throws Exception {
|
||||
|
||||
public void basicAuth() {
|
||||
String username = "foo";
|
||||
String password = "bar";
|
||||
|
||||
Consumer<HttpHeaders> consumer =
|
||||
HttpHeaders.basicAuthenticationConsumer(username, password);
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
assertFalse(headers.containsKey(HttpHeaders.AUTHORIZATION));
|
||||
consumer.accept(headers);
|
||||
headers.setBasicAuth(username, password);
|
||||
String authorization = headers.getFirst(HttpHeaders.AUTHORIZATION);
|
||||
assertNotNull(authorization);
|
||||
assertTrue(authorization.startsWith("Basic "));
|
||||
byte[] result = Base64.getDecoder().decode(authorization.substring(6).getBytes(StandardCharsets.ISO_8859_1));
|
||||
assertEquals("foo:bar", new String(result, StandardCharsets.ISO_8859_1));
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void basicAuthIllegalChar() {
|
||||
String username = "foo";
|
||||
String password = "\u03BB";
|
||||
headers.setBasicAuth(username, password);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,9 @@ public abstract class ExchangeFilterFunctions {
|
||||
/**
|
||||
* Name of the {@linkplain ClientRequest#attributes() request attribute} that
|
||||
* contains the {@link Credentials} used by {@link #basicAuthentication()}.
|
||||
* @deprecated in favor of {@link HttpHeaders#setBasicAuth(String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE =
|
||||
ExchangeFilterFunctions.class.getName() + ".basicAuthenticationCredentials";
|
||||
|
||||
@@ -59,7 +61,9 @@ public abstract class ExchangeFilterFunctions {
|
||||
* @return the filter for basic authentication
|
||||
* @throws IllegalArgumentException if either {@code user} or
|
||||
* {@code password} contain characters that cannot be encoded to ISO-8859-1.
|
||||
* @deprecated in favor of {@link HttpHeaders#setBasicAuth(String, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static ExchangeFilterFunction basicAuthentication(String user, String password) {
|
||||
Assert.notNull(user, "'user' must not be null");
|
||||
Assert.notNull(password, "'password' must not be null");
|
||||
@@ -75,7 +79,9 @@ public abstract class ExchangeFilterFunctions {
|
||||
* @return the filter for basic authentication
|
||||
* @see #BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE
|
||||
* @see Credentials#basicAuthenticationCredentials(String, String)
|
||||
* @deprecated as of Spring 5.1, with no direct replacement
|
||||
*/
|
||||
@Deprecated
|
||||
public static ExchangeFilterFunction basicAuthentication() {
|
||||
return basicAuthenticationInternal(request ->
|
||||
request.attribute(BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE)
|
||||
@@ -134,7 +140,9 @@ public abstract class ExchangeFilterFunctions {
|
||||
* Stores user and password for HTTP basic authentication.
|
||||
* @see #basicAuthentication()
|
||||
* @see #basicAuthenticationCredentials(String, String)
|
||||
* @deprecated as of Spring 5.1, with no direct replacement
|
||||
*/
|
||||
@Deprecated
|
||||
public static final class Credentials {
|
||||
|
||||
private final String username;
|
||||
|
||||
@@ -27,12 +27,13 @@ import org.springframework.http.HttpStatus;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.http.HttpMethod.*;
|
||||
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.Credentials.*;
|
||||
import static org.springframework.http.HttpMethod.GET;
|
||||
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.Credentials.basicAuthenticationCredentials;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ExchangeFilterFunctionsTests {
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user