Skip to content

Commit 4cc4f35

Browse files
committed
Add RequestMatcher to AbstractPreAuthenticatedProcessingFilter
Moved the existing auth check logic to the matcher. Issue: gh-5928
1 parent 2307b01 commit 4cc4f35

File tree

2 files changed

+93
-34
lines changed

2 files changed

+93
-34
lines changed

web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.springframework.security.core.context.SecurityContextHolder;
3535
import org.springframework.security.web.WebAttributes;
3636
import org.springframework.security.web.authentication.*;
37+
import org.springframework.security.web.util.matcher.RequestMatcher;
3738
import org.springframework.util.Assert;
3839
import org.springframework.web.filter.GenericFilterBean;
3940

@@ -73,6 +74,7 @@
7374
* @author Luke Taylor
7475
* @author Ruud Senden
7576
* @author Rob Winch
77+
* @author Tadaya Tsuyukubo
7678
* @since 2.0
7779
*/
7880
public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFilterBean
@@ -86,6 +88,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
8688
private boolean invalidateSessionOnPrincipalChange = true;
8789
private AuthenticationSuccessHandler authenticationSuccessHandler = null;
8890
private AuthenticationFailureHandler authenticationFailureHandler = null;
91+
private RequestMatcher requiresAuthenticationRequestMatcher = new PreAuthenticatedProcessingRequestMatcher();
8992

9093
/**
9194
* Check whether all required properties have been set.
@@ -114,7 +117,7 @@ public void doFilter(ServletRequest request, ServletResponse response,
114117
+ SecurityContextHolder.getContext().getAuthentication());
115118
}
116119

117-
if (requiresAuthentication((HttpServletRequest) request)) {
120+
if (requiresAuthenticationRequestMatcher.matches((HttpServletRequest) request)) {
118121
doAuthenticate((HttpServletRequest) request, (HttpServletResponse) response);
119122
}
120123

@@ -193,39 +196,6 @@ private void doAuthenticate(HttpServletRequest request, HttpServletResponse resp
193196
}
194197
}
195198

196-
private boolean requiresAuthentication(HttpServletRequest request) {
197-
Authentication currentUser = SecurityContextHolder.getContext()
198-
.getAuthentication();
199-
200-
if (currentUser == null) {
201-
return true;
202-
}
203-
204-
if (!checkForPrincipalChanges) {
205-
return false;
206-
}
207-
208-
if (!principalChanged(request, currentUser)) {
209-
return false;
210-
}
211-
212-
logger.debug("Pre-authenticated principal has changed and will be reauthenticated");
213-
214-
if (invalidateSessionOnPrincipalChange) {
215-
SecurityContextHolder.clearContext();
216-
217-
HttpSession session = request.getSession(false);
218-
219-
if (session != null) {
220-
logger.debug("Invalidating existing session");
221-
session.invalidate();
222-
request.getSession();
223-
}
224-
}
225-
226-
return true;
227-
}
228-
229199
/**
230200
* Puts the <code>Authentication</code> instance returned by the authentication
231201
* manager into the secure context.
@@ -348,6 +318,14 @@ public void setAuthenticationFailureHandler(AuthenticationFailureHandler authent
348318
this.authenticationFailureHandler = authenticationFailureHandler;
349319
}
350320

321+
/**
322+
* Sets the request matcher to check whether to proceed the request further.
323+
*/
324+
public void setRequiresAuthenticationRequestMatcher(RequestMatcher requiresAuthenticationRequestMatcher) {
325+
Assert.notNull(requiresAuthenticationRequestMatcher, "requestMatcher cannot be null");
326+
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
327+
}
328+
351329
/**
352330
* Override to extract the principal information from the current request
353331
*/
@@ -359,4 +337,46 @@ public void setAuthenticationFailureHandler(AuthenticationFailureHandler authent
359337
* return a dummy value.
360338
*/
361339
protected abstract Object getPreAuthenticatedCredentials(HttpServletRequest request);
340+
341+
/**
342+
* Request matcher for default auth check logic
343+
*/
344+
private class PreAuthenticatedProcessingRequestMatcher implements RequestMatcher {
345+
346+
@Override
347+
public boolean matches(HttpServletRequest request) {
348+
349+
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
350+
351+
if (currentUser == null) {
352+
return true;
353+
}
354+
355+
if (!checkForPrincipalChanges) {
356+
return false;
357+
}
358+
359+
if (!principalChanged(request, currentUser)) {
360+
return false;
361+
}
362+
363+
logger.debug("Pre-authenticated principal has changed and will be reauthenticated");
364+
365+
if (invalidateSessionOnPrincipalChange) {
366+
SecurityContextHolder.clearContext();
367+
368+
HttpSession session = request.getSession(false);
369+
370+
if (session != null) {
371+
logger.debug("Invalidating existing session");
372+
session.invalidate();
373+
request.getSession();
374+
}
375+
}
376+
377+
return true;
378+
}
379+
380+
}
381+
362382
}

web/src/test/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilterTests.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@
4646
import org.springframework.security.web.WebAttributes;
4747
import org.springframework.security.web.authentication.ForwardAuthenticationFailureHandler;
4848
import org.springframework.security.web.authentication.ForwardAuthenticationSuccessHandler;
49+
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
4950

5051
/**
5152
*
5253
* @author Rob Winch
54+
* @author Tadaya Tsuyukubo
5355
*
5456
*/
5557
public class AbstractPreAuthenticatedProcessingFilterTests {
@@ -377,6 +379,43 @@ protected boolean principalChanged(HttpServletRequest request,
377379
verifyZeroInteractions(am);
378380
}
379381

382+
@Test
383+
public void requestNotMatchRequestMatcher() throws Exception {
384+
MockHttpServletRequest request = new MockHttpServletRequest();
385+
MockHttpServletResponse response = new MockHttpServletResponse();
386+
MockFilterChain chain = new MockFilterChain();
387+
388+
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
389+
filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/no-matching"));
390+
391+
AuthenticationManager am = mock(AuthenticationManager.class);
392+
filter.setAuthenticationManager(am);
393+
filter.afterPropertiesSet();
394+
395+
filter.doFilter(request, response, chain);
396+
397+
verifyZeroInteractions(am);
398+
}
399+
400+
@Test
401+
public void requestMatchesRequestMatcher() throws Exception {
402+
MockHttpServletRequest request = new MockHttpServletRequest();
403+
MockHttpServletResponse response = new MockHttpServletResponse();
404+
MockFilterChain chain = new MockFilterChain();
405+
406+
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
407+
filter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/**"));
408+
409+
AuthenticationManager am = mock(AuthenticationManager.class);
410+
filter.setAuthenticationManager(am);
411+
filter.afterPropertiesSet();
412+
413+
filter.doFilter(request, response, chain);
414+
415+
verify(am).authenticate(any(PreAuthenticatedAuthenticationToken.class));
416+
417+
}
418+
380419
private void testDoFilter(boolean grantAccess) throws Exception {
381420
MockHttpServletRequest req = new MockHttpServletRequest();
382421
MockHttpServletResponse res = new MockHttpServletResponse();

0 commit comments

Comments
 (0)