From dab989d7c31c5f588e27e07110c05a020d4a2880 Mon Sep 17 00:00:00 2001 From: Joe Grandja <10884212+jgrandja@users.noreply.github.com> Date: Thu, 5 Jun 2025 15:23:57 -0400 Subject: [PATCH] Fix NPE with DPoP tokenAuthenticationManager Closes gh-17172 --- .../DPoPAuthenticationConfigurer.java | 23 ++++++++++++++++++- .../OAuth2ResourceServerConfigurer.java | 4 ++++ .../OAuth2ResourceServerConfigurerTests.java | 5 +++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/DPoPAuthenticationConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/DPoPAuthenticationConfigurer.java index cee89e0427..771d6c6e99 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/DPoPAuthenticationConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/DPoPAuthenticationConfigurer.java @@ -29,6 +29,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.core.Authentication; @@ -51,6 +52,9 @@ import org.springframework.security.web.context.RequestAttributeSecurityContextR import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; /** * An {@link AbstractHttpConfigurer} for OAuth 2.0 Demonstrating Proof of Possession @@ -76,7 +80,7 @@ final class DPoPAuthenticationConfigurer> @Override public void configure(B http) { AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); - http.authenticationProvider(new DPoPAuthenticationProvider(authenticationManager)); + http.authenticationProvider(new DPoPAuthenticationProvider(getTokenAuthenticationManager(http))); AuthenticationFilter authenticationFilter = new AuthenticationFilter(authenticationManager, getAuthenticationConverter()); authenticationFilter.setRequestMatcher(getRequestMatcher()); @@ -87,6 +91,23 @@ final class DPoPAuthenticationConfigurer> http.addFilter(authenticationFilter); } + private AuthenticationManager getTokenAuthenticationManager(B http) { + OAuth2ResourceServerConfigurer resourceServerConfigurer = http + .getConfigurer(OAuth2ResourceServerConfigurer.class); + final AuthenticationManagerResolver authenticationManagerResolver = resourceServerConfigurer + .getAuthenticationManagerResolver(); + if (authenticationManagerResolver == null) { + return resourceServerConfigurer.getAuthenticationManager(http); + } + return (authentication) -> { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; + AuthenticationManager authenticationManager = authenticationManagerResolver + .resolve(servletRequestAttributes.getRequest()); + return authenticationManager.authenticate(authentication); + }; + } + private RequestMatcher getRequestMatcher() { if (this.requestMatcher == null) { this.requestMatcher = new DPoPRequestMatcher(); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java index e9a425d46d..5add89675f 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurer.java @@ -363,6 +363,10 @@ public final class OAuth2ResourceServerConfigurer getAuthenticationManagerResolver() { + return this.authenticationManagerResolver; + } + BearerTokenResolver getBearerTokenResolver() { if (this.bearerTokenResolver == null) { if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) { diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java index 6b263c7048..81b0a86498 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/server/resource/OAuth2ResourceServerConfigurerTests.java @@ -88,6 +88,7 @@ import org.springframework.security.config.annotation.method.configuration.Enabl import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.test.SpringTestContext; import org.springframework.security.config.test.SpringTestContextExtension; @@ -2532,7 +2533,9 @@ public class OAuth2ResourceServerConfigurerTests { // @formatter:off http .oauth2ResourceServer() - .authenticationManagerResolver(authenticationManagerResolver); + .authenticationManagerResolver(authenticationManagerResolver) + .and() + .anonymous(AbstractHttpConfigurer::disable); return http.build(); // @formatter:on }