SEC-2296: HttpServletRequest.login should throw ServletException if already authenticated

See throws documentation at
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#login%28java.lang.String,%20java.lang.String%29
This commit is contained in:
Rob Winch 2013-08-31 11:55:24 -05:00
parent e8ac11641b
commit 8e74407381
2 changed files with 29 additions and 3 deletions

View File

@ -162,8 +162,7 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
logger.debug("authenticationEntryPoint is null, so allowing original HttpServletRequest to handle authenticate"); logger.debug("authenticationEntryPoint is null, so allowing original HttpServletRequest to handle authenticate");
return super.authenticate(response); return super.authenticate(response);
} }
Principal userPrincipal = getUserPrincipal(); if(isAuthenticated()) {
if(userPrincipal != null) {
return true; return true;
} }
entryPoint.commence(this, response, new AuthenticationCredentialsNotFoundException("User is not Authenticated")); entryPoint.commence(this, response, new AuthenticationCredentialsNotFoundException("User is not Authenticated"));
@ -171,6 +170,11 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
} }
public void login(String username, String password) throws ServletException { public void login(String username, String password) throws ServletException {
if(isAuthenticated()) {
throw new ServletException("Cannot perform login for '"
+ username + "' already authenticated as '"
+ getRemoteUser() + "'");
}
AuthenticationManager authManager = authenticationManager; AuthenticationManager authManager = authenticationManager;
if(authManager == null) { if(authManager == null) {
logger.debug("authenticationManager is null, so allowing original HttpServletRequest to handle login"); logger.debug("authenticationManager is null, so allowing original HttpServletRequest to handle login");
@ -199,6 +203,11 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
logoutHandler.logout(this, response, authentication); logoutHandler.logout(this, response, authentication);
} }
} }
private boolean isAuthenticated() {
Principal userPrincipal = getUserPrincipal();
return userPrincipal != null;
}
} }
private static class SecurityContextAsyncContext implements AsyncContext { private static class SecurityContextAsyncContext implements AsyncContext {

View File

@ -16,6 +16,7 @@
package org.springframework.security.web.servletapi; package org.springframework.security.web.servletapi;
import static junit.framework.Assert.fail;
import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
@ -172,11 +173,27 @@ public class SecurityContextHolderAwareRequestFilterTests {
verify(request, times(0)).login(anyString(),anyString()); verify(request, times(0)).login(anyString(),anyString());
} }
// SEC-2296
@Test
public void loginWithExstingUser() throws Exception {
TestingAuthenticationToken expectedAuth = new TestingAuthenticationToken("user", "password","ROLE_USER");
when(authenticationManager.authenticate(any(UsernamePasswordAuthenticationToken.class))).thenReturn(new TestingAuthenticationToken("newuser","not be found","ROLE_USER"));
SecurityContextHolder.getContext().setAuthentication(expectedAuth);
try {
wrappedRequest().login(expectedAuth.getName(),String.valueOf(expectedAuth.getCredentials()));
fail("Expected Exception");
} catch(ServletException success) {
assertThat(SecurityContextHolder.getContext().getAuthentication()).isSameAs(expectedAuth);
verifyZeroInteractions(authenticationEntryPoint, logoutHandler);
verify(request, times(0)).login(anyString(),anyString());
}
}
@Test @Test
public void loginFail() throws Exception { public void loginFail() throws Exception {
AuthenticationException authException = new BadCredentialsException("Invalid"); AuthenticationException authException = new BadCredentialsException("Invalid");
when(authenticationManager.authenticate(any(UsernamePasswordAuthenticationToken.class))).thenThrow(authException); when(authenticationManager.authenticate(any(UsernamePasswordAuthenticationToken.class))).thenThrow(authException);
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("should","be cleared","ROLE_USER"));
try { try {
wrappedRequest().login("invalid","credentials"); wrappedRequest().login("invalid","credentials");