From 8199015e79fe5e18a191690cd31596fc048738d0 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Thu, 20 Mar 2025 17:14:35 -0600 Subject: [PATCH] Add Support for AuthenticationConverter Closes gh-16793 --- ...bstractAuthenticationProcessingFilter.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java index af9b55f708..51776fb0b2 100644 --- a/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java +++ b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java @@ -31,6 +31,7 @@ import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.support.MessageSourceAccessor; import org.springframework.core.log.LogMessage; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.InternalAuthenticationServiceException; @@ -122,6 +123,11 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource(); + private AuthenticationConverter authenticationConverter = (request) -> { + throw new AuthenticationCredentialsNotFoundException( + "Please either configure an AuthenticationConverter or override attemptAuthentication when extending AbstractAuthenticationProcessingFilter"); + }; + private AuthenticationManager authenticationManager; protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); @@ -132,6 +138,8 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt private boolean continueChainBeforeSuccessfulAuthentication = false; + private boolean continueChainWhenNoAuthenticationResult; + private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy(); private boolean allowSessionCreation = true; @@ -230,6 +238,10 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt try { Authentication authenticationResult = attemptAuthentication(request, response); if (authenticationResult == null) { + if (this.continueChainWhenNoAuthenticationResult) { + chain.doFilter(request, response); + return; + } // return immediately as subclass has indicated that it hasn't completed return; } @@ -292,8 +304,18 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt * @return the authenticated user token, or null if authentication is incomplete. * @throws AuthenticationException if authentication fails. */ - public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) - throws AuthenticationException, IOException, ServletException; + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) + throws AuthenticationException, IOException, ServletException { + Authentication authentication = this.authenticationConverter.convert(request); + if (authentication == null) { + return null; + } + Authentication result = this.authenticationManager.authenticate(authentication); + if (result == null) { + throw new ServletException("AuthenticationManager should not return null Authentication object."); + } + return result; + } /** * Default behaviour for successful authentication. @@ -354,6 +376,12 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt this.failureHandler.onAuthenticationFailure(request, response, failed); } + public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) { + Assert.notNull(authenticationConverter, "authenticationConverter cannot be null"); + this.authenticationConverter = authenticationConverter; + this.continueChainWhenNoAuthenticationResult = true; + } + protected AuthenticationManager getAuthenticationManager() { return this.authenticationManager; }