Ver código fonte

Add Support for AuthenticationConverter

Closes gh-16793
Josh Cummings 5 meses atrás
pai
commit
8199015e79

+ 30 - 2
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<HttpServletRequest, ?> 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;
 	}