Use configurable charset in ServerHttpBasicAuthenticationConverter
Closes gh-10903
This commit is contained in:
parent
428216b322
commit
2b6bc5dd0b
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.security.web.server;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -25,6 +27,7 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
|
@ -43,6 +46,8 @@ public class ServerHttpBasicAuthenticationConverter implements Function<ServerWe
|
|||
|
||||
public static final String BASIC = "Basic ";
|
||||
|
||||
private Charset credentialsCharset = StandardCharsets.UTF_8;
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Mono<Authentication> apply(ServerWebExchange exchange) {
|
||||
|
@ -51,9 +56,8 @@ public class ServerHttpBasicAuthenticationConverter implements Function<ServerWe
|
|||
if (!StringUtils.startsWithIgnoreCase(authorization, "basic ")) {
|
||||
return Mono.empty();
|
||||
}
|
||||
String credentials = (authorization.length() <= BASIC.length()) ? ""
|
||||
: authorization.substring(BASIC.length(), authorization.length());
|
||||
String decoded = new String(base64Decode(credentials));
|
||||
String credentials = (authorization.length() <= BASIC.length()) ? "" : authorization.substring(BASIC.length());
|
||||
String decoded = new String(base64Decode(credentials), this.credentialsCharset);
|
||||
String[] parts = decoded.split(":", 2);
|
||||
if (parts.length != 2) {
|
||||
return Mono.empty();
|
||||
|
@ -70,4 +74,13 @@ public class ServerHttpBasicAuthenticationConverter implements Function<ServerWe
|
|||
}
|
||||
}
|
||||
|
||||
public Charset getCredentialsCharset() {
|
||||
return this.credentialsCharset;
|
||||
}
|
||||
|
||||
public void setCredentialsCharset(Charset credentialsCharset) {
|
||||
Assert.notNull(credentialsCharset, "credentialsCharset cannot be null");
|
||||
this.credentialsCharset = credentialsCharset;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.security.web.server.authentication;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
@ -62,7 +64,7 @@ public class ServerHttpBasicAuthenticationConverterTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void applyWhenNoSemicolonThenEmpty() {
|
||||
public void applyWhenNoColonThenEmpty() {
|
||||
Mono<Authentication> result = apply(this.request.header(HttpHeaders.AUTHORIZATION, "Basic dXNlcg=="));
|
||||
assertThat(result.block()).isNull();
|
||||
}
|
||||
|
@ -104,6 +106,38 @@ public class ServerHttpBasicAuthenticationConverterTests {
|
|||
assertThat(result.block()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyWhenNonAsciiThenAuthentication() {
|
||||
Mono<Authentication> result = apply(
|
||||
this.request.header(HttpHeaders.AUTHORIZATION, "Basic w7xzZXI6cGFzc3fDtnJk"));
|
||||
UsernamePasswordAuthenticationToken authentication = result.cast(UsernamePasswordAuthenticationToken.class)
|
||||
.block();
|
||||
assertThat(authentication.getPrincipal()).isEqualTo("üser");
|
||||
assertThat(authentication.getCredentials()).isEqualTo("passwörd");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyWhenIsoOnlyAsciiThenAuthentication() {
|
||||
this.converter.setCredentialsCharset(StandardCharsets.ISO_8859_1);
|
||||
Mono<Authentication> result = apply(
|
||||
this.request.header(HttpHeaders.AUTHORIZATION, "Basic dXNlcjpwYXNzd29yZA=="));
|
||||
UsernamePasswordAuthenticationToken authentication = result.cast(UsernamePasswordAuthenticationToken.class)
|
||||
.block();
|
||||
assertThat(authentication.getPrincipal()).isEqualTo("user");
|
||||
assertThat(authentication.getCredentials()).isEqualTo("password");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applyWhenIsoNonAsciiThenAuthentication() {
|
||||
this.converter.setCredentialsCharset(StandardCharsets.ISO_8859_1);
|
||||
Mono<Authentication> result = apply(
|
||||
this.request.header(HttpHeaders.AUTHORIZATION, "Basic /HNlcjpwYXNzd/ZyZA=="));
|
||||
UsernamePasswordAuthenticationToken authentication = result.cast(UsernamePasswordAuthenticationToken.class)
|
||||
.block();
|
||||
assertThat(authentication.getPrincipal()).isEqualTo("üser");
|
||||
assertThat(authentication.getCredentials()).isEqualTo("passwörd");
|
||||
}
|
||||
|
||||
private Mono<Authentication> apply(MockServerHttpRequest.BaseBuilder<?> request) {
|
||||
return this.converter.convert(MockServerWebExchange.from(this.request.build()));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue