SEC-3051: Add AbstractPreAuthenticatedProcessingFilter#principalChanged
This commit is contained in:
parent
a50d297f3a
commit
92ae45a04d
|
@ -116,6 +116,40 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current principal has changed. The default implementation tries
|
||||
*
|
||||
* <ul>
|
||||
* <li>If the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is a String, the {@link Authentication#getName()} is compared against the pre authenticated principal</li>
|
||||
* <li>Otherwise, the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is compared against the {@link Authentication#getPrincipal()}
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Subclasses can override this method to determine when a principal has changed.
|
||||
* </p>
|
||||
*
|
||||
* @param request
|
||||
* @param currentAuthentication
|
||||
* @return true if the principal has changed, else false
|
||||
*/
|
||||
protected boolean principalChanged(HttpServletRequest request, Authentication currentAuthentication) {
|
||||
|
||||
Object principal = getPreAuthenticatedPrincipal(request);
|
||||
|
||||
if ((principal instanceof String) && currentAuthentication.getName().equals(principal)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (principal != null && principal.equals(currentAuthentication.getPrincipal())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("Pre-authenticated principal has changed to " + principal + " and will be reauthenticated");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actual authentication for a pre-authenticated user.
|
||||
*/
|
||||
|
@ -166,18 +200,11 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|||
return false;
|
||||
}
|
||||
|
||||
Object principal = getPreAuthenticatedPrincipal(request);
|
||||
|
||||
if ((principal instanceof String) && currentUser.getName().equals(principal)) {
|
||||
if(!principalChanged(request, currentUser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (principal != null && principal.equals(currentUser.getPrincipal())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.debug("Pre-authenticated principal has changed to " + principal
|
||||
+ " and will be reauthenticated");
|
||||
logger.debug("Pre-authenticated principal has changed and will be reauthenticated");
|
||||
|
||||
if (invalidateSessionOnPrincipalChange) {
|
||||
SecurityContextHolder.clearContext();
|
||||
|
|
|
@ -274,6 +274,60 @@ public class AbstractPreAuthenticatedProcessingFilterTests {
|
|||
verify(am).authenticate(any(PreAuthenticatedAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requiresAuthenticationOverridePrincipalChangedTrue() throws Exception {
|
||||
Object principal = new Object();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(principal, "something", "ROLE_USER"));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter() {
|
||||
@Override
|
||||
protected boolean principalChanged(HttpServletRequest request,
|
||||
Authentication currentAuthentication) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
filter.setCheckForPrincipalChanges(true);
|
||||
filter.principal = principal;
|
||||
AuthenticationManager am = mock(AuthenticationManager.class);
|
||||
filter.setAuthenticationManager(am);
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
filter.doFilter(request, response, chain);
|
||||
|
||||
verify(am).authenticate(any(PreAuthenticatedAuthenticationToken.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requiresAuthenticationOverridePrincipalChangedFalse() throws Exception {
|
||||
Object principal = new Object();
|
||||
SecurityContextHolder.getContext().setAuthentication(
|
||||
new TestingAuthenticationToken(principal, "something", "ROLE_USER"));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
|
||||
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter() {
|
||||
@Override
|
||||
protected boolean principalChanged(HttpServletRequest request,
|
||||
Authentication currentAuthentication) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
filter.setCheckForPrincipalChanges(true);
|
||||
filter.principal = principal;
|
||||
AuthenticationManager am = mock(AuthenticationManager.class);
|
||||
filter.setAuthenticationManager(am);
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
filter.doFilter(request, response, chain);
|
||||
|
||||
verifyZeroInteractions(am);
|
||||
}
|
||||
|
||||
private void testDoFilter(boolean grantAccess) throws Exception {
|
||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
|
|
Loading…
Reference in New Issue