SEC-1250: RequestHeaderPreAuthenticatedProcessingFilter cannot be use to fail back to another authentication type. Added exceptionIfHeaderMissing property.
This commit is contained in:
parent
e398922f85
commit
0da99171da
|
@ -11,12 +11,15 @@ import org.springframework.util.Assert;
|
|||
* As with most pre-authenticated scenarios, it is essential that the external authentication system is set up
|
||||
* correctly as this filter does no authentication whatsoever. All the protection is assumed to be provided externally
|
||||
* and if this filter is included inappropriately in a configuration, it would be possible to assume the
|
||||
* identity of a user merely by setting the correct header name. This also means it should not be used in combination
|
||||
* with other Spring Security authentication mechanisms such as form login, as this would imply there was a means of
|
||||
* bypassing the external system which would be risky.
|
||||
* identity of a user merely by setting the correct header name. This also means it should not generally be used
|
||||
* in combination with other Spring Security authentication mechanisms such as form login, as this would imply there
|
||||
* was a means of bypassing the external system which would be risky.
|
||||
* <p>
|
||||
* The property <tt>principalRequestHeader</tt> is the name of the request header that contains the username. It
|
||||
* defaults to "SM_USER" for compatibility with Siteminder.
|
||||
* <p>
|
||||
* If the header is missing from the request, <tt>getPreAuthenticatedPrincipal</tt> will throw an exception. You
|
||||
* can override this behaviour by setting the <tt>exceptionIfMissingHeader</tt> property.
|
||||
*
|
||||
*
|
||||
* @author Luke Taylor
|
||||
|
@ -26,16 +29,19 @@ import org.springframework.util.Assert;
|
|||
public class RequestHeaderAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
||||
private String principalRequestHeader = "SM_USER";
|
||||
private String credentialsRequestHeader;
|
||||
private boolean exceptionIfHeaderMissing = true;
|
||||
private boolean exceptionIfMissingHeader;
|
||||
|
||||
/**
|
||||
* Read and returns the header named by <tt>principalRequestHeader</tt> from the request.
|
||||
*
|
||||
* @throws PreAuthenticatedCredentialsNotFoundException if the header is missing
|
||||
* @throws PreAuthenticatedCredentialsNotFoundException if the header is missing and <tt>exceptionIfHeaderMissing</tt>
|
||||
* is set to <tt>true</tt>.
|
||||
*/
|
||||
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
|
||||
String principal = request.getHeader(principalRequestHeader);
|
||||
|
||||
if (principal == null) {
|
||||
if (principal == null && exceptionIfHeaderMissing) {
|
||||
throw new PreAuthenticatedCredentialsNotFoundException(principalRequestHeader
|
||||
+ " header not found in request.");
|
||||
}
|
||||
|
@ -66,4 +72,14 @@ public class RequestHeaderAuthenticationFilter extends AbstractPreAuthenticatedP
|
|||
Assert.hasText(credentialsRequestHeader, "credentialsRequestHeader must not be empty or null");
|
||||
this.credentialsRequestHeader = credentialsRequestHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines whether an exception should be raised if the principal header is missing. Defaults to <tt>true</tt>.
|
||||
*
|
||||
* @param exceptionIfHeaderMissing set to <tt>false</tt> to override the default behaviour and allow
|
||||
* the request to proceed if no header is found.
|
||||
*/
|
||||
public void setExceptionIfHeaderMissing(boolean exceptionIfHeaderMissing) {
|
||||
this.exceptionIfHeaderMissing = exceptionIfMissingHeader;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import org.springframework.security.web.authentication.preauth.RequestHeaderAuth
|
|||
* @author Luke Taylor
|
||||
* @version $Id$
|
||||
*/
|
||||
public class RequestHeaderPreAuthenticatedProcessingFilterTests {
|
||||
public class RequestHeaderAuthenticationFilterTests {
|
||||
|
||||
@After
|
||||
@Before
|
||||
|
@ -108,6 +108,28 @@ public class RequestHeaderPreAuthenticatedProcessingFilterTests {
|
|||
assertSame(dog, SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
@Test(expected=PreAuthenticatedCredentialsNotFoundException.class)
|
||||
public void missingHeaderCausesException() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
|
||||
filter.doFilter(request, response, chain);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingHeaderIsIgnoredIfExceptionIfHeaderMissingIsFalse() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter();
|
||||
filter.setExceptionIfHeaderMissing(false);
|
||||
filter.setAuthenticationManager(createAuthenticationManager());
|
||||
filter.doFilter(request, response, chain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an authentication manager which returns the passed in object.
|
||||
*/
|
Loading…
Reference in New Issue