Skip to content

Commit ead3845

Browse files
committed
feat: Add option to specify a custom ServerAuthenticationConverter for x509()
Signed-off-by: blake_bauman <[email protected]>
1 parent 00ead7f commit ead3845

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3214,6 +3214,8 @@ public final class X509Spec {
32143214

32153215
private ReactiveAuthenticationManager authenticationManager;
32163216

3217+
private ServerAuthenticationConverter serverAuthenticationConverter;
3218+
32173219
private X509Spec() {
32183220
}
32193221

@@ -3227,11 +3229,17 @@ public X509Spec authenticationManager(ReactiveAuthenticationManager authenticati
32273229
return this;
32283230
}
32293231

3232+
public X509Spec serverAuthenticationConverter(ServerAuthenticationConverter serverAuthenticationConverter) {
3233+
this.serverAuthenticationConverter = serverAuthenticationConverter;
3234+
return this;
3235+
}
3236+
32303237
protected void configure(ServerHttpSecurity http) {
32313238
ReactiveAuthenticationManager authenticationManager = getAuthenticationManager();
32323239
X509PrincipalExtractor principalExtractor = getPrincipalExtractor();
3240+
ServerAuthenticationConverter converter = getServerAuthenticationConverter(principalExtractor);
32333241
AuthenticationWebFilter filter = new AuthenticationWebFilter(authenticationManager);
3234-
filter.setServerAuthenticationConverter(new ServerX509AuthenticationConverter(principalExtractor));
3242+
filter.setServerAuthenticationConverter(serverAuthenticationConverter);
32353243
http.addFilterAt(filter, SecurityWebFiltersOrder.AUTHENTICATION);
32363244
}
32373245

@@ -3250,6 +3258,13 @@ private ReactiveAuthenticationManager getAuthenticationManager() {
32503258
return new ReactivePreAuthenticatedAuthenticationManager(userDetailsService);
32513259
}
32523260

3261+
private ServerAuthenticationConverter getServerAuthenticationConverter(X509PrincipalExtractor extractor) {
3262+
if (this.serverAuthenticationConverter != null) {
3263+
return this.serverAuthenticationConverter;
3264+
}
3265+
return new ServerX509AuthenticationConverter(extractor);
3266+
}
3267+
32533268
}
32543269

32553270
public final class OAuth2LoginSpec {

config/src/test/java/org/springframework/security/config/web/server/ServerHttpSecurityTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.springframework.security.web.server.authentication.DelegatingServerAuthenticationSuccessHandler;
6161
import org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint;
6262
import org.springframework.security.web.server.authentication.HttpStatusServerEntryPoint;
63+
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
6364
import org.springframework.security.web.server.authentication.ServerAuthenticationFailureHandler;
6465
import org.springframework.security.web.server.authentication.ServerAuthenticationSuccessHandler;
6566
import org.springframework.security.web.server.authentication.ServerX509AuthenticationConverter;
@@ -497,6 +498,17 @@ public void x509WhenCustomizedThenAddsX509Filter() {
497498
assertThat(x509WebFilter).isNotNull();
498499
}
499500

501+
@Test
502+
public void x509WithConverterAndNoExtractorThenAddsX509Filter() {
503+
ServerAuthenticationConverter mockConverter = mock(ServerAuthenticationConverter.class);
504+
this.http.x509((x509) -> x509.serverAuthenticationConverter(mockConverter));
505+
SecurityWebFilterChain securityWebFilterChain = this.http.build();
506+
WebFilter x509WebFilter = securityWebFilterChain.getWebFilters()
507+
.filter(filter -> matchesX509Converter(filter, mockConverter))
508+
.blockFirst();
509+
assertThat(x509WebFilter).isNotNull();
510+
}
511+
500512
@Test
501513
public void addsX509FilterWhenX509AuthenticationIsConfiguredWithDefaults() {
502514
this.http.x509(withDefaults());
@@ -769,6 +781,17 @@ private boolean isX509Filter(WebFilter filter) {
769781
}
770782
}
771783

784+
private boolean matchesX509Converter(WebFilter filter, ServerAuthenticationConverter expectedConverter) {
785+
try {
786+
Object converter = ReflectionTestUtils.getField(filter, "authenticationConverter");
787+
return converter.equals(expectedConverter);
788+
}
789+
catch (IllegalArgumentException ex) {
790+
// field doesn't exist
791+
return false;
792+
}
793+
}
794+
772795
private <T extends WebFilter> Optional<T> getWebFilter(SecurityWebFilterChain filterChain, Class<T> filterClass) {
773796
return (Optional<T>) filterChain.getWebFilters()
774797
.filter(Objects::nonNull)

0 commit comments

Comments
 (0)