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);
|
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.
|
* Do the actual authentication for a pre-authenticated user.
|
||||||
*/
|
*/
|
||||||
|
@ -166,18 +200,11 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object principal = getPreAuthenticatedPrincipal(request);
|
if(!principalChanged(request, currentUser)) {
|
||||||
|
|
||||||
if ((principal instanceof String) && currentUser.getName().equals(principal)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (principal != null && principal.equals(currentUser.getPrincipal())) {
|
logger.debug("Pre-authenticated principal has changed and will be reauthenticated");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug("Pre-authenticated principal has changed to " + principal
|
|
||||||
+ " and will be reauthenticated");
|
|
||||||
|
|
||||||
if (invalidateSessionOnPrincipalChange) {
|
if (invalidateSessionOnPrincipalChange) {
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
|
|
|
@ -274,6 +274,60 @@ public class AbstractPreAuthenticatedProcessingFilterTests {
|
||||||
verify(am).authenticate(any(PreAuthenticatedAuthenticationToken.class));
|
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 {
|
private void testDoFilter(boolean grantAccess) throws Exception {
|
||||||
MockHttpServletRequest req = new MockHttpServletRequest();
|
MockHttpServletRequest req = new MockHttpServletRequest();
|
||||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||||
|
|
Loading…
Reference in New Issue