From e8e0da1ec67a535dbcfa86b9054af22856288ce9 Mon Sep 17 00:00:00 2001 From: Ronny Perinke <23166289+sephiroth-j@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:22:06 +0100 Subject: [PATCH] Add Null Guard for Setting ReactiveUserDetailsPasswordService This use case specifically arises when using `ReactiveUserDetailsService` without `ReactiveUserDetailsPasswordService`. Closes gh-17986 Signed-off-by: Ronny Perinke <23166289+sephiroth-j@users.noreply.github.com> --- .../ServerHttpSecurityConfiguration.java | 4 +++- .../ServerHttpSecurityConfigurationTests.java | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java index a68f357fe7..60b9346059 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfiguration.java @@ -255,7 +255,9 @@ class ServerHttpSecurityConfiguration { if (this.passwordEncoder != null) { manager.setPasswordEncoder(this.passwordEncoder); } - manager.setUserDetailsPasswordService(this.userDetailsPasswordService); + if (this.userDetailsPasswordService != null) { + manager.setUserDetailsPasswordService(this.userDetailsPasswordService); + } manager.setCompromisedPasswordChecker(this.compromisedPasswordChecker); return this.postProcessor.postProcess(manager); } diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationTests.java index b68736ced4..fec27f57ef 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/reactive/ServerHttpSecurityConfigurationTests.java @@ -107,7 +107,7 @@ public class ServerHttpSecurityConfigurationTests { } @Test - public void loadConfigWhenReactiveUserDetailsServiceConfiguredThenServerHttpSecurityExists() { + public void loadConfigWhenReactiveUserAuthenticationServiceConfiguredThenServerHttpSecurityExists() { this.spring .register(ServerHttpSecurityConfiguration.class, ReactiveAuthenticationTestConfiguration.class, WebFluxSecurityConfiguration.class) @@ -116,6 +116,16 @@ public class ServerHttpSecurityConfigurationTests { assertThat(serverHttpSecurity).isNotNull(); } + @Test + public void loadConfigWhenOnlyReactiveUserDetailsServiceConfiguredThenServerHttpSecurityExists() { + this.spring + .register(ServerHttpSecurityConfiguration.class, ReactiveUserDetailsServiceOnlyTestConfiguration.class, + WebFluxSecurityConfiguration.class) + .autowire(); + ServerHttpSecurity serverHttpSecurity = this.spring.getContext().getBean(ServerHttpSecurity.class); + assertThat(serverHttpSecurity).isNotNull(); + } + @Test public void loadConfigWhenProxyingEnabledAndSubclassThenServerHttpSecurityExists() { this.spring @@ -581,4 +591,14 @@ public class ServerHttpSecurityConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class ReactiveUserDetailsServiceOnlyTestConfiguration { + + @Bean + static ReactiveUserDetailsService userDetailsService() { + return (username) -> Mono.just(PasswordEncodedUser.user()); + } + + } + }