From f90ccf149a598cb75ee6d39095f86ac563606323 Mon Sep 17 00:00:00 2001 From: Denis Angilella Date: Wed, 3 Aug 2016 10:27:40 +0200 Subject: [PATCH] Add property to stop filter chain after successful authentication --- .../SpnegoAuthenticationProcessingFilter.java | 19 +++++++++- ...egoAuthenticationProcessingFilterTest.java | 37 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/spring-security-kerberos-web/src/main/java/org/springframework/security/kerberos/web/authentication/SpnegoAuthenticationProcessingFilter.java b/spring-security-kerberos-web/src/main/java/org/springframework/security/kerberos/web/authentication/SpnegoAuthenticationProcessingFilter.java index e3a8456d..9357c62a 100644 --- a/spring-security-kerberos-web/src/main/java/org/springframework/security/kerberos/web/authentication/SpnegoAuthenticationProcessingFilter.java +++ b/spring-security-kerberos-web/src/main/java/org/springframework/security/kerberos/web/authentication/SpnegoAuthenticationProcessingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,6 +102,7 @@ * * @author Mike Wiesner * @author Jeremy Stone + * @author Denis Angilella * @since 1.0 * @see KerberosServiceAuthenticationProvider * @see SpnegoEntryPoint @@ -114,6 +115,7 @@ public class SpnegoAuthenticationProcessingFilter extends GenericFilterBean { private AuthenticationFailureHandler failureHandler; private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy(); private boolean skipIfAlreadyAuthenticated = true; + private boolean stopFilterChainOnSuccessfulAuthentication = false; @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { @@ -161,7 +163,9 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) if (successHandler != null) { successHandler.onAuthenticationSuccess(request, response, authentication); } - + if (stopFilterChainOnSuccessfulAuthentication) { + return; + } } chain.doFilter(request, response); @@ -244,4 +248,15 @@ public void setAuthenticationDetailsSource( this.authenticationDetailsSource = authenticationDetailsSource; } + /** + * If set to {@code false} (the default) and authentication is successful, the request will be processed by + * the next filter in the chain. If {@code true} and authentication is successful, the filter chain will stop here. + * + * @since 1.0.2 + * @param shouldStop set to {@code true} to prevent the next filter in the chain from processing the request + * after a successful authentication. + */ + public void setStopFilterChainOnSuccessfulAuthentication(boolean shouldStop) { + this.stopFilterChainOnSuccessfulAuthentication = shouldStop; + } } diff --git a/spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java b/spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java index 39c72e63..e0f19307 100644 --- a/spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java +++ b/spring-security-kerberos-web/src/test/java/org/springframework/security/kerberos/web/SpnegoAuthenticationProcessingFilterTest.java @@ -55,6 +55,7 @@ * * @author Mike Wiesner * @author Jeremy Stone + * @author Denis Angilella * @since 1.0 */ public class SpnegoAuthenticationProcessingFilterTest { @@ -127,21 +128,36 @@ public void testEverythingWorksWithHandlers_Kerberos() throws Exception { everythingWorksWithHandlers(TOKEN_PREFIX_KERB); } + @Test + public void testEverythingWorksWithHandlers_stopFilterChain() throws Exception { + filter.setStopFilterChainOnSuccessfulAuthentication(true); + + createHandler(); + everythingWorksStub(TOKEN_PREFIX_NEG); + + // testing + filter.doFilter(request, response, chain); + verify(chain, never()).doFilter(request, response); + assertEquals(AUTHENTICATION, SecurityContextHolder.getContext().getAuthentication()); + everythingWorksVerifyHandlers(); + } + private void everythingWorksWithHandlers(String tokenPrefix) throws Exception { createHandler(); everythingWorks(tokenPrefix); - verify(successHandler).onAuthenticationSuccess(request, response, AUTHENTICATION); - verify(failureHandler, never()).onAuthenticationFailure(any(HttpServletRequest.class), - any(HttpServletResponse.class), any(AuthenticationException.class)); + everythingWorksVerifyHandlers(); + } + + private void everythingWorksVerifyHandlers() throws Exception { + verify(successHandler).onAuthenticationSuccess(request, response, AUTHENTICATION); + verify(failureHandler, never()).onAuthenticationFailure(any(HttpServletRequest.class), + any(HttpServletResponse.class), any(AuthenticationException.class)); } private void everythingWorks(String tokenPrefix) throws IOException, ServletException { // stubbing - when(request.getHeader(HEADER)).thenReturn(tokenPrefix + TEST_TOKEN_BASE64); - KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(TEST_TOKEN); - requestToken.setDetails(detailsSource.buildDetails(request)); - when(authenticationManager.authenticate(requestToken)).thenReturn(AUTHENTICATION); + everythingWorksStub(tokenPrefix); // testing filter.doFilter(request, response, chain); @@ -149,6 +165,13 @@ private void everythingWorks(String tokenPrefix) throws IOException, assertEquals(AUTHENTICATION, SecurityContextHolder.getContext().getAuthentication()); } + private void everythingWorksStub(String tokenPrefix) throws IOException, ServletException { + when(request.getHeader(HEADER)).thenReturn(tokenPrefix + TEST_TOKEN_BASE64); + KerberosServiceRequestToken requestToken = new KerberosServiceRequestToken(TEST_TOKEN); + requestToken.setDetails(detailsSource.buildDetails(request)); + when(authenticationManager.authenticate(requestToken)).thenReturn(AUTHENTICATION); + } + @Test public void testNoHeader() throws Exception { filter.doFilter(request, response, chain);