3131import org .springframework .context .MessageSourceAware ;
3232import org .springframework .context .support .MessageSourceAccessor ;
3333import org .springframework .core .log .LogMessage ;
34+ import org .springframework .security .authentication .AuthenticationCredentialsNotFoundException ;
3435import org .springframework .security .authentication .AuthenticationDetailsSource ;
3536import org .springframework .security .authentication .AuthenticationManager ;
3637import org .springframework .security .authentication .InternalAuthenticationServiceException ;
@@ -122,6 +123,11 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
122123
123124 protected AuthenticationDetailsSource <HttpServletRequest , ?> authenticationDetailsSource = new WebAuthenticationDetailsSource ();
124125
126+ private AuthenticationConverter authenticationConverter = (request ) -> {
127+ throw new AuthenticationCredentialsNotFoundException (
128+ "Please either configure an AuthenticationConverter or override attemptAuthentication when extending AbstractAuthenticationProcessingFilter" );
129+ };
130+
125131 private AuthenticationManager authenticationManager ;
126132
127133 protected MessageSourceAccessor messages = SpringSecurityMessageSource .getAccessor ();
@@ -132,6 +138,8 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
132138
133139 private boolean continueChainBeforeSuccessfulAuthentication = false ;
134140
141+ private boolean continueChainWhenNoAuthenticationResult ;
142+
135143 private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy ();
136144
137145 private boolean allowSessionCreation = true ;
@@ -230,6 +238,10 @@ private void doFilter(HttpServletRequest request, HttpServletResponse response,
230238 try {
231239 Authentication authenticationResult = attemptAuthentication (request , response );
232240 if (authenticationResult == null ) {
241+ if (this .continueChainWhenNoAuthenticationResult ) {
242+ chain .doFilter (request , response );
243+ return ;
244+ }
233245 // return immediately as subclass has indicated that it hasn't completed
234246 return ;
235247 }
@@ -292,8 +304,18 @@ protected boolean requiresAuthentication(HttpServletRequest request, HttpServlet
292304 * @return the authenticated user token, or null if authentication is incomplete.
293305 * @throws AuthenticationException if authentication fails.
294306 */
295- public abstract Authentication attemptAuthentication (HttpServletRequest request , HttpServletResponse response )
296- throws AuthenticationException , IOException , ServletException ;
307+ public Authentication attemptAuthentication (HttpServletRequest request , HttpServletResponse response )
308+ throws AuthenticationException , IOException , ServletException {
309+ Authentication authentication = this .authenticationConverter .convert (request );
310+ if (authentication == null ) {
311+ return null ;
312+ }
313+ Authentication result = this .authenticationManager .authenticate (authentication );
314+ if (result == null ) {
315+ throw new ServletException ("AuthenticationManager should not return null Authentication object." );
316+ }
317+ return result ;
318+ }
297319
298320 /**
299321 * Default behaviour for successful authentication.
@@ -354,6 +376,12 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServle
354376 this .failureHandler .onAuthenticationFailure (request , response , failed );
355377 }
356378
379+ public void setAuthenticationConverter (AuthenticationConverter authenticationConverter ) {
380+ Assert .notNull (authenticationConverter , "authenticationConverter cannot be null" );
381+ this .authenticationConverter = authenticationConverter ;
382+ this .continueChainWhenNoAuthenticationResult = true ;
383+ }
384+
357385 protected AuthenticationManager getAuthenticationManager () {
358386 return this .authenticationManager ;
359387 }
0 commit comments