SEC-1125: Created separate web module spring-security-web

This commit is contained in:
Luke Taylor
2009-03-25 06:28:18 +00:00
parent 2c985a1c36
commit 2a9a8a41db
247 changed files with 611 additions and 506 deletions

View File

@@ -0,0 +1,50 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.ui.AuthenticationEntryPoint;
/**
* Performs a HTTP redirect to the constructor-indicated URL.
*
* @author Ben Alex
* @version $Id$
*/
public class MockAuthenticationEntryPoint implements AuthenticationEntryPoint {
//~ Instance fields ================================================================================================
private String url;
//~ Constructors ===================================================================================================
public MockAuthenticationEntryPoint(String url) {
this.url = url;
}
//~ Methods ========================================================================================================
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authenticationException) throws IOException, ServletException {
response.sendRedirect(request.getContextPath() + url);
}
}

View File

@@ -0,0 +1,63 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
/**
*
* @author Ben Alex
* @version $Id$
*/
@SuppressWarnings("unchecked")
public class MockFilterConfig implements FilterConfig {
//~ Instance fields ================================================================================================
private Map map = new HashMap();
//~ Methods ========================================================================================================
public String getFilterName() {
throw new UnsupportedOperationException("mock method not implemented");
}
public String getInitParameter(String arg0) {
Object result = map.get(arg0);
if (result != null) {
return (String) result;
} else {
return null;
}
}
public Enumeration getInitParameterNames() {
throw new UnsupportedOperationException("mock method not implemented");
}
public ServletContext getServletContext() {
throw new UnsupportedOperationException("mock method not implemented");
}
public void setInitParmeter(String parameter, String value) {
map.put(parameter, value);
}
}

View File

@@ -0,0 +1,51 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security;
import org.springframework.security.web.util.PortResolver;
import javax.servlet.ServletRequest;
/**
* Always returns the constructor-specified HTTP and HTTPS ports.
*
* @author Ben Alex
* @version $Id$
*/
public class MockPortResolver implements PortResolver {
//~ Instance fields ================================================================================================
private int http = 80;
private int https = 443;
//~ Constructors ===================================================================================================
public MockPortResolver(int http, int https) {
this.http = http;
this.https = https;
}
//~ Methods ========================================================================================================
public int getServerPort(ServletRequest request) {
if ((request.getScheme() != null) && request.getScheme().equals("https")) {
return https;
} else {
return http;
}
}
}

View File

@@ -0,0 +1,123 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.WebAuthenticationDetails;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
/**
* Tests {@link ConcurrentSessionControllerImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class ConcurrentSessionControllerImplTests extends TestCase {
//~ Methods ========================================================================================================
private Authentication createAuthentication(String user, String password) {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, password);
auth.setDetails(createWebDetails(auth));
return auth;
}
private WebAuthenticationDetails createWebDetails(Authentication auth) {
MockHttpSession session = new MockHttpSession();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setSession(session);
request.setUserPrincipal(auth);
return new WebAuthenticationDetails(request);
}
public void testLifecycle() throws Exception {
// Build a test fixture
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
SessionRegistry registry = new SessionRegistryImpl();
sc.setSessionRegistry(registry);
// Attempt to authenticate - it should be successful
Authentication auth = createAuthentication("bob", "1212");
sc.checkAuthenticationAllowed(auth);
sc.registerSuccessfulAuthentication(auth);
String sessionId1 = ((WebAuthenticationDetails) auth.getDetails()).getSessionId();
assertFalse(registry.getSessionInformation(sessionId1).isExpired());
// Attempt to authenticate again - it should still be successful
sc.checkAuthenticationAllowed(auth);
sc.registerSuccessfulAuthentication(auth);
// Attempt to authenticate with a different session for same principal - should fail
sc.setExceptionIfMaximumExceeded(true);
Authentication auth2 = createAuthentication("bob", "1212");
assertFalse(registry.getSessionInformation(sessionId1).isExpired());
try {
sc.checkAuthenticationAllowed(auth2);
fail("Should have thrown ConcurrentLoginException");
} catch (ConcurrentLoginException expected) {
assertTrue(true);
}
// Attempt to authenticate with a different session for same principal - should expire first session
sc.setExceptionIfMaximumExceeded(false);
Authentication auth3 = createAuthentication("bob", "1212");
sc.checkAuthenticationAllowed(auth3);
sc.registerSuccessfulAuthentication(auth3);
String sessionId3 = ((WebAuthenticationDetails) auth3.getDetails()).getSessionId();
assertTrue(registry.getSessionInformation(sessionId1).isExpired());
assertFalse(registry.getSessionInformation(sessionId3).isExpired());
}
public void testStartupDetectsInvalidMaximumSessions()
throws Exception {
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
sc.setMaximumSessions(0);
try {
sc.afterPropertiesSet();
fail("Should have thrown IAE");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testStartupDetectsInvalidSessionRegistry()
throws Exception {
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
sc.setSessionRegistry(null);
try {
sc.afterPropertiesSet();
fail("Should have thrown IAE");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
}

View File

@@ -0,0 +1,165 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import junit.framework.TestCase;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
import java.util.Date;
/**
* Tests {@link ConcurrentSessionFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class ConcurrentSessionFilterTests extends TestCase {
//~ Constructors ===================================================================================================
public ConcurrentSessionFilterTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
public void testDetectsExpiredSessions() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpSession session = new MockHttpSession();
request.setSession(session);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will not be invoked, as we redirect to expiredUrl
MockFilterChain chain = new MockFilterChain(false);
// Setup our test fixture and registry to want this session to be expired
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
SessionRegistry registry = new SessionRegistryImpl();
registry.registerNewSession(session.getId(), "principal");
registry.getSessionInformation(session.getId()).expireNow();
filter.setSessionRegistry(registry);
filter.setExpiredUrl("/expired.jsp");
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/expired.jsp", response.getRedirectedUrl());
}
// As above, but with no expiredUrl set.
public void testReturnsExpectedMessageWhenNoExpiredUrlSet() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpSession session = new MockHttpSession();
request.setSession(session);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(false);
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
SessionRegistry registry = new SessionRegistryImpl();
registry.registerNewSession(session.getId(), "principal");
registry.getSessionInformation(session.getId()).expireNow();
filter.setSessionRegistry(registry);
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("This session has been expired (possibly due to multiple concurrent logins being " +
"attempted as the same user).", response.getContentAsString());
}
public void testDetectsMissingSessionRegistry() throws Exception {
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
filter.setExpiredUrl("xcx");
try {
filter.afterPropertiesSet();
fail("Should have thrown IAE");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testUpdatesLastRequestTime() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpSession session = new MockHttpSession();
request.setSession(session);
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will be invoked, as our session hasn't expired
MockFilterChain chain = new MockFilterChain(true);
// Setup our test fixture
ConcurrentSessionFilter filter = new ConcurrentSessionFilter();
SessionRegistry registry = new SessionRegistryImpl();
registry.registerNewSession(session.getId(), "principal");
Date lastRequest = registry.getSessionInformation(session.getId()).getLastRequest();
filter.setSessionRegistry(registry);
filter.setExpiredUrl("/expired.jsp");
Thread.sleep(1000);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertTrue(registry.getSessionInformation(session.getId()).getLastRequest().after(lastRequest));
}
//~ Inner Classes ==================================================================================================
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
}

View File

@@ -0,0 +1,48 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import junit.framework.TestCase;
import java.util.Date;
/**
* Tests {@link SessionInformation}.
*
* @author Ben Alex
* @version $Id$
*/
public class SessionInformationTests extends TestCase {
//~ Methods ========================================================================================================
public void testObject() throws Exception {
Object principal = "Some principal object";
String sessionId = "1234567890";
Date currentDate = new Date();
SessionInformation info = new SessionInformation(principal, sessionId, currentDate);
assertEquals(principal, info.getPrincipal());
assertEquals(sessionId, info.getSessionId());
assertEquals(currentDate, info.getLastRequest());
Thread.sleep(1000);
info.refreshLastRequest();
assertTrue(info.getLastRequest().after(currentDate));
}
}

View File

@@ -0,0 +1,167 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.concurrent;
import junit.framework.TestCase;
import org.springframework.security.ui.session.HttpSessionDestroyedEvent;
import org.springframework.mock.web.MockHttpSession;
import java.util.Date;
/**
* Tests {@link SessionRegistryImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class SessionRegistryImplTests extends TestCase {
private SessionRegistryImpl sessionRegistry;
//~ Methods ========================================================================================================
protected void setUp() throws Exception {
sessionRegistry = new SessionRegistryImpl();
}
public void testEventPublishing() {
MockHttpSession httpSession = new MockHttpSession();
Object principal = "Some principal object";
String sessionId = httpSession.getId();
assertNotNull(sessionId);
// Register new Session
sessionRegistry.registerNewSession(sessionId, principal);
// Deregister session via an ApplicationEvent
sessionRegistry.onApplicationEvent(new HttpSessionDestroyedEvent(httpSession));
// Check attempts to retrieve cleared session return null
assertNull(sessionRegistry.getSessionInformation(sessionId));
}
public void testMultiplePrincipals() throws Exception {
Object principal1 = "principal_1";
Object principal2 = "principal_2";
String sessionId1 = "1234567890";
String sessionId2 = "9876543210";
String sessionId3 = "5432109876";
sessionRegistry.registerNewSession(sessionId1, principal1);
sessionRegistry.registerNewSession(sessionId2, principal1);
sessionRegistry.registerNewSession(sessionId3, principal2);
assertEquals(principal1, sessionRegistry.getAllPrincipals()[0]);
assertEquals(principal2, sessionRegistry.getAllPrincipals()[1]);
}
public void testSessionInformationLifecycle() throws Exception {
Object principal = "Some principal object";
String sessionId = "1234567890";
// Register new Session
sessionRegistry.registerNewSession(sessionId, principal);
// Retrieve existing session by session ID
Date currentDateTime = sessionRegistry.getSessionInformation(sessionId).getLastRequest();
assertEquals(principal, sessionRegistry.getSessionInformation(sessionId).getPrincipal());
assertEquals(sessionId, sessionRegistry.getSessionInformation(sessionId).getSessionId());
assertNotNull(sessionRegistry.getSessionInformation(sessionId).getLastRequest());
// Retrieve existing session by principal
assertEquals(1, sessionRegistry.getAllSessions(principal, false).length);
// Sleep to ensure SessionRegistryImpl will update time
Thread.sleep(1000);
// Update request date/time
sessionRegistry.refreshLastRequest(sessionId);
Date retrieved = sessionRegistry.getSessionInformation(sessionId).getLastRequest();
assertTrue(retrieved.after(currentDateTime));
// Check it retrieves correctly when looked up via principal
assertEquals(retrieved, sessionRegistry.getAllSessions(principal, false)[0].getLastRequest());
// Clear session information
sessionRegistry.removeSessionInformation(sessionId);
// Check attempts to retrieve cleared session return null
assertNull(sessionRegistry.getSessionInformation(sessionId));
assertNull(sessionRegistry.getAllSessions(principal, false));
}
public void testTwoSessionsOnePrincipalExpiring() throws Exception {
Object principal = "Some principal object";
String sessionId1 = "1234567890";
String sessionId2 = "9876543210";
sessionRegistry.registerNewSession(sessionId1, principal);
SessionInformation[] sessions = sessionRegistry.getAllSessions(principal, false);
assertEquals(1, sessions.length);
assertTrue(contains(sessionId1, principal));
sessionRegistry.registerNewSession(sessionId2, principal);
sessions = sessionRegistry.getAllSessions(principal, false);
assertEquals(2, sessions.length);
assertTrue(contains(sessionId2, principal));
// Expire one session
SessionInformation session = sessionRegistry.getSessionInformation(sessionId2);
session.expireNow();
// Check retrieval still correct
assertTrue(sessionRegistry.getSessionInformation(sessionId2).isExpired());
assertFalse(sessionRegistry.getSessionInformation(sessionId1).isExpired());
}
public void testTwoSessionsOnePrincipalHandling() throws Exception {
Object principal = "Some principal object";
String sessionId1 = "1234567890";
String sessionId2 = "9876543210";
sessionRegistry.registerNewSession(sessionId1, principal);
SessionInformation[] sessions = sessionRegistry.getAllSessions(principal, false);
assertEquals(1, sessions.length);
assertTrue(contains(sessionId1, principal));
sessionRegistry.registerNewSession(sessionId2, principal);
sessions = sessionRegistry.getAllSessions(principal, false);
assertEquals(2, sessions.length);
assertTrue(contains(sessionId2, principal));
sessionRegistry.removeSessionInformation(sessionId1);
sessions = sessionRegistry.getAllSessions(principal, false);
assertEquals(1, sessions.length);
assertTrue(contains(sessionId2, principal));
sessionRegistry.removeSessionInformation(sessionId2);
assertNull(sessionRegistry.getSessionInformation(sessionId2));
assertNull(sessionRegistry.getAllSessions(principal, false));
}
boolean contains(String sessionId, Object principal) {
SessionInformation[] info = sessionRegistry.getAllSessions(principal, false);
for (int i = 0; i < info.length; i++) {
if (sessionId.equals(info[i].getSessionId())) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,306 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.context.web;
import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.MockFilterConfig;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Tests {@link HttpSessionContextIntegrationFilter}.
*
* @author Ben Alex
* @version $Id$
*/
@SuppressWarnings("deprecation")
public class HttpSessionContextIntegrationFilterTests extends TestCase {
// Build an Authentication object we simulate came from HttpSession
private UsernamePasswordAuthenticationToken sessionPrincipal = new UsernamePasswordAuthenticationToken(
"someone",
"password",
AuthorityUtils.createAuthorityList("SOME_ROLE"));
//~ Methods ========================================================================================================
private static void executeFilterInContainerSimulator(
FilterConfig filterConfig, Filter filter, ServletRequest request,
ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
public void testDetectsIncompatibleSessionProperties() throws Exception {
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
try {
filter.setAllowSessionCreation(false);
filter.setForceEagerSessionCreation(true);
filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
filter.setAllowSessionCreation(true);
filter.afterPropertiesSet();
assertTrue(true);
}
public void testDetectsMissingOrInvalidContext() throws Exception {
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
try {
filter.setContextClass(null);
filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
try {
filter.setContextClass(Integer.class);
assertEquals(Integer.class, filter.getContextClass());
filter.afterPropertiesSet();
fail("Shown have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testExceptionWithinFilterChainStillClearsSecurityContextHolder() throws Exception {
// Build a Context to store in HttpSession (simulating prior request)
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(sessionPrincipal);
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession().setAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY,
sc);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(sessionPrincipal, null,
new IOException());
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
try {
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
fail("We should have received the IOException thrown inside the filter chain here");
} catch (IOException ioe) {
assertTrue(true);
}
// Check the SecurityContextHolder is null, even though an exception was
// thrown during chain
assertEquals(new SecurityContextImpl(), SecurityContextHolder.getContext());
assertNull("Should have cleared FILTER_APPLIED",
request.getAttribute(HttpSessionContextIntegrationFilter.FILTER_APPLIED));
}
public void testExistingContextContentsCopiedIntoContextHolderFromSessionAndChangesToContextCopiedBackToSession()
throws Exception {
// Build an Authentication object we simulate came from HttpSession
UsernamePasswordAuthenticationToken updatedPrincipal = new UsernamePasswordAuthenticationToken(
"someone",
"password",
AuthorityUtils.createAuthorityList("SOME_DIFFERENT_ROLE"));
// Build a Context to store in HttpSession (simulating prior request)
SecurityContext sc = new SecurityContextImpl();
sc.setAuthentication(sessionPrincipal);
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession().setAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY,
sc);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(sessionPrincipal,
updatedPrincipal, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Obtain new/update Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession().getAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
}
public void testHttpSessionCreatedWhenContextHolderChanges() throws Exception {
// Build an Authentication object we simulate our Authentication changed it to
UsernamePasswordAuthenticationToken updatedPrincipal = new UsernamePasswordAuthenticationToken(
"someone",
"password",
AuthorityUtils.createAuthorityList("SOME_ROLE"));
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
// don't call afterPropertiesSet to test case when Spring filter.afterPropertiesSet(); isn't called
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
// Obtain new/updated Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession(false).getAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
}
public void testHttpSessionEagerlyCreatedWhenDirected() throws Exception {
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, null, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
filter.setForceEagerSessionCreation(true); // non-default
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Check the session is not null
assertNotNull(request.getSession(false));
}
public void testHttpSessionNotCreatedUnlessContextHolderChanges() throws Exception {
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, null, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter,
request, response, chain);
// Check the session is null
assertNull(request.getSession(false));
}
public void testHttpSessionWithNonContextInWellKnownLocationIsOverwritten() throws Exception {
// Build an Authentication object we simulate our Authentication changed it to
UsernamePasswordAuthenticationToken updatedPrincipal = new UsernamePasswordAuthenticationToken(
"someone",
"password",
AuthorityUtils.createAuthorityList("SOME_DIFFERENT_ROLE"));
// Build a mock request
MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession().setAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY,
"NOT_A_CONTEXT_OBJECT");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = new MockFilterChain(null, updatedPrincipal, null);
// Prepare filter
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
filter.setContextClass(SecurityContextImpl.class);
filter.afterPropertiesSet();
// Execute filter
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
// Obtain new/update Authentication from HttpSession
SecurityContext context = (SecurityContext) request.getSession().getAttribute(
HttpSessionContextIntegrationFilter.SPRING_SECURITY_CONTEXT_KEY);
assertEquals(updatedPrincipal, ((SecurityContext) context).getAuthentication());
}
//~ Inner Classes ==================================================================================================
private class MockFilterChain extends TestCase implements FilterChain {
private Authentication changeContextHolder;
private Authentication expectedOnContextHolder;
private IOException toThrowDuringChain;
public MockFilterChain(Authentication expectedOnContextHolder,
Authentication changeContextHolder,
IOException toThrowDuringChain) {
this.expectedOnContextHolder = expectedOnContextHolder;
this.changeContextHolder = changeContextHolder;
this.toThrowDuringChain = toThrowDuringChain;
}
public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException {
if (expectedOnContextHolder != null) {
assertEquals(expectedOnContextHolder, SecurityContextHolder.getContext().getAuthentication());
}
if (changeContextHolder != null) {
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(changeContextHolder);
SecurityContextHolder.setContext(sc);
}
if (toThrowDuringChain != null) {
throw toThrowDuringChain;
}
}
}
}

View File

@@ -0,0 +1,227 @@
package org.springframework.security.context.web;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
public class HttpSessionSecurityContextRepositoryTests {
private final TestingAuthenticationToken testToken = new TestingAuthenticationToken("someone", "passwd", "ROLE_A");
@Test(expected=IllegalArgumentException.class)
public void detectsInvalidContextClass() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setSecurityContextClass(String.class);
}
@Test(expected=IllegalArgumentException.class)
public void cannotSetNullContextClass() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setSecurityContextClass(null);
}
@Test
public void sessionIsntCreatedIfContextDoesntChange() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext context = repo.loadContext(holder);
assertNull(request.getSession(false));
repo.saveContext(context, holder.getRequest(), holder.getResponse());
assertNull(request.getSession(false));
}
@Test
public void sessionIsntCreatedIfAllowSessionCreationIsFalse() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setAllowSessionCreation(false);
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext context = repo.loadContext(holder);
// Change context
context.setAuthentication(testToken);
repo.saveContext(context, holder.getRequest(), holder.getResponse());
assertNull(request.getSession(false));
}
@Test
public void existingContextIsSuccessFullyLoadedFromSessionAndSavedBack() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
SecurityContextHolder.getContext().setAuthentication(testToken);
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext context = repo.loadContext(holder);
assertNotNull(context);
assertEquals(testToken, context.getAuthentication());
// Won't actually be saved as it hasn't changed, but go through the use case anyway
repo.saveContext(context, holder.getRequest(), holder.getResponse());
assertEquals(context, request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
}
@Test
public void nonSecurityContextInSessionIsIgnored() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
SecurityContextHolder.getContext().setAuthentication(testToken);
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, "NotASecurityContextInstance");
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext context = repo.loadContext(holder);
assertNotNull(context);
assertNull(context.getAuthentication());
}
@Test
public void sessionIsCreatedAndContextStoredWhenContextChanges() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext context = repo.loadContext(holder);
assertNull(request.getSession(false));
// Simulate authentication during the request
context.setAuthentication(testToken);
repo.saveContext(context, holder.getRequest(), holder.getResponse());
assertNotNull(request.getSession(false));
assertEquals(context, request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
}
@Test
public void redirectCausesEarlySaveOfContext() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContextHolder.setContext(repo.loadContext(holder));
SecurityContextHolder.getContext().setAuthentication(testToken);
holder.getResponse().sendRedirect("/doesntmatter");
assertEquals(SecurityContextHolder.getContext(), request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
assertTrue(((SaveContextOnUpdateOrErrorResponseWrapper)holder.getResponse()).isContextSaved());
repo.saveContext(SecurityContextHolder.getContext(), holder.getRequest(), holder.getResponse());
// Check it's still the same
assertEquals(SecurityContextHolder.getContext(), request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
}
@Test
public void sendErrorCausesEarlySaveOfContext() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContextHolder.setContext(repo.loadContext(holder));
SecurityContextHolder.getContext().setAuthentication(testToken);
holder.getResponse().sendError(404);
assertEquals(SecurityContextHolder.getContext(), request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
assertTrue(((SaveContextOnUpdateOrErrorResponseWrapper)holder.getResponse()).isContextSaved());
repo.saveContext(SecurityContextHolder.getContext(), holder.getRequest(), holder.getResponse());
// Check it's still the same
assertEquals(SecurityContextHolder.getContext(), request.getSession().getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY));
}
@Test
public void noSessionIsCreatedIfSessionWasInvalidatedDuringTheRequest() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
request.getSession();
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContextHolder.setContext(repo.loadContext(holder));
SecurityContextHolder.getContext().setAuthentication(testToken);
request.getSession().invalidate();
repo.saveContext(SecurityContextHolder.getContext(), holder.getRequest(), holder.getResponse());
assertNull(request.getSession(false));
}
@Test
public void settingCloneFromContextLoadsClonedContextObject() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setCloneFromHttpSession(true);
MockHttpServletRequest request = new MockHttpServletRequest();
MockContext contextBefore = new MockContext();
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, contextBefore);
contextBefore.setAuthentication(testToken);
MockHttpServletResponse response = new MockHttpServletResponse();
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
SecurityContext loadedContext = repo.loadContext(holder);
assertTrue(loadedContext instanceof MockContext);
assertFalse(loadedContext == contextBefore);
}
@Test
public void generateNewContextWorksWithContextClass() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
repo.setSecurityContextClass(MockContext.class);
assertTrue(repo.generateNewContext() instanceof MockContext);
}
@Test
@SuppressWarnings("deprecation")
public void sessionDisableUrlRewritingPreventsSessionIdBeingWrittenToUrl() throws Exception {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
MockHttpServletRequest request = new MockHttpServletRequest();
final String sessionId = ";jsessionid=id";
MockHttpServletResponse response = new MockHttpServletResponse() {
@Override
public String encodeRedirectUrl(String url) {
return url + sessionId;
}
@Override
public String encodeRedirectURL(String url) {
return url + sessionId;
}
@Override
public String encodeUrl(String url) {
return url + sessionId;
}
@Override
public String encodeURL(String url) {
return url + sessionId;
}
};
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
repo.loadContext(holder);
String url = "/aUrl";
assertEquals(url + sessionId, holder.getResponse().encodeRedirectUrl(url));
assertEquals(url + sessionId, holder.getResponse().encodeRedirectURL(url));
assertEquals(url + sessionId, holder.getResponse().encodeUrl(url));
assertEquals(url + sessionId, holder.getResponse().encodeURL(url));
repo.setDisableUrlRewriting(true);
holder = new HttpRequestResponseHolder(request, response);
repo.loadContext(holder);
assertEquals(url, holder.getResponse().encodeRedirectUrl(url));
assertEquals(url, holder.getResponse().encodeRedirectURL(url));
assertEquals(url, holder.getResponse().encodeUrl(url));
assertEquals(url, holder.getResponse().encodeURL(url));
}
static class MockContext implements Cloneable, SecurityContext {
Authentication a;
public Authentication getAuthentication() {
return a;
}
public void setAuthentication(Authentication authentication) {
a = authentication;
}
public Object clone() {
MockContext mc = new MockContext();
mc.setAuthentication(this.getAuthentication());
return mc;
}
}
}

View File

@@ -0,0 +1,136 @@
package org.springframework.security.context.web;
import static org.junit.Assert.*;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.ui.FilterChainOrder;
public class SecurityContextPersistenceFilterTests {
Mockery jmock = new JUnit4Mockery();
TestingAuthenticationToken testToken = new TestingAuthenticationToken("someone", "passwd", "ROLE_A");
@After
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test
public void contextIsClearedAfterChainProceeds() throws Exception {
final FilterChain chain = jmock.mock(FilterChain.class);
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
SecurityContextHolder.getContext().setAuthentication(testToken);
jmock.checking(new Expectations() {{
oneOf(chain).doFilter(with(aNonNull(HttpServletRequest.class)), with(aNonNull(HttpServletResponse.class)));
}});
filter.doFilter(request, response, chain);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void contextIsStillClearedIfExceptionIsThrowByFilterChain() throws Exception {
final FilterChain chain = jmock.mock(FilterChain.class);
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
SecurityContextHolder.getContext().setAuthentication(testToken);
jmock.checking(new Expectations() {{
oneOf(chain).doFilter(with(aNonNull(HttpServletRequest.class)), with(aNonNull(HttpServletResponse.class)));
will(throwException(new IOException()));
}});
try {
filter.doFilter(request, response, chain);
fail();
} catch(IOException expected) {
}
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void loadedContextContextIsCopiedToSecurityContextHolderAndUpdatedContextIsStored() throws Exception {
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
final TestingAuthenticationToken beforeAuth = new TestingAuthenticationToken("someoneelse", "passwd", "ROLE_B");
final SecurityContext scBefore = new SecurityContextImpl();
final SecurityContext scExpectedAfter = new SecurityContextImpl();
scExpectedAfter.setAuthentication(testToken);
scBefore.setAuthentication(beforeAuth);
final SecurityContextRepository repo = jmock.mock(SecurityContextRepository.class);
filter.setSecurityContextRepository(repo);
jmock.checking(new Expectations() {{
oneOf(repo).loadContext(with(aNonNull(HttpRequestResponseHolder.class))); will(returnValue(scBefore));
oneOf(repo).saveContext(scExpectedAfter, request, response);
}});
final FilterChain chain = new FilterChain() {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
assertEquals(beforeAuth, SecurityContextHolder.getContext().getAuthentication());
// Change the context here
SecurityContextHolder.setContext(scExpectedAfter);
}
};
filter.doFilter(request, response, chain);
jmock.assertIsSatisfied();
}
@Test
public void filterIsNotAppliedAgainIfFilterAppliedAttributeIsSet() throws Exception {
final FilterChain chain = jmock.mock(FilterChain.class);
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
filter.setSecurityContextRepository(jmock.mock(SecurityContextRepository.class));
jmock.checking(new Expectations() {{
oneOf(chain).doFilter(request, response);
}});
request.setAttribute(SecurityContextPersistenceFilter.FILTER_APPLIED, Boolean.TRUE);
filter.doFilter(request, response, chain);
jmock.assertIsSatisfied();
}
@Test
public void sessionIsEagerlyCreatedWhenConfigured() throws Exception {
final FilterChain chain = jmock.mock(FilterChain.class);
jmock.checking(new Expectations() {{ ignoring(chain); }});
final MockHttpServletRequest request = new MockHttpServletRequest();
final MockHttpServletResponse response = new MockHttpServletResponse();
SecurityContextPersistenceFilter filter = new SecurityContextPersistenceFilter();
filter.setForceEagerSessionCreation(true);
filter.doFilter(request, response, chain);
assertNotNull(request.getSession(false));
}
@Test
public void filterOrderHasExpectedValue() throws Exception {
assertEquals(FilterChainOrder.SECURITY_CONTEXT_FILTER, (new SecurityContextPersistenceFilter()).getOrder());
}
}

View File

@@ -0,0 +1,69 @@
package org.springframework.security.expression.web.support;
import static org.junit.Assert.*;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.Authentication;
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.web.util.FilterInvocationUtils;
/**
* Tests for {@link WebSecurityExpressionRoot}.
*
* @author Luke Taylor
* @version $Id$
* @since 2.5
*/
public class WebSecurityExpressionRootTests {
Mockery jmock = new JUnit4Mockery();
@Test
public void ipAddressMatchesForEqualIpAddresses() throws Exception {
FilterInvocation fi = FilterInvocationUtils.create("/test");
MockHttpServletRequest request = (MockHttpServletRequest) fi.getHttpRequest();
// IPv4
request.setRemoteAddr("192.168.1.1");
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(jmock.mock(Authentication.class), fi);
assertTrue(root.hasIpAddress("192.168.1.1"));
// IPv6 Address
request.setRemoteAddr("fa:db8:85a3::8a2e:370:7334");
assertTrue(root.hasIpAddress("fa:db8:85a3::8a2e:370:7334"));
}
@Test
public void addressesInIpRangeMatch() throws Exception {
FilterInvocation fi = FilterInvocationUtils.create("/test");
MockHttpServletRequest request = (MockHttpServletRequest) fi.getHttpRequest();
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(jmock.mock(Authentication.class), fi);
for (int i=0; i < 255; i++) {
request.setRemoteAddr("192.168.1." + i);
assertTrue(root.hasIpAddress("192.168.1.0/24"));
}
request.setRemoteAddr("192.168.1.127");
// 25 = FF FF FF 80
assertTrue(root.hasIpAddress("192.168.1.0/25"));
// encroach on the mask
request.setRemoteAddr("192.168.1.128");
assertFalse(root.hasIpAddress("192.168.1.0/25"));
request.setRemoteAddr("192.168.1.255");
assertTrue(root.hasIpAddress("192.168.1.128/25"));
assertTrue(root.hasIpAddress("192.168.1.192/26"));
assertTrue(root.hasIpAddress("192.168.1.224/27"));
assertTrue(root.hasIpAddress("192.168.1.240/27"));
assertTrue(root.hasIpAddress("192.168.1.255/32"));
request.setRemoteAddr("202.24.199.127");
assertTrue(root.hasIpAddress("202.24.0.0/14"));
request.setRemoteAddr("202.25.179.135");
assertTrue(root.hasIpAddress("202.24.0.0/14"));
request.setRemoteAddr("202.26.179.135");
assertTrue(root.hasIpAddress("202.24.0.0/14"));
}
}

View File

@@ -0,0 +1,192 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.intercept.web;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import java.util.LinkedHashMap;
import java.util.List;
import javax.servlet.FilterChain;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.SecurityConfig;
import org.springframework.security.util.AntUrlPathMatcher;
/**
* Tests parts of {@link DefaultFilterInvocationSecurityMetadataSource} not tested by {@link
* FilterInvocationDefinitionSourceEditorTests}.
*
* @author Ben Alex
* @version $Id$
*/
@SuppressWarnings("unchecked")
public class DefaultFilterInvocationSecurityMetadataSourceTests {
private DefaultFilterInvocationSecurityMetadataSource fids;
private List<ConfigAttribute> def = SecurityConfig.createList("ROLE_ONE");
//~ Methods ========================================================================================================
private void createFids(String url, String method) {
LinkedHashMap requestMap = new LinkedHashMap();
requestMap.put(new RequestKey(url, method), def);
fids = new DefaultFilterInvocationSecurityMetadataSource(new AntUrlPathMatcher(), requestMap);
fids.setStripQueryStringFromUrls(true);
}
private void createFids(String url, boolean convertToLowerCase) {
LinkedHashMap requestMap = new LinkedHashMap();
requestMap.put(new RequestKey(url), def);
fids = new DefaultFilterInvocationSecurityMetadataSource(new AntUrlPathMatcher(convertToLowerCase), requestMap);
fids.setStripQueryStringFromUrls(true);
}
@Test
public void convertUrlToLowercaseIsTrueByDefault() {
LinkedHashMap requestMap = new LinkedHashMap();
requestMap.put(new RequestKey("/something"), def);
fids = new DefaultFilterInvocationSecurityMetadataSource(new AntUrlPathMatcher(), requestMap);
assertTrue(fids.isConvertUrlToLowercaseBeforeComparison());
}
@Test
public void lookupNotRequiringExactMatchSucceedsIfNotMatching() {
createFids("/secure/super/**", null);
FilterInvocation fi = createFilterInvocation("/SeCuRE/super/somefile.html", null);
assertEquals(def, fids.lookupAttributes(fi.getRequestUrl(), null));
}
/**
* SEC-501. Note that as of 2.0, lower case comparisons are the default for this class.
*/
@Test
public void lookupNotRequiringExactMatchSucceedsIfSecureUrlPathContainsUpperCase() {
createFids("/SeCuRE/super/**", null);
FilterInvocation fi = createFilterInvocation("/secure/super/somefile.html", null);
List<? extends ConfigAttribute> response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(def, response);
}
@Test
public void lookupRequiringExactMatchFailsIfNotMatching() {
createFids("/secure/super/**", false);
FilterInvocation fi = createFilterInvocation("/SeCuRE/super/somefile.html", null);
List<? extends ConfigAttribute> response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(null, response);
}
@Test
public void lookupRequiringExactMatchIsSuccessful() {
createFids("/SeCurE/super/**", false);
FilterInvocation fi = createFilterInvocation("/SeCurE/super/somefile.html", null);
List<? extends ConfigAttribute> response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(def, response);
}
@Test
public void lookupRequiringExactMatchWithAdditionalSlashesIsSuccessful() {
createFids("/someAdminPage.html**", null);
FilterInvocation fi = createFilterInvocation("/someAdminPage.html?a=/test", null);
List<? extends ConfigAttribute> response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(def, response); // see SEC-161 (it should truncate after ? sign)
}
@Test(expected = IllegalArgumentException.class)
public void unknownHttpMethodIsRejected() {
createFids("/someAdminPage.html**", "UNKNOWN");
}
@Test
public void httpMethodLookupSucceeds() {
createFids("/somepage**", "GET");
FilterInvocation fi = createFilterInvocation("/somepage", "GET");
List<? extends ConfigAttribute> attrs = fids.getAttributes(fi);
assertEquals(def, attrs);
}
@Test
public void generalMatchIsUsedIfNoMethodSpecificMatchExists() {
createFids("/somepage**", null);
FilterInvocation fi = createFilterInvocation("/somepage", "GET");
List<? extends ConfigAttribute> attrs = fids.getAttributes(fi);
assertEquals(def, attrs);
}
@Test
public void requestWithDifferentHttpMethodDoesntMatch() {
createFids("/somepage**", "GET");
FilterInvocation fi = createFilterInvocation("/somepage", null);
List<? extends ConfigAttribute> attrs = fids.getAttributes(fi);
assertNull(attrs);
}
@Test
public void httpMethodSpecificUrlTakesPrecedence() {
LinkedHashMap<RequestKey, List<ConfigAttribute>> requestMap = new LinkedHashMap<RequestKey, List<ConfigAttribute>>();
// Even though this is added before the Http method-specific def, the latter should match
requestMap.put(new RequestKey("/**"), def);
List<ConfigAttribute> postOnlyDef = SecurityConfig.createList("ROLE_TWO");
requestMap.put(new RequestKey("/somepage**", "POST"), postOnlyDef);
fids = new DefaultFilterInvocationSecurityMetadataSource(new AntUrlPathMatcher(), requestMap);
List<ConfigAttribute> attrs = fids.getAttributes(createFilterInvocation("/somepage", "POST"));
assertEquals(postOnlyDef, attrs);
}
/**
* Check fixes for SEC-321
*/
@Test
public void extraQuestionMarkStillMatches() {
createFids("/someAdminPage.html*", null);
FilterInvocation fi = createFilterInvocation("/someAdminPage.html?x=2/aa?y=3", null);
List<? extends ConfigAttribute> response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(def, response);
fi = createFilterInvocation("/someAdminPage.html??", null);
response = fids.lookupAttributes(fi.getRequestUrl(), null);
assertEquals(def, response);
}
private FilterInvocation createFilterInvocation(String path, String method) {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI(null);
request.setMethod(method);
request.setServletPath(path);
return new FilterInvocation(request, new MockHttpServletResponse(), mock(FilterChain.class));
}
}

View File

@@ -0,0 +1,118 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.intercept.web;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import javax.servlet.FilterChain;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* Tests {@link FilterInvocation}.
*
* @author Ben Alex
* @author colin sampaleanu
* @version $Id$
*/
public class FilterInvocationTests {
//~ Methods ========================================================================================================
@Test
public void testGettersAndStringMethods() {
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
request.setServletPath("/HelloWorld");
request.setPathInfo("/some/more/segments.html");
request.setServerName("www.example.com");
request.setScheme("http");
request.setServerPort(80);
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/HelloWorld/some/more/segments.html");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain chain = mock(FilterChain.class);
FilterInvocation fi = new FilterInvocation(request, response, chain);
assertEquals(request, fi.getRequest());
assertEquals(request, fi.getHttpRequest());
assertEquals(response, fi.getResponse());
assertEquals(response, fi.getHttpResponse());
assertEquals(chain, fi.getChain());
assertEquals("/HelloWorld/some/more/segments.html", fi.getRequestUrl());
assertEquals("FilterInvocation: URL: /HelloWorld/some/more/segments.html", fi.toString());
assertEquals("http://www.example.com/mycontext/HelloWorld/some/more/segments.html", fi.getFullRequestUrl());
}
@Test(expected=IllegalArgumentException.class)
public void testRejectsNullFilterChain() {
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
MockHttpServletResponse response = new MockHttpServletResponse();
new FilterInvocation(request, response, null);
}
@Test(expected=IllegalArgumentException.class)
public void testRejectsNullServletRequest() {
MockHttpServletResponse response = new MockHttpServletResponse();
new FilterInvocation(null, response, mock(FilterChain.class));
}
@Test(expected=IllegalArgumentException.class)
public void testRejectsNullServletResponse() {
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
new FilterInvocation(request, null, mock(FilterChain.class));
}
@Test
public void testStringMethodsWithAQueryString() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("foo=bar");
request.setServletPath("/HelloWorld");
request.setServerName("www.example.com");
request.setScheme("http");
request.setServerPort(80);
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/HelloWorld");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
assertEquals("/HelloWorld?foo=bar", fi.getRequestUrl());
assertEquals("FilterInvocation: URL: /HelloWorld?foo=bar", fi.toString());
assertEquals("http://www.example.com/mycontext/HelloWorld?foo=bar", fi.getFullRequestUrl());
}
@Test
public void testStringMethodsWithoutAnyQueryString() {
MockHttpServletRequest request = new MockHttpServletRequest(null, null);
request.setServletPath("/HelloWorld");
request.setServerName("www.example.com");
request.setScheme("http");
request.setServerPort(80);
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/HelloWorld");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
assertEquals("/HelloWorld", fi.getRequestUrl());
assertEquals("FilterInvocation: URL: /HelloWorld", fi.toString());
assertEquals("http://www.example.com/mycontext/HelloWorld", fi.getFullRequestUrl());
}
}

View File

@@ -0,0 +1,125 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.intercept.web;
import java.util.List;
import javax.servlet.FilterChain;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.AccessDecisionManager;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.MockApplicationEventPublisher;
import org.springframework.security.RunAsManager;
import org.springframework.security.SecurityConfig;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
/**
* Tests {@link FilterSecurityInterceptor}.
*
* @author Ben Alex
* @version $Id$
*/
public class FilterSecurityInterceptorTests {
private Mockery jmock = new JUnit4Mockery();
private AuthenticationManager am;
private AccessDecisionManager adm;
private FilterInvocationSecurityMetadataSource ods;
private RunAsManager ram;
private FilterSecurityInterceptor interceptor;
//~ Methods ========================================================================================================
@Before
public final void setUp() throws Exception {
interceptor = new FilterSecurityInterceptor();
am = jmock.mock(AuthenticationManager.class);
ods = jmock.mock(FilterInvocationSecurityMetadataSource.class);
adm = jmock.mock(AccessDecisionManager.class);
ram = jmock.mock(RunAsManager.class);
interceptor.setAuthenticationManager(am);
interceptor.setSecurityMetadataSource(ods);
interceptor.setAccessDecisionManager(adm);
interceptor.setRunAsManager(ram);
interceptor.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
SecurityContextHolder.clearContext();
}
@After
public void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
@Test(expected=IllegalArgumentException.class)
public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass() throws Exception {
jmock.checking(new Expectations() {{
ignoring(ods);
allowing(adm).supports(FilterInvocation.class); will(returnValue(false));
}});
interceptor.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void testEnsuresRunAsManagerSupportsFilterInvocationClass() throws Exception {
jmock.checking(new Expectations() {{
ignoring(ods);
allowing(ram).supports(FilterInvocation.class); will(returnValue(false));
}});
interceptor.afterPropertiesSet();
}
/**
* We just test invocation works in a success event. There is no need to test access denied events as the
* abstract parent enforces that logic, which is extensively tested separately.
*/
@Test
public void testSuccessfulInvocation() throws Throwable {
final MockHttpServletResponse response = new MockHttpServletResponse();
final MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
// Setup a Context
final Authentication token = new TestingAuthenticationToken("Test", "Password", "NOT_USED");
SecurityContextHolder.getContext().setAuthentication(token);
// Create and test our secure object
final FilterChain chain = jmock.mock(FilterChain.class);
final FilterInvocation fi = new FilterInvocation(request, response, chain);
final List<ConfigAttribute> attributes = SecurityConfig.createList("MOCK_OK");
jmock.checking(new Expectations() {{
ignoring(ram);
allowing(ods).getAttributes(fi); will(returnValue(attributes));
oneOf(adm).decide(token, fi, attributes);
// Setup our expectation that the filter chain will be invoked, as access is granted
oneOf(chain).doFilter(request, response);
}});
interceptor.invoke(fi);
}
}

View File

@@ -0,0 +1,51 @@
package org.springframework.security.intercept.web;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Luke Taylor
* @version $Id$
*
*/
public class RequestKeyTests {
@Test
public void equalsWorksWithNullHttpMethod() {
RequestKey key1 = new RequestKey("/someurl");
RequestKey key2 = new RequestKey("/someurl");
assertEquals(key1, key2);
key1 = new RequestKey("/someurl","GET");
assertFalse(key1.equals(key2));
assertFalse(key2.equals(key1));
}
@Test
public void keysWithSameUrlAndHttpMethodAreEqual() {
RequestKey key1 = new RequestKey("/someurl", "GET");
RequestKey key2 = new RequestKey("/someurl", "GET");
assertEquals(key1, key2);
}
@Test
public void keysWithSameUrlAndDifferentHttpMethodAreNotEqual() {
RequestKey key1 = new RequestKey("/someurl", "GET");
RequestKey key2 = new RequestKey("/someurl", "POST");
assertFalse(key1.equals(key2));
assertFalse(key2.equals(key1));
}
@Test
public void keysWithDifferentUrlsAreNotEquals() {
RequestKey key1 = new RequestKey("/someurl", "GET");
RequestKey key2 = new RequestKey("/anotherurl", "GET");
assertFalse(key1.equals(key2));
assertFalse(key2.equals(key1));
}
}

View File

@@ -0,0 +1,115 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.intercept.web;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.security.matcher.AuthenticationMatcher.anAuthenticationWithUsername;
import java.util.List;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.AccessDecisionManager;
import org.springframework.security.AccessDeniedException;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.MockApplicationEventPublisher;
import org.springframework.security.RunAsManager;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.web.util.FilterInvocationUtils;
/**
* Tests {@link org.springframework.security.intercept.web.WebInvocationPrivilegeEvaluator}.
*
* @author Ben Alex
* @version $Id$
*/
public class WebInvocationPrivilegeEvaluatorTests {
private Mockery jmock = new JUnit4Mockery();
private AuthenticationManager am;
private AccessDecisionManager adm;
private FilterInvocationSecurityMetadataSource ods;
private RunAsManager ram;
private FilterSecurityInterceptor interceptor;
//~ Methods ========================================================================================================
@Before
public final void setUp() throws Exception {
interceptor = new FilterSecurityInterceptor();
am = jmock.mock(AuthenticationManager.class);
ods = jmock.mock(FilterInvocationSecurityMetadataSource.class);
adm = jmock.mock(AccessDecisionManager.class);
ram = jmock.mock(RunAsManager.class);
interceptor.setAuthenticationManager(am);
interceptor.setSecurityMetadataSource(ods);
interceptor.setAccessDecisionManager(adm);
interceptor.setRunAsManager(ram);
interceptor.setApplicationEventPublisher(new MockApplicationEventPublisher(true));
SecurityContextHolder.clearContext();
}
@After
public void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
@SuppressWarnings("unchecked")
@Test
public void allowsAccessIfAccessDecisionMangerDoes() throws Exception {
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
FilterInvocation fi = FilterInvocationUtils.create("/foo/index.jsp");
WebInvocationPrivilegeEvaluator wipe = new WebInvocationPrivilegeEvaluator();
wipe.setSecurityInterceptor(interceptor);
wipe.afterPropertiesSet();
jmock.checking(new Expectations() {{
ignoring(ram); ignoring(ods);
oneOf(adm).decide(with(anAuthenticationWithUsername("test")), with(anything()), with(aNonNull(List.class)));
}});
assertTrue(wipe.isAllowed(fi, token));
jmock.assertIsSatisfied();
}
@SuppressWarnings("unchecked")
@Test
public void deniesAccessIfAccessDecisionMangerDoes() throws Exception {
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
FilterInvocation fi = FilterInvocationUtils.create("/foo/index.jsp");
WebInvocationPrivilegeEvaluator wipe = new WebInvocationPrivilegeEvaluator();
wipe.setSecurityInterceptor(interceptor);
wipe.afterPropertiesSet();
jmock.checking(new Expectations() {{
ignoring(ram); ignoring(ods);
oneOf(adm).decide(with(anAuthenticationWithUsername("test")), with(anything()), with(aNonNull(List.class)));
will(throwException(new AccessDeniedException("")));
}});
assertFalse(wipe.isAllowed(fi, token));
jmock.assertIsSatisfied();
}
}

View File

@@ -0,0 +1,216 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.FilterInvocation;
/**
* Tests {@link ChannelDecisionManagerImpl}.
*
* @author Ben Alex
* @version $Id$
*/
@SuppressWarnings("unchecked")
public class ChannelDecisionManagerImplTests extends TestCase {
//~ Methods ========================================================================================================
public void testCannotSetEmptyChannelProcessorsList() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
try {
cdm.setChannelProcessors(new Vector());
cdm.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A list of ChannelProcessors is required", expected.getMessage());
}
}
public void testCannotSetIncorrectObjectTypesIntoChannelProcessorsList() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
List list = new Vector();
list.add("THIS IS NOT A CHANNELPROCESSOR");
try {
cdm.setChannelProcessors(list);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testCannotSetNullChannelProcessorsList() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
try {
cdm.setChannelProcessors(null);
cdm.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A list of ChannelProcessors is required", expected.getMessage());
}
}
public void testDecideIsOperational() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", true);
List list = new Vector();
list.add(cpXyz);
list.add(cpAbc);
cdm.setChannelProcessors(list);
cdm.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
List<ConfigAttribute> cad = SecurityConfig.createList("xyz");
cdm.decide(fi, cad);
assertTrue(fi.getResponse().isCommitted());
}
public void testAnyChannelAttributeCausesProcessorsToBeSkipped() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", true);
List list = new Vector();
list.add(cpAbc);
cdm.setChannelProcessors(list);
cdm.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
cdm.decide(fi, SecurityConfig.createList(new String[]{"abc", "ANY_CHANNEL"}));
assertFalse(fi.getResponse().isCommitted());
}
public void testDecideIteratesAllProcessorsIfNoneCommitAResponse() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
List list = new Vector();
list.add(cpXyz);
list.add(cpAbc);
cdm.setChannelProcessors(list);
cdm.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
cdm.decide(fi, SecurityConfig.createList("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT"));
assertFalse(fi.getResponse().isCommitted());
}
public void testDelegatesSupports() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
List list = new Vector();
list.add(cpXyz);
list.add(cpAbc);
cdm.setChannelProcessors(list);
cdm.afterPropertiesSet();
assertTrue(cdm.supports(new SecurityConfig("xyz")));
assertTrue(cdm.supports(new SecurityConfig("abc")));
assertFalse(cdm.supports(new SecurityConfig("UNSUPPORTED")));
}
public void testGettersSetters() {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
assertNull(cdm.getChannelProcessors());
MockChannelProcessor cpXyz = new MockChannelProcessor("xyz", false);
MockChannelProcessor cpAbc = new MockChannelProcessor("abc", false);
List list = new Vector();
list.add(cpXyz);
list.add(cpAbc);
cdm.setChannelProcessors(list);
assertEquals(list, cdm.getChannelProcessors());
}
public void testStartupFailsWithEmptyChannelProcessorsList() throws Exception {
ChannelDecisionManagerImpl cdm = new ChannelDecisionManagerImpl();
try {
cdm.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("A list of ChannelProcessors is required", expected.getMessage());
}
}
//~ Inner Classes ==================================================================================================
private class MockChannelProcessor implements ChannelProcessor {
private String configAttribute;
private boolean failIfCalled;
public MockChannelProcessor(String configAttribute, boolean failIfCalled) {
this.configAttribute = configAttribute;
this.failIfCalled = failIfCalled;
}
public void decide(FilterInvocation invocation, List<ConfigAttribute> config)
throws IOException, ServletException {
Iterator iter = config.iterator();
if (failIfCalled) {
fail("Should not have called this channel processor: " + configAttribute);
}
while (iter.hasNext()) {
ConfigAttribute attr = (ConfigAttribute) iter.next();
if (attr.getAttribute().equals(configAttribute)) {
invocation.getHttpResponse().sendRedirect("/redirected");
return;
}
}
}
public boolean supports(ConfigAttribute attribute) {
if (attribute.getAttribute().equals(configAttribute)) {
return true;
} else {
return false;
}
}
}
}

View File

@@ -0,0 +1,218 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.intercept.web.FilterInvocationSecurityMetadataSource;
/**
* Tests {@link ChannelProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class ChannelProcessingFilterTests {
//~ Methods ========================================================================================================
@Test(expected=IllegalArgumentException.class)
public void testDetectsMissingChannelDecisionManager() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "MOCK");
filter.setFilterInvocationSecurityMetadataSource(fids);
filter.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void testDetectsMissingFilterInvocationSecurityMetadataSource() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "MOCK"));
filter.afterPropertiesSet();
}
@Test
public void testDetectsSupportedConfigAttribute() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SUPPORTS_MOCK_ONLY"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY");
filter.setFilterInvocationSecurityMetadataSource(fids);
filter.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void testDetectsUnsupportedConfigAttribute() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SUPPORTS_MOCK_ONLY"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SUPPORTS_MOCK_ONLY", "INVALID_ATTRIBUTE");
filter.setFilterInvocationSecurityMetadataSource(fids);
filter.afterPropertiesSet();
}
@Test
public void testDoFilterWhenManagerDoesCommitResponse() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
filter.setFilterInvocationSecurityMetadataSource(fids);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=now");
request.setServletPath("/path");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
}
@Test
public void testDoFilterWhenManagerDoesNotCommitResponse() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
filter.setFilterInvocationSecurityMetadataSource(fids);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=now");
request.setServletPath("/path");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
}
@Test
public void testDoFilterWhenNullConfigAttributeReturned()
throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
filter.setFilterInvocationSecurityMetadataSource(fids);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=now");
request.setServletPath("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
}
@Test
public void testGetterSetters() throws Exception {
ChannelProcessingFilter filter = new ChannelProcessingFilter();
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "MOCK"));
assertTrue(filter.getChannelDecisionManager() != null);
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", false, "MOCK");
filter.setFilterInvocationSecurityMetadataSource(fids);
assertTrue(filter.getFilterInvocationSecurityMetadataSource() != null);
filter.init(null);
filter.afterPropertiesSet();
filter.destroy();
}
//~ Inner Classes ==================================================================================================
private class MockChannelDecisionManager implements ChannelDecisionManager {
private String supportAttribute;
private boolean commitAResponse;
public MockChannelDecisionManager(boolean commitAResponse, String supportAttribute) {
this.commitAResponse = commitAResponse;
this.supportAttribute = supportAttribute;
}
public void decide(FilterInvocation invocation, List<ConfigAttribute> config)
throws IOException, ServletException {
if (commitAResponse) {
invocation.getHttpResponse().sendRedirect("/redirected");
}
}
public boolean supports(ConfigAttribute attribute) {
if (attribute.getAttribute().equals(supportAttribute)) {
return true;
} else {
return false;
}
}
}
private class MockFilterInvocationDefinitionMap implements FilterInvocationSecurityMetadataSource {
private List<ConfigAttribute> toReturn;
private String servletPath;
private boolean provideIterator;
public MockFilterInvocationDefinitionMap(String servletPath, boolean provideIterator, String... toReturn) {
this.servletPath = servletPath;
this.toReturn = SecurityConfig.createList(toReturn);
this.provideIterator = provideIterator;
}
public List<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
FilterInvocation fi = (FilterInvocation) object;
if (servletPath.equals(fi.getHttpRequest().getServletPath())) {
return toReturn;
} else {
return null;
}
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
if (!provideIterator) {
return null;
}
return toReturn;
}
public boolean supports(Class<?> clazz) {
return true;
}
}
}

View File

@@ -0,0 +1,138 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import static org.mockito.Mockito.mock;
import javax.servlet.FilterChain;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.FilterInvocation;
/**
* Tests {@link InsecureChannelProcessor}.
*
* @author Ben Alex
* @version $Id$
*/
public class InsecureChannelProcessorTests extends TestCase {
public void testDecideDetectsAcceptableChannel() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/bigapp");
request.setServletPath("/servlet");
request.setScheme("http");
request.setServerPort(8080);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL"));
assertFalse(fi.getResponse().isCommitted());
}
public void testDecideDetectsUnacceptableChannel()
throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/bigapp");
request.setServletPath("/servlet");
request.setScheme("https");
request.setSecure(true);
request.setServerPort(8443);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList(new String[]{"SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL"}));
assertTrue(fi.getResponse().isCommitted());
}
public void testDecideRejectsNulls() throws Exception {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.afterPropertiesSet();
try {
processor.decide(null, null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
assertEquals("REQUIRES_INSECURE_CHANNEL", processor.getInsecureKeyword());
processor.setInsecureKeyword("X");
assertEquals("X", processor.getInsecureKeyword());
assertTrue(processor.getEntryPoint() != null);
processor.setEntryPoint(null);
assertTrue(processor.getEntryPoint() == null);
}
public void testMissingEntryPoint() throws Exception {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.setEntryPoint(null);
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("entryPoint required", expected.getMessage());
}
}
public void testMissingSecureChannelKeyword() throws Exception {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.setInsecureKeyword(null);
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("insecureKeyword required", expected.getMessage());
}
processor.setInsecureKeyword("");
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("insecureKeyword required", expected.getMessage());
}
}
public void testSupports() {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
assertTrue(processor.supports(new SecurityConfig("REQUIRES_INSECURE_CHANNEL")));
assertFalse(processor.supports(null));
assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
}
}

View File

@@ -0,0 +1,153 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import junit.framework.TestCase;
import org.springframework.security.MockPortResolver;
import org.springframework.security.web.util.PortMapperImpl;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Tests {@link RetryWithHttpEntryPoint}.
*
* @author Ben Alex
* @version $Id$
*/
public class RetryWithHttpEntryPointTests extends TestCase {
//~ Methods ========================================================================================================
public void testDetectsMissingPortMapper() throws Exception {
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
try {
ep.setPortMapper(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testDetectsMissingPortResolver() throws Exception {
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
try {
ep.setPortResolver(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testGettersSetters() {
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8080, 8443));
assertTrue(ep.getPortMapper() != null);
assertTrue(ep.getPortResolver() != null);
}
public void testNormalOperation() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(443);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.commence(request, response);
assertEquals("http://www.example.com/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl());
}
public void testNormalOperationWithNullPathInfoAndNullQueryString()
throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo(null);
request.setServerPort(443);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.commence(request, response);
assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
}
public void testOperationWhenTargetPortIsUnknown()
throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(8768);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8768, 1234));
ep.commence(request, response);
assertEquals("/bigWebApp", response.getRedirectedUrl());
}
public void testOperationWithNonStandardPort() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(9999);
MockHttpServletResponse response = new MockHttpServletResponse();
PortMapperImpl portMapper = new PortMapperImpl();
Map<String, String> map = new HashMap<String, String>();
map.put("8888", "9999");
portMapper.setPortMappings(map);
RetryWithHttpEntryPoint ep = new RetryWithHttpEntryPoint();
ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.setPortMapper(portMapper);
ep.commence(request, response);
assertEquals("http://www.example.com:8888/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl());
}
}

View File

@@ -0,0 +1,160 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import junit.framework.TestCase;
import org.springframework.security.MockPortResolver;
import org.springframework.security.web.util.PortMapperImpl;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Tests {@link RetryWithHttpsEntryPoint}.
*
* @author Ben Alex
* @version $Id$
*/
public class RetryWithHttpsEntryPointTests extends TestCase {
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(RetryWithHttpsEntryPointTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testDetectsMissingPortMapper() throws Exception {
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
try {
ep.setPortMapper(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testDetectsMissingPortResolver() throws Exception {
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
try {
ep.setPortResolver(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testGettersSetters() {
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8080, 8443));
assertTrue(ep.getPortMapper() != null);
assertTrue(ep.getPortResolver() != null);
}
public void testNormalOperation() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.commence(request, response);
assertEquals("https://www.example.com/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl());
}
public void testNormalOperationWithNullPathInfoAndNullQueryString()
throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo(null);
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.commence(request, response);
assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
}
public void testOperationWhenTargetPortIsUnknown() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(8768);
MockHttpServletResponse response = new MockHttpServletResponse();
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8768, 1234));
ep.commence(request, response);
assertEquals("/bigWebApp", response.getRedirectedUrl());
}
public void testOperationWithNonStandardPort() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("open=true");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServletPath("/hello");
request.setPathInfo("/pathInfo.html");
request.setServerPort(8888);
MockHttpServletResponse response = new MockHttpServletResponse();
PortMapperImpl portMapper = new PortMapperImpl();
Map<String, String> map = new HashMap<String, String>();
map.put("8888", "9999");
portMapper.setPortMappings(map);
RetryWithHttpsEntryPoint ep = new RetryWithHttpsEntryPoint();
ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.setPortMapper(portMapper);
ep.commence(request, response);
assertEquals("https://www.example.com:9999/bigWebApp/hello/pathInfo.html?open=true", response.getRedirectedUrl());
}
}

View File

@@ -0,0 +1,138 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.securechannel;
import static org.mockito.Mockito.mock;
import javax.servlet.FilterChain;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.FilterInvocation;
/**
* Tests {@link SecureChannelProcessor}.
*
* @author Ben Alex
* @version $Id$
*/
public class SecureChannelProcessorTests extends TestCase {
//~ Methods ========================================================================================================
public void testDecideDetectsAcceptableChannel() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/bigapp");
request.setServletPath("/servlet");
request.setScheme("https");
request.setSecure(true);
request.setServerPort(8443);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL"));
assertFalse(fi.getResponse().isCommitted());
}
public void testDecideDetectsUnacceptableChannel() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setQueryString("info=true");
request.setServerName("localhost");
request.setContextPath("/bigapp");
request.setServletPath("/servlet");
request.setScheme("http");
request.setServerPort(8080);
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList(new String[]{"SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL"}));
assertTrue(fi.getResponse().isCommitted());
}
public void testDecideRejectsNulls() throws Exception {
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.afterPropertiesSet();
try {
processor.decide(null, null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() {
SecureChannelProcessor processor = new SecureChannelProcessor();
assertEquals("REQUIRES_SECURE_CHANNEL", processor.getSecureKeyword());
processor.setSecureKeyword("X");
assertEquals("X", processor.getSecureKeyword());
assertTrue(processor.getEntryPoint() != null);
processor.setEntryPoint(null);
assertTrue(processor.getEntryPoint() == null);
}
public void testMissingEntryPoint() throws Exception {
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.setEntryPoint(null);
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("entryPoint required", expected.getMessage());
}
}
public void testMissingSecureChannelKeyword() throws Exception {
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.setSecureKeyword(null);
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("secureKeyword required", expected.getMessage());
}
processor.setSecureKeyword("");
try {
processor.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("secureKeyword required", expected.getMessage());
}
}
public void testSupports() {
SecureChannelProcessor processor = new SecureChannelProcessor();
assertTrue(processor.supports(new SecurityConfig("REQUIRES_SECURE_CHANNEL")));
assertFalse(processor.supports(null));
assertFalse(processor.supports(new SecurityConfig("NOT_SUPPORTED")));
}
}

View File

@@ -0,0 +1,574 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import junit.framework.TestCase;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.AccountExpiredException;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.rememberme.NullRememberMeServices;
import org.springframework.security.ui.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.web.util.PortResolverImpl;
/**
* Tests {@link AbstractProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class AbstractProcessingFilterTests extends TestCase {
SavedRequestAwareAuthenticationSuccessHandler successHandler;
SimpleUrlAuthenticationFailureHandler failureHandler;
//~ Methods ========================================================================================================
private MockHttpServletRequest createMockRequest() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/j_mock_post");
request.setScheme("http");
request.setServerName("www.example.com");
request.setRequestURI("/mycontext/j_mock_post");
request.setContextPath("/mycontext");
return request;
}
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
private SavedRequest makeSavedRequestForUrl() {
MockHttpServletRequest request = createMockRequest();
request.setMethod("GET");
request.setServletPath("/some_protected_file.html");
request.setScheme("http");
request.setServerName("www.example.com");
request.setRequestURI("/mycontext/some_protected_file.html");
return new SavedRequest(request, new PortResolverImpl());
}
// private SavedRequest makePostSavedRequestForUrl() {
// MockHttpServletRequest request = createMockRequest();
// request.setServletPath("/some_protected_file.html");
// request.setScheme("http");
// request.setServerName("www.example.com");
// request.setRequestURI("/mycontext/post/some_protected_file.html");
// request.setMethod("POST");
//
// return new SavedRequest(request, new PortResolverImpl());
// }
protected void setUp() throws Exception {
super.setUp();
successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
successHandler.setDefaultTargetUrl("/logged_in.jsp");
failureHandler = new SimpleUrlAuthenticationFailureHandler();
failureHandler.setDefaultFailureUrl("/failed.jsp");
SecurityContextHolder.clearContext();
}
protected void tearDown() throws Exception {
super.tearDown();
SecurityContextHolder.clearContext();
}
public void testDefaultProcessesFilterUrlMatchesWithPathParameter() {
MockHttpServletRequest request = createMockRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setFilterProcessesUrl("/j_spring_security_check");
request.setRequestURI("/mycontext/j_spring_security_check;jsessionid=I8MIONOSTHOR");
assertTrue(filter.requiresAuthentication(request, response));
}
public void testFailedAuthenticationRedirectsAppropriately() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to deny access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
filter.setAuthenticationFailureHandler(failureHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/failed.jsp", response.getRedirectedUrl());
assertNull(SecurityContextHolder.getContext().getAuthentication());
//Prepare again, this time using the exception mapping
filter = new MockAbstractProcessingFilter(new AccountExpiredException("You're account is expired"));
ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
filter.setAuthenticationFailureHandler(failureHandler);
Properties exceptionMappings = new Properties();
exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/accountExpired.jsp");
failureHandler.setExceptionMappings(exceptionMappings);
response = new MockHttpServletResponse();
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/accountExpired.jsp", response.getRedirectedUrl());
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
public void testFilterProcessesUrlVariationsRespected() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.setServletPath("/j_OTHER_LOCATION");
request.setRequestURI("/mycontext/j_OTHER_LOCATION");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_OTHER_LOCATION");
filter.setAuthenticationSuccessHandler(successHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
}
public void testGettersSetters() throws Exception {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setFilterProcessesUrl("/p");
filter.afterPropertiesSet();
assertNotNull(filter.getRememberMeServices());
filter.setRememberMeServices(new TokenBasedRememberMeServices());
assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass());
assertTrue(filter.getAuthenticationManager() != null);
assertEquals("/p", filter.getFilterProcessesUrl());
}
public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.setServletPath("/some.file.html");
request.setRequestURI("/mycontext/some.file.html");
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will be invoked, as our request is for a page the filter isn't monitoring
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to deny access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
}
public void testNormalOperationWithDefaultFilterProcessesUrl() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
HttpSession sessionPreAuth = request.getSession();
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_mock_post");
filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler);
filter.setAuthenticationManager(new MockAuthenticationManager(true));
filter.afterPropertiesSet();
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
// Should still have the same session
assertEquals(sessionPreAuth, request.getSession());
}
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationFailureHandler(failureHandler);
successHandler.setDefaultTargetUrl("/");
filter.setAuthenticationSuccessHandler(successHandler);
filter.setFilterProcessesUrl("/j_spring_security_check");
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("authenticationManager must be specified", expected.getMessage());
}
}
public void testStartupDetectsInvalidFilterProcessesUrl() throws Exception {
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationFailureHandler(failureHandler);
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setAuthenticationSuccessHandler(successHandler);
filter.setFilterProcessesUrl(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("filterProcessesUrl must be specified", expected.getMessage());
}
}
public void testSuccessLoginThenFailureLoginResultsInSessionLosingToken() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will not be invoked, as we redirect to defaultTargetUrl
MockFilterChain chain = new MockFilterChain(false);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_mock_post");
filter.setAuthenticationSuccessHandler(successHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
// Now try again but this time have filter deny access
// Setup our HTTP request
// Setup our expectation that the filter chain will not be invoked, as we redirect to authenticationFailureUrl
chain = new MockFilterChain(false);
response = new MockHttpServletResponse();
// Setup our test object, to deny access
filter = new MockAbstractProcessingFilter(false);
filter.setFilterProcessesUrl("/j_mock_post");
filter.setAuthenticationFailureHandler(failureHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
public void testSuccessfulAuthenticationButWithAlwaysUseDefaultTargetUrlCausesRedirectToDefaultTargetUrl()
throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will be invoked, as we want to go to the location requested in the session
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_mock_post");
successHandler.setDefaultTargetUrl("/foobar");
assertFalse(successHandler.isAlwaysUseDefaultTargetUrl()); // check default
successHandler.setAlwaysUseDefaultTargetUrl(true);
assertTrue(successHandler.isAlwaysUseDefaultTargetUrl()); // check changed
filter.setAuthenticationSuccessHandler(successHandler);
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/foobar", response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
}
public void testSuccessfulAuthenticationCausesRedirectToSessionSpecifiedUrl() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = createMockRequest();
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, makeSavedRequestForUrl());
// Setup our filter configuration
MockFilterConfig config = new MockFilterConfig(null, null);
// Setup our expectation that the filter chain will be invoked, as we want to go to the location requested in the session
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_mock_post");
// Test
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals(makeSavedRequestForUrl().getFullRequestUrl(), response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
}
/**
* SEC-297 fix.
*/
public void testFullDefaultTargetUrlDoesNotHaveContextPathPrepended() throws Exception {
MockHttpServletRequest request = createMockRequest();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
successHandler.setDefaultTargetUrl("https://monkeymachine.co.uk/");
successHandler.setAlwaysUseDefaultTargetUrl(true);
filter.setAuthenticationSuccessHandler(successHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("https://monkeymachine.co.uk/", response.getRedirectedUrl());
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
}
public void testNewSessionIsCreatedIfInvalidateSessionOnSuccessfulAuthenticationIsSet() throws Exception {
MockHttpServletRequest request = createMockRequest();
HttpSession oldSession = request.getSession();
oldSession.setAttribute("test","test");
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Setup our test object, to grant access
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setInvalidateSessionOnSuccessfulAuthentication(true);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setAuthenticationSuccessHandler(successHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
HttpSession newSession = request.getSession();
assertFalse(newSession.getId().equals(oldSession.getId()));
assertEquals("test", newSession.getAttribute("test"));
}
public void testAttributesAreNotMigratedToNewlyCreatedSessionIfMigrateAttributesIsFalse() throws Exception {
MockHttpServletRequest request = createMockRequest();
HttpSession oldSession = request.getSession();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setInvalidateSessionOnSuccessfulAuthentication(true);
filter.setMigrateInvalidatedSessionAttributes(false);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setAuthenticationSuccessHandler(successHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
HttpSession newSession = request.getSession();
assertFalse(newSession.getId().equals(oldSession.getId()));
assertNull(newSession.getAttribute("test"));
}
/**
* SEC-571
*/
public void testNoSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
MockHttpServletRequest request = createMockRequest();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
// Reject authentication, so exception would normally be stored in session
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
filter.setAllowSessionCreation(false);
filter.setAuthenticationFailureHandler(failureHandler);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setAuthenticationSuccessHandler(successHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertNull(request.getSession(false));
}
/**
* SEC-462
*/
public void testLoginErrorWithNoFailureUrlSendsUnauthorizedStatus() throws Exception {
MockHttpServletRequest request = createMockRequest();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setAuthenticationSuccessHandler(successHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
}
/**
* SEC-462
*/
public void testServerSideRedirectForwardsToFailureUrl() throws Exception {
MockHttpServletRequest request = createMockRequest();
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler);
failureHandler.setUseForward(true);
failureHandler.setDefaultFailureUrl("/error");
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/error", response.getForwardedUrl());
}
/**
* SEC-213
*/
public void testTargetUrlParameterIsUsedIfPresent() throws Exception {
MockHttpServletRequest request = createMockRequest();
request.setParameter("targetUrl", "/target");
MockFilterConfig config = new MockFilterConfig(null, null);
MockFilterChain chain = new MockFilterChain(true);
MockHttpServletResponse response = new MockHttpServletResponse();
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setAuthenticationSuccessHandler(successHandler);
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
successHandler.setTargetUrlParameter("targetUrl");
filter.setAuthenticationFailureHandler(failureHandler);
executeFilterInContainerSimulator(config, filter, request, response, chain);
assertEquals("/mycontext/target", response.getRedirectedUrl());
}
//~ Inner Classes ==================================================================================================
private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
private AuthenticationException exceptionToThrow;
private boolean grantAccess;
public MockAbstractProcessingFilter(boolean grantAccess) {
this();
setRememberMeServices(new NullRememberMeServices());
this.grantAccess = grantAccess;
this.exceptionToThrow = new BadCredentialsException("Mock requested to do so");
}
public MockAbstractProcessingFilter(AuthenticationException exceptionToThrow) {
this();
setRememberMeServices(new NullRememberMeServices());
this.grantAccess = false;
this.exceptionToThrow = exceptionToThrow;
}
private MockAbstractProcessingFilter() {
super("/j_mock_post");
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (grantAccess) {
return new UsernamePasswordAuthenticationToken("test", "test", AuthorityUtils.createAuthorityList("TEST"));
} else {
throw exceptionToThrow;
}
}
public boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return super.requiresAuthentication(request, response);
}
public int getOrder() {
return 0;
}
}
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
}

View File

@@ -0,0 +1,200 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui;
import junit.framework.TestCase;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.MockFilterConfig;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.ui.anonymous.AnonymousProcessingFilter;
import org.springframework.security.userdetails.memory.UserAttribute;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* Tests {@link AnonymousProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class AnonymousProcessingFilterTests extends TestCase {
//~ Constructors ===================================================================================================
public AnonymousProcessingFilterTests() {
super();
}
public AnonymousProcessingFilterTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
protected void setUp() throws Exception {
super.setUp();
SecurityContextHolder.clearContext();
}
protected void tearDown() throws Exception {
super.tearDown();
SecurityContextHolder.clearContext();
}
public void testDetectsMissingKey() throws Exception {
UserAttribute user = new UserAttribute();
user.setPassword("anonymousUsername");
user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
filter.setUserAttribute(user);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testDetectsUserAttribute() throws Exception {
AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
filter.setKey("qwerty");
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() throws Exception {
UserAttribute user = new UserAttribute();
user.setPassword("anonymousUsername");
user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
filter.setKey("qwerty");
filter.setUserAttribute(user);
assertTrue(filter.isRemoveAfterRequest());
filter.afterPropertiesSet();
assertEquals("qwerty", filter.getKey());
assertEquals(user, filter.getUserAttribute());
filter.setRemoveAfterRequest(false);
assertFalse(filter.isRemoveAfterRequest());
}
public void testOperationWhenAuthenticationExistsInContextHolder()
throws Exception {
// Put an Authentication object into the SecurityContextHolder
Authentication originalAuth = new TestingAuthenticationToken("user", "password",
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_A")});
SecurityContextHolder.getContext().setAuthentication(originalAuth);
// Setup our filter correctly
UserAttribute user = new UserAttribute();
user.setPassword("anonymousUsername");
user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
filter.setKey("qwerty");
filter.setUserAttribute(user);
filter.afterPropertiesSet();
// Test
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("x");
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
// Ensure filter didn't change our original object
assertEquals(originalAuth, SecurityContextHolder.getContext().getAuthentication());
}
public void testOperationWhenNoAuthenticationInSecurityContextHolder() throws Exception {
UserAttribute user = new UserAttribute();
user.setPassword("anonymousUsername");
user.addAuthority(new GrantedAuthorityImpl("ROLE_ANONYMOUS"));
AnonymousProcessingFilter filter = new AnonymousProcessingFilter();
filter.setKey("qwerty");
filter.setUserAttribute(user);
filter.setRemoveAfterRequest(false); // set to non-default value
filter.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("x");
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
assertEquals("anonymousUsername", auth.getPrincipal());
assertEquals(new GrantedAuthorityImpl("ROLE_ANONYMOUS"), auth.getAuthorities().get(0));
SecurityContextHolder.getContext().setAuthentication(null); // so anonymous fires again
// Now test operation if we have removeAfterRequest = true
filter.setRemoveAfterRequest(true); // set to default value
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
//~ Inner Classes ==================================================================================================
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
}

View File

@@ -0,0 +1,52 @@
package org.springframework.security.ui;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.security.providers.TestingAuthenticationToken;
/**
*
* @author Luke Taylor
* @version $Id$
*/
public class AuthenticationDetailsSourceImplTests {
@Test
public void buildDetailsReturnsExpectedAuthenticationDetails() {
AuthenticationDetailsSourceImpl ads = new AuthenticationDetailsSourceImpl();
AuthenticationDetails details = (AuthenticationDetails) ads.buildDetails("the context");
assertEquals("the context", details.getContext());
assertEquals(new AuthenticationDetails("the context"), details);
ads.setClazz(AuthenticationDetails.class);
details = (AuthenticationDetails) ads.buildDetails("another context");
assertEquals("another context", details.getContext());
}
@Test(expected=IllegalStateException.class)
public void nonMatchingConstructorIsRejected() {
AuthenticationDetailsSourceImpl ads = new AuthenticationDetailsSourceImpl();
ads.setClazz(String.class);
ads.buildDetails(new Object());
}
@Test(expected=IllegalStateException.class)
public void constructorTakingMultipleArgumentsIsRejected() {
AuthenticationDetailsSourceImpl ads = new AuthenticationDetailsSourceImpl();
ads.setClazz(TestingAuthenticationToken.class);
ads.buildDetails(null);
}
@Test
public void authenticationDetailsEqualsBehavesAsExpected() {
AuthenticationDetails details = new AuthenticationDetails("the context");
assertFalse((new AuthenticationDetails("different context")).equals(details));
assertFalse((new AuthenticationDetails(null)).equals(details));
assertFalse(details.equals(new AuthenticationDetails(null)));
assertFalse(details.equals("a string"));
// Just check toString() functions OK
details.toString();
(new AuthenticationDetails(null)).toString();
}
}

View File

@@ -0,0 +1,334 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.AccessDeniedException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.MockAuthenticationEntryPoint;
import org.springframework.security.MockPortResolver;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.anonymous.AnonymousAuthenticationToken;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.util.AuthorityUtils;
/**
* Tests {@link ExceptionTranslationFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class ExceptionTranslationFilterTests extends TestCase {
//~ Methods ========================================================================================================
protected void tearDown() throws Exception {
super.tearDown();
SecurityContextHolder.clearContext();
}
private static String getSavedRequestUrl(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return null;
}
SavedRequest savedRequest = (SavedRequest) session.getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY);
return savedRequest.getFullRequestUrl();
}
public void testAccessDeniedWhenAnonymous() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
request.setServerPort(80);
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/secure/page.html");
// Setup the FilterChain to thrown an access denied exception
MockFilterChain chain = new MockFilterChain(true, false, false, false);
// Setup SecurityContextHolder, as filter needs to check if user is
// anonymous
SecurityContextHolder.getContext().setAuthentication(
new AnonymousAuthenticationToken("ignored", "ignored", AuthorityUtils.createAuthorityList("IGNORED")));
// Test
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
assertEquals("http://www.example.com/mycontext/secure/page.html", getSavedRequestUrl(request));
}
public void testAccessDeniedWhenNonAnonymous() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
// Setup the FilterChain to thrown an access denied exception
MockFilterChain chain = new MockFilterChain(true, false, false, false);
// Setup SecurityContextHolder, as filter needs to check if user is
// anonymous
SecurityContextHolder.getContext().setAuthentication(null);
// Setup a new AccessDeniedHandlerImpl that will do a "forward"
AccessDeniedHandlerImpl adh = new AccessDeniedHandlerImpl();
adh.setErrorPage("/error.jsp");
// Test
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
filter.setAccessDeniedHandler(adh);
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
assertEquals(403, response.getStatus());
assertEquals(AccessDeniedException.class, request.getAttribute(
AccessDeniedHandlerImpl.SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY).getClass());
}
public void testGettersSetters() {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
assertTrue(filter.getAuthenticationEntryPoint() != null);
filter.setPortResolver(new MockPortResolver(80, 443));
assertTrue(filter.getPortResolver() != null);
}
public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWhenAuthenticationException() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
request.setServerPort(80);
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/secure/page.html");
// Setup the FilterChain to thrown an authentication failure exception
MockFilterChain chain = new MockFilterChain(false, true, false, false);
// Test
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
filter.setPortResolver(new MockPortResolver(80, 443));
/*
* Disabled the call to afterPropertiesSet as it requires
* applicationContext to be injected before it is invoked. We do not
* have this filter configured in IOC for this test hence no
* ApplicationContext
*/
// filter.afterPropertiesSet();
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
assertEquals("http://www.example.com/mycontext/secure/page.html", getSavedRequestUrl(request));
}
public void testRedirectedToLoginFormAndSessionShowsOriginalTargetWithExoticPortWhenAuthenticationException()
throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
request.setServerPort(8080);
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/mycontext");
request.setRequestURI("/mycontext/secure/page.html");
// Setup the FilterChain to thrown an authentication failure exception
MockFilterChain chain = new MockFilterChain(false, true, false, false);
// Test
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
filter.setPortResolver(new MockPortResolver(8080, 8443));
/*
* Disabled the call to afterPropertiesSet as it requires
* applicationContext to be injected before it is invoked. We do not
* have this filter configured in IOC for this test hence no
* ApplicationContext
*/
// filter.afterPropertiesSet();
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
assertEquals("/mycontext/login.jsp", response.getRedirectedUrl());
assertEquals("http://www.example.com:8080/mycontext/secure/page.html", getSavedRequestUrl(request));
}
public void testSavedRequestIsNotStoredForPostIfJustUseSaveRequestOnGetIsSet() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setJustUseSavedRequestOnGet(true);
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
filter.setPortResolver(new MockPortResolver(8080, 8443));
MockHttpServletRequest request = new MockHttpServletRequest();
MockFilterChain chain = new MockFilterChain(false, true, false, false);
request.setMethod("POST");
filter.doFilter(request, new MockHttpServletResponse(), chain);
assertTrue(request.getSession().getAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY) == null);
}
public void testStartupDetectsMissingAuthenticationEntryPoint() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertEquals("authenticationEntryPoint must be specified", expected.getMessage());
}
}
public void testStartupDetectsMissingPortResolver() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
filter.setPortResolver(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException expected) {
assertEquals("portResolver must be specified", expected.getMessage());
}
}
public void testSuccessfulAccessGrant() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/secure/page.html");
// Setup the FilterChain to thrown no exceptions
MockFilterChain chain = new MockFilterChain(false, false, false, false);
// Test
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("/login.jsp"));
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
}
public void testSuccessfulStartupAndShutdownDown() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.init(null);
filter.destroy();
assertTrue(true);
}
public void testThrowIOException() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
/*
* Disabled the call to afterPropertiesSet as it requires
* applicationContext to be injected before it is invoked. We do not
* have this filter configured in IOC for this test hence no
* ApplicationContext
*/
// filter.afterPropertiesSet();
try {
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false,
false, false, true));
fail("Should have thrown IOException");
}
catch (IOException e) {
assertNull("The IOException thrown should not have been wrapped", e.getCause());
}
}
public void testThrowServletException() throws Exception {
ExceptionTranslationFilter filter = new ExceptionTranslationFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint(""));
/*
* Disabled the call to afterPropertiesSet as it requires
* applicationContext to be injected before it is invoked. We do not
* have this filter configured in IOC for this test hence no
* ApplicationContext
*/
// filter.afterPropertiesSet();
try {
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), new MockFilterChain(false,
false, true, false));
fail("Should have thrown ServletException");
}
catch (ServletException e) {
assertNull("The ServletException thrown should not have been wrapped", e.getCause());
}
}
// ~ Inner Classes =================================================================================================
private class MockFilterChain implements FilterChain {
private boolean throwAccessDenied;
private boolean throwAuthenticationFailure;
private boolean throwIOException;
private boolean throwServletException;
public MockFilterChain(boolean throwAccessDenied, boolean throwAuthenticationFailure,
boolean throwServletException, boolean throwIOException) {
this.throwAccessDenied = throwAccessDenied;
this.throwAuthenticationFailure = throwAuthenticationFailure;
this.throwServletException = throwServletException;
this.throwIOException = throwIOException;
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (throwAccessDenied) {
throw new AccessDeniedException("As requested");
}
if (throwAuthenticationFailure) {
throw new BadCredentialsException("As requested");
}
if (throwServletException) {
throw new ServletException("As requested");
}
if (throwIOException) {
throw new IOException("As requested");
}
}
}
}

View File

@@ -0,0 +1,22 @@
package org.springframework.security.ui;
import static org.junit.Assert.*;
import org.junit.Test;
public class SavedRequestAwareAuthenticationSuccessHandlerTests {
@Test
public void defaultUrlMuststartWithSlashOrHttpScheme() {
SavedRequestAwareAuthenticationSuccessHandler handler = new SavedRequestAwareAuthenticationSuccessHandler();
handler.setDefaultTargetUrl("/acceptableRelativeUrl");
handler.setDefaultTargetUrl("http://some.site.org/index.html");
handler.setDefaultTargetUrl("https://some.site.org/index.html");
try {
handler.setDefaultTargetUrl("missingSlash");
fail("Shouldn't accept default target without leading slash");
} catch (IllegalArgumentException expected) {}
}
}

View File

@@ -0,0 +1,79 @@
package org.springframework.security.ui;
import static org.junit.Assert.*;
import javax.servlet.http.HttpServletRequest;
import org.junit.After;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.web.HttpSessionSecurityContextRepository;
import org.springframework.security.providers.TestingAuthenticationToken;
/**
*
* @author Luke Taylor
* @version $Id$
*/
public class SessionFixationProtectionFilterTests {
@After
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test
public void newSessionShouldNotBeCreatedIfNoSessionExists() throws Exception {
SessionFixationProtectionFilter filter = new SessionFixationProtectionFilter();
HttpServletRequest request = new MockHttpServletRequest();
authenticateUser();
filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
assertNull(request.getSession(false));
}
@Test
public void newSessionBeCreatedIfAuthenticatedOccurredDuringRequest() throws Exception {
SessionFixationProtectionFilter filter = new SessionFixationProtectionFilter();
HttpServletRequest request = new MockHttpServletRequest();
String sessionId = request.getSession().getId();
authenticateUser();
filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
assertFalse(sessionId.equals(request.getSession().getId()));
}
@Test
public void newSessionShouldNotBeCreatedIfSessionExistsAndUserIsNotAuthenticated() throws Exception {
SessionFixationProtectionFilter filter = new SessionFixationProtectionFilter();
HttpServletRequest request = new MockHttpServletRequest();
String sessionId = request.getSession().getId();
filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
assertEquals(sessionId, request.getSession().getId());
}
@Test
public void newSessionShouldNotBeCreatedIfUserIsAlreadyAuthenticated() throws Exception {
SessionFixationProtectionFilter filter = new SessionFixationProtectionFilter();
HttpServletRequest request = new MockHttpServletRequest();
String sessionId = request.getSession().getId();
authenticateUser();
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
SecurityContextHolder.getContext());
filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
assertEquals(sessionId, request.getSession().getId());
}
private void authenticateUser() {
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "pass"));
}
}

View File

@@ -0,0 +1,89 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.basicauth;
import junit.framework.TestCase;
import org.springframework.security.DisabledException;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* Tests {@link BasicProcessingFilterEntryPoint}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicProcessingFilterEntryPointTests extends TestCase {
//~ Constructors ===================================================================================================
public BasicProcessingFilterEntryPointTests() {
super();
}
public BasicProcessingFilterEntryPointTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(BasicProcessingFilterEntryPointTests.class);
}
public final void setUp() throws Exception {
super.setUp();
}
public void testDetectsMissingRealmName() throws Exception {
BasicProcessingFilterEntryPoint ep = new BasicProcessingFilterEntryPoint();
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("realmName must be specified", expected.getMessage());
}
}
public void testGettersSetters() {
BasicProcessingFilterEntryPoint ep = new BasicProcessingFilterEntryPoint();
ep.setRealmName("realm");
assertEquals("realm", ep.getRealmName());
}
public void testNormalOperation() throws Exception {
BasicProcessingFilterEntryPoint ep = new BasicProcessingFilterEntryPoint();
ep.setRealmName("hello");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
MockHttpServletResponse response = new MockHttpServletResponse();
//ep.afterPropertiesSet();
String msg = "These are the jokes kid";
ep.commence(request, response, new DisabledException(msg));
assertEquals(401, response.getStatus());
assertEquals(msg, response.getErrorMessage());
assertEquals("Basic realm=\"hello\"", response.getHeader("WWW-Authenticate"));
}
}

View File

@@ -0,0 +1,261 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.basicauth;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.security.matcher.AuthenticationMatcher.anAuthenticationWithUsernameAndPassword;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import org.apache.commons.codec.binary.Base64;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationManager;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.MockAuthenticationEntryPoint;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.MockFilterConfig;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
/**
* Tests {@link BasicProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class BasicProcessingFilterTests {
//~ Instance fields ================================================================================================
private BasicProcessingFilter filter;
private Mockery jmock = new JUnit4Mockery();
//~ Methods ========================================================================================================
private MockHttpServletResponse executeFilterInContainerSimulator(Filter filter, final ServletRequest request,
final boolean expectChainToProceed) throws ServletException, IOException {
filter.init(new MockFilterConfig());
final MockHttpServletResponse response = new MockHttpServletResponse();
Mockery jmockContext = new JUnit4Mockery();
final FilterChain chain = jmockContext.mock(FilterChain.class);
jmockContext.checking(new Expectations() {{
exactly(expectChainToProceed ? 1 : 0).of(chain).doFilter(request, response);
}});
filter.doFilter(request, response, chain);
filter.destroy();
jmockContext.assertIsSatisfied();
return response;
}
@Before
public void setUp() throws Exception {
SecurityContextHolder.clearContext();
final AuthenticationManager manager = jmock.mock(AuthenticationManager.class);
final Authentication rod =
new UsernamePasswordAuthenticationToken("rod", "koala", AuthorityUtils.createAuthorityList("ROLE_1"));
jmock.checking(new Expectations() {{
allowing(manager).authenticate(with(anAuthenticationWithUsernameAndPassword("rod", "koala")));
will(returnValue(rod));
allowing(manager).authenticate(with(any(Authentication.class)));
will(throwException(new BadCredentialsException("")));
}});
filter = new BasicProcessingFilter();
filter.setAuthenticationManager(manager);
filter.setAuthenticationEntryPoint(new BasicProcessingFilterEntryPoint());
}
@After
public void clearContext() throws Exception {
SecurityContextHolder.clearContext();
}
@Test
public void testFilterIgnoresRequestsContainingNoAuthorizationHeader() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath("/some_file.html");
// Test
executeFilterInContainerSimulator(filter, request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testGettersSetters() {
BasicProcessingFilter filter = new BasicProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
assertTrue(filter.getAuthenticationManager() != null);
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("sx"));
assertTrue(filter.getAuthenticationEntryPoint() != null);
}
@Test
public void testInvalidBasicAuthorizationTokenIsIgnored() throws Exception {
// Setup our HTTP request
String token = "NOT_A_VALID_TOKEN_AS_MISSING_COLON";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
// The filter chain shouldn't proceed
executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testNormalOperation() throws Exception {
// Setup our HTTP request
String token = "rod:koala";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
// Test
assertNull(SecurityContextHolder.getContext().getAuthentication());
executeFilterInContainerSimulator(filter, request, true);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("rod", SecurityContextHolder.getContext().getAuthentication().getName());
}
@Test
public void testOtherAuthorizationSchemeIsIgnored() throws Exception {
// Setup our HTTP request
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "SOME_OTHER_AUTHENTICATION_SCHEME");
request.setServletPath("/some_file.html");
// Test
executeFilterInContainerSimulator(filter, request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testStartupDetectsMissingAuthenticationEntryPoint() throws Exception {
try {
BasicProcessingFilter filter = new BasicProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("An AuthenticationEntryPoint is required", expected.getMessage());
}
}
@Test(expected=IllegalArgumentException.class)
public void testStartupDetectsMissingAuthenticationManager() throws Exception {
BasicProcessingFilter filter = new BasicProcessingFilter();
filter.setAuthenticationEntryPoint(new MockAuthenticationEntryPoint("x"));
filter.afterPropertiesSet();
}
@Test
public void testSuccessLoginThenFailureLoginResultsInSessionLosingToken() throws Exception {
// Setup our HTTP request
String token = "rod:koala";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
// Test
executeFilterInContainerSimulator(filter, request, true);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("rod", SecurityContextHolder.getContext().getAuthentication().getName());
// NOW PERFORM FAILED AUTHENTICATION
// Setup our HTTP request
token = "otherUser:WRONG_PASSWORD";
request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
// Test - the filter chain will not be invoked, as we get a 403 forbidden response
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testWrongPasswordContinuesFilterChainIfIgnoreFailureIsTrue() throws Exception {
// Setup our HTTP request
String token = "rod:WRONG_PASSWORD";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
filter.setIgnoreFailure(true);
assertTrue(filter.isIgnoreFailure());
// Test - the filter chain will be invoked, as we've set ignoreFailure = true
executeFilterInContainerSimulator(filter, request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testWrongPasswordReturnsForbiddenIfIgnoreFailureIsFalse() throws Exception {
// Setup our HTTP request
String token = "rod:WRONG_PASSWORD";
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Authorization", "Basic " + new String(Base64.encodeBase64(token.getBytes())));
request.setServletPath("/some_file.html");
request.setSession(new MockHttpSession());
assertFalse(filter.isIgnoreFailure());
// Test - the filter chain will not be invoked, as we get a 403 forbidden response
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
}

View File

@@ -0,0 +1,153 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.digestauth;
import junit.framework.TestCase;
import org.springframework.security.DisabledException;
import org.springframework.security.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* Tests {@link DigestProcessingFilterEntryPoint}.
*
* @author Ben Alex
* @version $Id$
*/
public class DigestProcessingFilterEntryPointTests extends TestCase {
//~ Methods ========================================================================================================
private void checkNonceValid(String nonce) {
// Check the nonce seems to be generated correctly
// format of nonce is:
// base64(expirationTime + ":" + md5Hex(expirationTime + ":" + key))
assertTrue(Base64.isArrayByteBase64(nonce.getBytes()));
String decodedNonce = new String(Base64.decodeBase64(nonce.getBytes()));
String[] nonceTokens = StringUtils.delimitedListToStringArray(decodedNonce, ":");
assertEquals(2, nonceTokens.length);
String expectedNonceSignature = DigestUtils.md5Hex(nonceTokens[0] + ":" + "key");
assertEquals(expectedNonceSignature, nonceTokens[1]);
}
public void testDetectsMissingKey() throws Exception {
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
ep.setRealmName("realm");
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("key must be specified", expected.getMessage());
}
}
public void testDetectsMissingRealmName() throws Exception {
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
ep.setKey("dcdc");
ep.setNonceValiditySeconds(12);
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertEquals("realmName must be specified", expected.getMessage());
}
}
public void testGettersSetters() {
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
assertEquals(300, ep.getNonceValiditySeconds()); // 5 mins default
ep.setRealmName("realm");
assertEquals("realm", ep.getRealmName());
ep.setKey("dcdc");
assertEquals("dcdc", ep.getKey());
ep.setNonceValiditySeconds(12);
assertEquals(12, ep.getNonceValiditySeconds());
}
public void testNormalOperation() throws Exception {
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
ep.setRealmName("hello");
ep.setKey("key");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
MockHttpServletResponse response = new MockHttpServletResponse();
ep.afterPropertiesSet();
ep.commence(request, response, new DisabledException("foobar"));
// Check response is properly formed
assertEquals(401, response.getStatus());
assertEquals(true, response.getHeader("WWW-Authenticate").toString().startsWith("Digest "));
// Break up response header
String header = response.getHeader("WWW-Authenticate").toString().substring(7);
String[] headerEntries = StringUtils.commaDelimitedListToStringArray(header);
Map<String,String> headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"");
assertEquals("hello", headerMap.get("realm"));
assertEquals("auth", headerMap.get("qop"));
assertNull(headerMap.get("stale"));
checkNonceValid((String) headerMap.get("nonce"));
}
public void testOperationIfDueToStaleNonce() throws Exception {
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
ep.setRealmName("hello");
ep.setKey("key");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
MockHttpServletResponse response = new MockHttpServletResponse();
ep.afterPropertiesSet();
ep.commence(request, response, new NonceExpiredException("expired nonce"));
// Check response is properly formed
assertEquals(401, response.getStatus());
assertTrue(response.getHeader("WWW-Authenticate").toString().startsWith("Digest "));
// Break up response header
String header = response.getHeader("WWW-Authenticate").toString().substring(7);
String[] headerEntries = StringUtils.commaDelimitedListToStringArray(header);
Map<String,String> headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"");
assertEquals("hello", headerMap.get("realm"));
assertEquals("auth", headerMap.get("qop"));
assertEquals("true", headerMap.get("stale"));
checkNonceValid((String) headerMap.get("nonce"));
}
}

View File

@@ -0,0 +1,421 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.digestauth;
import static org.junit.Assert.*;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.MockFilterConfig;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.dao.cache.NullUserCache;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.memory.InMemoryDaoImpl;
import org.springframework.security.userdetails.memory.UserMap;
import org.springframework.security.userdetails.memory.UserMapEditor;
import org.springframework.security.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
/**
* Tests {@link DigestProcessingFilter}.
*
* @author Ben Alex
* @author Luke Taylor
* @version $Id$
*/
public class DigestProcessingFilterTests {
//~ Static fields/initializers =====================================================================================
private static final String NC = "00000002";
private static final String CNONCE = "c822c727a648aba7";
private static final String REALM = "The Actual, Correct Realm Name";
private static final String KEY = "springsecurity";
private static final String QOP = "auth";
private static final String USERNAME = "rod,ok";
private static final String PASSWORD = "koala";
private static final String REQUEST_URI = "/some_file.html";
/**
* A standard valid nonce with a validity period of 60 seconds
*/
private static final String NONCE = generateNonce(60);
//~ Instance fields ================================================================================================
// private ApplicationContext ctx;
private DigestProcessingFilter filter;
private MockHttpServletRequest request;
//~ Methods ========================================================================================================
private String createAuthorizationHeader(String username, String realm, String nonce, String uri,
String responseDigest, String qop, String nc, String cnonce) {
return "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + uri
+ "\", response=\"" + responseDigest + "\", qop=" + qop + ", nc=" + nc + ", cnonce=\"" + cnonce + "\"";
}
private MockHttpServletResponse executeFilterInContainerSimulator(Filter filter, final ServletRequest request,
final boolean expectChainToProceed) throws ServletException, IOException {
filter.init(new MockFilterConfig());
final MockHttpServletResponse response = new MockHttpServletResponse();
Mockery jmockContext = new JUnit4Mockery();
final FilterChain chain = jmockContext.mock(FilterChain.class);
jmockContext.checking(new Expectations() {{
exactly(expectChainToProceed ? 1 : 0).of(chain).doFilter(request, response);
}});
filter.doFilter(request, response, chain);
filter.destroy();
jmockContext.assertIsSatisfied();
return response;
}
private static String generateNonce(int validitySeconds) {
long expiryTime = System.currentTimeMillis() + (validitySeconds * 1000);
String signatureValue = new String(DigestUtils.md5Hex(expiryTime + ":" + KEY));
String nonceValue = expiryTime + ":" + signatureValue;
return new String(Base64.encodeBase64(nonceValue.getBytes()));
}
@After
public void clearContext() throws Exception {
SecurityContextHolder.clearContext();
}
@Before
public void setUp() throws Exception {
SecurityContextHolder.clearContext();
// Create User Details Service
InMemoryDaoImpl dao = new InMemoryDaoImpl();
UserMapEditor editor = new UserMapEditor();
editor.setAsText("rod,ok=koala,ROLE_ONE,ROLE_TWO,enabled\r\n");
dao.setUserMap((UserMap) editor.getValue());
DigestProcessingFilterEntryPoint ep = new DigestProcessingFilterEntryPoint();
ep.setRealmName(REALM);
ep.setKey(KEY);
filter = new DigestProcessingFilter();
filter.setUserDetailsService(dao);
filter.setAuthenticationEntryPoint(ep);
request = new MockHttpServletRequest("GET", REQUEST_URI);
request.setServletPath(REQUEST_URI);
}
@Test
public void testExpiredNonceReturnsForbiddenWithStaleHeader()
throws Exception {
String nonce = generateNonce(0);
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, nonce, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
Thread.sleep(1000); // ensures token expired
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
String header = response.getHeader("WWW-Authenticate").toString().substring(7);
String[] headerEntries = StringUtils.commaDelimitedListToStringArray(header);
Map<String,String> headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\"");
assertEquals("true", headerMap.get("stale"));
}
@Test
public void testFilterIgnoresRequestsContainingNoAuthorizationHeader()
throws Exception {
executeFilterInContainerSimulator(filter, request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testGettersSetters() {
DigestProcessingFilter filter = new DigestProcessingFilter();
filter.setUserDetailsService(new InMemoryDaoImpl());
assertTrue(filter.getUserDetailsService() != null);
filter.setAuthenticationEntryPoint(new DigestProcessingFilterEntryPoint());
assertTrue(filter.getAuthenticationEntryPoint() != null);
filter.setUserCache(null);
assertNull(filter.getUserCache());
filter.setUserCache(new NullUserCache());
assertNotNull(filter.getUserCache());
}
@Test
public void testInvalidDigestAuthorizationTokenGeneratesError()
throws Exception {
String token = "NOT_A_VALID_TOKEN_AS_MISSING_COLON";
request.addHeader("Authorization", "Digest " + new String(Base64.encodeBase64(token.getBytes())));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertEquals(401, response.getStatus());
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test
public void testMalformedHeaderReturnsForbidden() throws Exception {
request.addHeader("Authorization", "Digest scsdcsdc");
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testNonBase64EncodedNonceReturnsForbidden() throws Exception {
String nonce = "NOT_BASE_64_ENCODED";
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, nonce, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testNonceWithIncorrectSignatureForNumericFieldReturnsForbidden() throws Exception {
String nonce = new String(Base64.encodeBase64("123456:incorrectStringPassword".getBytes()));
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, nonce, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testNonceWithNonNumericFirstElementReturnsForbidden() throws Exception {
String nonce = new String(Base64.encodeBase64("hello:ignoredSecondElement".getBytes()));
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, nonce, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testNonceWithoutTwoColonSeparatedElementsReturnsForbidden() throws Exception {
String nonce = new String(Base64.encodeBase64("a base 64 string without a colon".getBytes()));
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, nonce, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, nonce, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void testNormalOperationWhenPasswordIsAlreadyEncoded() throws Exception {
String encodedPassword = DigestProcessingFilter.encodePasswordInA1Format(USERNAME, REALM, PASSWORD);
String responseDigest = DigestProcessingFilter.generateDigest(true, USERNAME, REALM, encodedPassword, "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
executeFilterInContainerSimulator(filter, request, true);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(USERNAME,
((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
}
@Test
public void testNormalOperationWhenPasswordNotAlreadyEncoded() throws Exception {
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
executeFilterInContainerSimulator(filter, request, true);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(USERNAME,
((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername());
}
@Test
public void otherAuthorizationSchemeIsIgnored()
throws Exception {
request.addHeader("Authorization", "SOME_OTHER_AUTHENTICATION_SCHEME");
executeFilterInContainerSimulator(filter, request, true);
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
@Test(expected=IllegalArgumentException.class)
public void startupDetectsMissingAuthenticationEntryPoint() throws Exception {
DigestProcessingFilter filter = new DigestProcessingFilter();
filter.setUserDetailsService(new InMemoryDaoImpl());
filter.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void startupDetectsMissingUserDetailsService() throws Exception {
DigestProcessingFilter filter = new DigestProcessingFilter();
filter.setAuthenticationEntryPoint(new DigestProcessingFilterEntryPoint());
filter.afterPropertiesSet();
}
@Test
public void successfulLoginThenFailedLoginResultsInSessionLosingToken() throws Exception {
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
executeFilterInContainerSimulator(filter, request, true);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
// Now retry, giving an invalid nonce
responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, "WRONG_PASSWORD", "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request = new MockHttpServletRequest();
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
// Check we lost our previous authentication
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void wrongCnonceBasedOnDigestReturnsForbidden() throws Exception {
String cnonce = "NOT_SAME_AS_USED_FOR_DIGEST_COMPUTATION";
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, PASSWORD, "GET",
REQUEST_URI, QOP, NONCE, NC, "DIFFERENT_CNONCE");
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, cnonce));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void wrongDigestReturnsForbidden() throws Exception {
String password = "WRONG_PASSWORD";
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, REALM, password, "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void wrongRealmReturnsForbidden() throws Exception {
String realm = "WRONG_REALM";
String responseDigest = DigestProcessingFilter.generateDigest(false, USERNAME, realm, PASSWORD, "GET",
REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, realm, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
@Test
public void wrongUsernameReturnsForbidden() throws Exception {
String responseDigest = DigestProcessingFilter.generateDigest(false, "NOT_A_KNOWN_USER", REALM, PASSWORD,
"GET", REQUEST_URI, QOP, NONCE, NC, CNONCE);
request.addHeader("Authorization",
createAuthorizationHeader(USERNAME, REALM, NONCE, REQUEST_URI, responseDigest, QOP, NC, CNONCE));
MockHttpServletResponse response = executeFilterInContainerSimulator(filter, request, false);
assertNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals(401, response.getStatus());
}
}

View File

@@ -0,0 +1,38 @@
package org.springframework.security.ui.logout;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* @author Luke Taylor
* @version $Id$
*/
public class LogoutHandlerTests extends TestCase {
LogoutFilter filter;
protected void setUp() throws Exception {
filter = new LogoutFilter("/success", new SecurityContextLogoutHandler());
}
public void testRequiresLogoutUrlWorksWithPathParams() {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setRequestURI("/j_spring_security_logout;someparam=blah?otherparam=blah");
assertTrue(filter.requiresLogout(request, response));
}
public void testRequiresLogoutUrlWorksWithQueryParams() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("/context");
MockHttpServletResponse response = new MockHttpServletResponse();
request.setRequestURI("/context/j_spring_security_logout?param=blah");
assertTrue(filter.requiresLogout(request, response));
}
}

View File

@@ -0,0 +1,56 @@
package org.springframework.security.ui.preauth;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.context.SecurityContextHolder;
public class AbstractPreAuthenticatedProcessingFilterTests {
private AbstractPreAuthenticatedProcessingFilter filter;
@Before
public void createFilter() {
filter = new AbstractPreAuthenticatedProcessingFilter() {
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "n/a";
}
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
return "doesntmatter";
}
public int getOrder() {
return 0;
}
};
SecurityContextHolder.getContext().setAuthentication(null);
}
@Test
public void filterChainProceedsOnFailedAuthenticationByDefault() throws Exception {
filter.setAuthenticationManager(new MockAuthenticationManager(false));
filter.afterPropertiesSet();
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), mock(FilterChain.class));
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
/* SEC-881 */
@Test(expected=BadCredentialsException.class)
public void exceptionIsThrownOnFailedAuthenticationIfContinueFilterChainOnUnsuccessfulAuthenticationSetToFalse() throws Exception {
filter.setContinueFilterChainOnUnsuccessfulAuthentication(false);
filter.setAuthenticationManager(new MockAuthenticationManager(false));
filter.afterPropertiesSet();
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), mock(FilterChain.class));
assertNull(SecurityContextHolder.getContext().getAuthentication());
}
}

View File

@@ -0,0 +1,61 @@
package org.springframework.security.ui.preauth;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.util.AuthorityUtils;
/**
* @author TSARDD
*/
public class PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetailsTests {
List<GrantedAuthority> gas = AuthorityUtils.createAuthorityList("Role1", "Role2");
@Test
public void testToString() {
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
getRequest("testUser", new String[] {}));
details.setGrantedAuthorities(gas);
String toString = details.toString();
assertTrue("toString should contain Role1", toString.contains("Role1"));
assertTrue("toString should contain Role2", toString.contains("Role2"));
}
@Test
public void testGetSetPreAuthenticatedGrantedAuthorities() {
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
getRequest("testUser", new String[] {}));
details.setGrantedAuthorities(gas);
List<GrantedAuthority> returnedGas = details.getGrantedAuthorities();
assertTrue("Collections do not contain same elements; expected: " + gas + ", returned: " + returnedGas,
gas.containsAll(returnedGas) && returnedGas.containsAll(gas));
}
@Test(expected=IllegalArgumentException.class)
public void testGetWithoutSetPreAuthenticatedGrantedAuthorities() {
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
getRequest("testUser", new String[] {}));
details.getGrantedAuthorities();
}
private HttpServletRequest getRequest(final String userName,final String[] aRoles) {
MockHttpServletRequest req = new MockHttpServletRequest() {
private Set<String> roles = new HashSet<String>(Arrays.asList(aRoles));
public boolean isUserInRole(String arg0) {
return roles.contains(arg0);
}
};
req.setRemoteUser(userName);
return req;
}
}

View File

@@ -0,0 +1,42 @@
package org.springframework.security.ui.preauth;
import org.springframework.security.AuthenticationCredentialsNotFoundException;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
/**
*
* @author TSARDD
* @since 18-okt-2007
*/
public class PreAuthenticatedProcessingFilterEntryPointTests extends TestCase {
public void testGetSetOrder() {
PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
fep.setOrder(333);
assertEquals(fep.getOrder(), 333);
}
public void testCommence() {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse resp = new MockHttpServletResponse();
PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
try {
fep.commence(req,resp,new AuthenticationCredentialsNotFoundException("test"));
assertEquals("Incorrect status",resp.getStatus(),HttpServletResponse.SC_FORBIDDEN);
} catch (IOException e) {
fail("Unexpected exception thrown: "+e);
} catch (ServletException e) {
fail("Unexpected exception thrown: "+e);
}
}
}

View File

@@ -0,0 +1,65 @@
package org.springframework.security.ui.preauth;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.ui.FilterChainOrder;
import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class PreAuthenticatedProcessingFilterTests extends TestCase {
protected void setUp() throws Exception {
SecurityContextHolder.clearContext();
}
public void testAfterPropertiesSet() {
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
try {
filter.afterPropertiesSet();
fail("AfterPropertiesSet didn't throw expected exception");
} catch (IllegalArgumentException expected) {
} catch (Exception unexpected) {
fail("AfterPropertiesSet throws unexpected exception");
}
}
public final void testDoFilterAuthenticated() throws Exception {
testDoFilter(true);
}
public final void testDoFilterUnauthenticated() throws Exception {
testDoFilter(false);
}
private final void testDoFilter(boolean grantAccess) throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
getFilter(grantAccess).doFilter(req,res,new MockFilterChain());
assertEquals(grantAccess,null!= SecurityContextHolder.getContext().getAuthentication());
}
private static final ConcretePreAuthenticatedProcessingFilter getFilter(boolean grantAccess) throws Exception {
ConcretePreAuthenticatedProcessingFilter filter = new ConcretePreAuthenticatedProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(grantAccess));
filter.afterPropertiesSet();
return filter;
}
private static final class ConcretePreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpRequest) {
return "testPrincipal";
}
protected Object getPreAuthenticatedCredentials(HttpServletRequest httpRequest) {
return "testCredentials";
}
public int getOrder() {
return FilterChainOrder.PRE_AUTH_FILTER;
}
}
}

View File

@@ -0,0 +1,85 @@
package org.springframework.security.ui.preauth.header;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.ui.preauth.PreAuthenticatedCredentialsNotFoundException;
/**
*
* @author Luke Taylor
* @version $Id$
*/
public class RequestHeaderPreAuthenticatedProcessingFilterTests {
@After
@Before
public void clearContext() {
SecurityContextHolder.clearContext();
}
@Test(expected = PreAuthenticatedCredentialsNotFoundException.class)
public void rejectsMissingHeader() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
RequestHeaderPreAuthenticatedProcessingFilter filter = new RequestHeaderPreAuthenticatedProcessingFilter();
filter.getOrder();
filter.doFilter(request, response, chain);
}
@Test
public void defaultsToUsingSiteminderHeader() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("SM_USER", "cat");
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
RequestHeaderPreAuthenticatedProcessingFilter filter = new RequestHeaderPreAuthenticatedProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.doFilter(request, response, chain);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("cat", SecurityContextHolder.getContext().getAuthentication().getName());
assertEquals("N/A", SecurityContextHolder.getContext().getAuthentication().getCredentials());
}
@Test
public void alternativeHeaderNameIsSupported() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("myUsernameHeader", "wolfman");
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
RequestHeaderPreAuthenticatedProcessingFilter filter = new RequestHeaderPreAuthenticatedProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setPrincipalRequestHeader("myUsernameHeader");
filter.doFilter(request, response, chain);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("wolfman", SecurityContextHolder.getContext().getAuthentication().getName());
}
@Test
public void credentialsAreRetrievedIfHeaderNameIsSet() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
RequestHeaderPreAuthenticatedProcessingFilter filter = new RequestHeaderPreAuthenticatedProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setCredentialsRequestHeader("myCredentialsHeader");
request.addHeader("SM_USER", "cat");
request.addHeader("myCredentialsHeader", "catspassword");
filter.doFilter(request, response, chain);
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
assertEquals("catspassword", SecurityContextHolder.getContext().getAuthentication().getCredentials());
}
}

View File

@@ -0,0 +1,149 @@
package org.springframework.security.ui.preauth.j2ee;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
import org.springframework.security.authoritymapping.MappableAttributesRetriever;
import org.springframework.security.authoritymapping.Attributes2GrantedAuthoritiesMapper;
import org.springframework.security.authoritymapping.SimpleMappableAttributesRetriever;
import org.springframework.security.authoritymapping.SimpleAttributes2GrantedAuthoritiesMapper;
import org.springframework.security.ui.preauth.PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails;
import org.springframework.security.GrantedAuthority;
import org.springframework.mock.web.MockHttpServletRequest;
/**
*
* @author TSARDD
*/
public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSourceTests extends TestCase {
public final void testAfterPropertiesSetException() {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource t = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
try {
t.afterPropertiesSet();
fail("AfterPropertiesSet didn't throw expected exception");
} catch (IllegalArgumentException expected) {
} catch (Exception unexpected) {
fail("AfterPropertiesSet throws unexpected exception");
}
}
public final void testBuildDetailsHttpServletRequestNoMappedNoUserRoles() {
String[] mappedRoles = new String[] {};
String[] roles = new String[] {};
String[] expectedRoles = new String[] {};
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestNoMappedUnmappedUserRoles() {
String[] mappedRoles = new String[] {};
String[] roles = new String[] { "Role1", "Role2" };
String[] expectedRoles = new String[] {};
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestNoUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] roles = new String[] {};
String[] expectedRoles = new String[] {};
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestAllUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestUnmappedUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] roles = new String[] { "Role1", "Role2", "Role3", "Role4", "Role5" };
String[] expectedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestPartialUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] roles = new String[] { "Role2", "Role3" };
String[] expectedRoles = new String[] { "Role2", "Role3" };
testDetails(mappedRoles, roles, expectedRoles);
}
public final void testBuildDetailsHttpServletRequestPartialAndUnmappedUserRoles() {
String[] mappedRoles = new String[] { "Role1", "Role2", "Role3", "Role4" };
String[] roles = new String[] { "Role2", "Role3", "Role5" };
String[] expectedRoles = new String[] { "Role2", "Role3" };
testDetails(mappedRoles, roles, expectedRoles);
}
private void testDetails(String[] mappedRoles, String[] userRoles, String[] expectedRoles) {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource src = getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(mappedRoles);
Object o = src.buildDetails(getRequest("testUser", userRoles));
assertNotNull(o);
assertTrue("Returned object not of type PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails, actual type: " + o.getClass(),
o instanceof PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails);
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails details = (PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails) o;
List<GrantedAuthority> gas = details.getGrantedAuthorities();
assertNotNull("Granted authorities should not be null", gas);
assertEquals(expectedRoles.length, gas.size());
Collection<String> expectedRolesColl = Arrays.asList(expectedRoles);
Collection<String> gasRolesSet = new HashSet<String>();
for (int i = 0; i < gas.size(); i++) {
gasRolesSet.add(gas.get(i).getAuthority());
}
assertTrue("Granted Authorities do not match expected roles", expectedRolesColl.containsAll(gasRolesSet)
&& gasRolesSet.containsAll(expectedRolesColl));
}
private final J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource(
String[] mappedRoles) {
J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource result = new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
result.setMappableRolesRetriever(getMappableRolesRetriever(mappedRoles));
result.setUserRoles2GrantedAuthoritiesMapper(getJ2eeUserRoles2GrantedAuthoritiesMapper());
result.setClazz(PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails.class);
try {
result.afterPropertiesSet();
} catch (Exception expected) {
fail("AfterPropertiesSet throws unexpected exception");
}
return result;
}
private MappableAttributesRetriever getMappableRolesRetriever(String[] mappedRoles) {
SimpleMappableAttributesRetriever result = new SimpleMappableAttributesRetriever();
result.setMappableAttributes(mappedRoles);
return result;
}
private Attributes2GrantedAuthoritiesMapper getJ2eeUserRoles2GrantedAuthoritiesMapper() {
SimpleAttributes2GrantedAuthoritiesMapper result = new SimpleAttributes2GrantedAuthoritiesMapper();
result.setAddPrefixIfAlreadyExisting(false);
result.setConvertAttributeToLowerCase(false);
result.setConvertAttributeToUpperCase(false);
result.setAttributePrefix("");
return result;
}
private final HttpServletRequest getRequest(final String userName,final String[] aRoles)
{
MockHttpServletRequest req = new MockHttpServletRequest() {
private Set<String> roles = new HashSet<String>(Arrays.asList(aRoles));
public boolean isUserInRole(String arg0) {
return roles.contains(arg0);
}
};
req.setRemoteUser(userName);
return req;
}
}

View File

@@ -0,0 +1,49 @@
package org.springframework.security.ui.preauth.j2ee;
import java.security.Principal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
/**
*
* @author TSARDD
* @since 18-okt-2007
*/
public class J2eePreAuthenticatedProcessingFilterTests extends TestCase {
public final void testGetPreAuthenticatedPrincipal() {
String user = "testUser";
assertEquals(user, new J2eePreAuthenticatedProcessingFilter().getPreAuthenticatedPrincipal(
getRequest(user,new String[] {})));
}
public final void testGetPreAuthenticatedCredentials() {
assertEquals("N/A", new J2eePreAuthenticatedProcessingFilter().getPreAuthenticatedCredentials(
getRequest("testUser", new String[] {})));
}
private final HttpServletRequest getRequest(final String aUserName,final String[] aRoles)
{
MockHttpServletRequest req = new MockHttpServletRequest() {
private Set<String> roles = new HashSet<String>(Arrays.asList(aRoles));
public boolean isUserInRole(String arg0) {
return roles.contains(arg0);
}
};
req.setRemoteUser(aUserName);
req.setUserPrincipal(new Principal() {
public String getName() {
return aUserName;
}
});
return req;
}
}

View File

@@ -0,0 +1,34 @@
package org.springframework.security.ui.preauth.j2ee;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
public class WebXmlJ2eeDefinedRolesRetrieverTests extends TestCase {
public final void testRole1To4Roles() throws Exception {
final List<String> ROLE1TO4_EXPECTED_ROLES = Arrays.asList(new String[] { "Role1", "Role2", "Role3", "Role4" });
InputStream role1to4InputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("webxml/Role1-4.web.xml");
WebXmlMappableAttributesRetriever rolesRetriever = new WebXmlMappableAttributesRetriever();
rolesRetriever.setWebXmlInputStream(role1to4InputStream);
rolesRetriever.afterPropertiesSet();
Set<String> j2eeRoles = rolesRetriever.getMappableAttributes();
assertNotNull(j2eeRoles);
assertTrue("J2eeRoles expected size: " + ROLE1TO4_EXPECTED_ROLES.size() + ", actual size: " + j2eeRoles.size(),
j2eeRoles.size() == ROLE1TO4_EXPECTED_ROLES.size());
assertTrue("J2eeRoles expected contents (arbitrary order): " + ROLE1TO4_EXPECTED_ROLES + ", actual content: " + j2eeRoles,
j2eeRoles.containsAll(ROLE1TO4_EXPECTED_ROLES));
}
public final void testGetZeroJ2eeRoles() throws Exception {
InputStream noRolesInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("webxml/NoRoles.web.xml");
WebXmlMappableAttributesRetriever rolesRetriever = new WebXmlMappableAttributesRetriever();
rolesRetriever.setWebXmlInputStream(noRolesInputStream);
rolesRetriever.afterPropertiesSet();
Set<String> j2eeRoles = rolesRetriever.getMappableAttributes();
assertEquals("J2eeRoles expected size: 0, actual size: " + j2eeRoles.size(), 0, j2eeRoles.size());
}
}

View File

@@ -0,0 +1,47 @@
package org.springframework.security.ui.preauth.x509;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.BadCredentialsException;
import org.junit.Test;
import org.junit.Before;
import static junit.framework.Assert.*;
/**
* @author Luke Taylor
* @version $Id$
*/
public class SubjectDnX509PrincipalExtractorTests {
SubjectDnX509PrincipalExtractor extractor;
@Before
public void setUp() {
extractor = new SubjectDnX509PrincipalExtractor();
extractor.setMessageSource(new SpringSecurityMessageSource());
}
@Test(expected = IllegalArgumentException.class)
public void invalidRegexFails() throws Exception {
extractor.setSubjectDnRegex("CN=(.*?,"); // missing closing bracket on group
}
@Test
public void defaultCNPatternReturnsExcpectedPrincipal() throws Exception {
Object principal = extractor.extractPrincipal(X509TestUtils.buildTestCertificate());
assertEquals("Luke Taylor", principal);
}
@Test
public void matchOnEmailReturnsExpectedPrincipal() throws Exception {
extractor.setSubjectDnRegex("emailAddress=(.*?),");
Object principal = extractor.extractPrincipal(X509TestUtils.buildTestCertificate());
assertEquals("luke@monkeymachine", principal);
}
@Test(expected = BadCredentialsException.class)
public void matchOnShoeSizeThrowsBadCredentials() throws Exception {
extractor.setSubjectDnRegex("shoeSize=(.*?),");
extractor.extractPrincipal(X509TestUtils.buildTestCertificate());
}
}

View File

@@ -0,0 +1,102 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.preauth.x509;
import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Certificate creation utility for use in X.509 tests.
*
* @author Luke Taylor
* @version $Id$
*/
public class X509TestUtils {
//~ Methods ========================================================================================================
/**
* Builds an X.509 certificate. In human-readable form it is:
* <pre>
* Certificate:
* Data:
* Version: 3 (0x2)
* Serial Number: 1 (0x1)
* Signature Algorithm: sha1WithRSAEncryption
* Issuer: CN=Monkey Machine CA, C=UK, ST=Scotland, L=Glasgow,
* O=monkeymachine.co.uk/emailAddress=ca@monkeymachine
* Validity
* Not Before: Mar 6 23:28:22 2005 GMT
* Not After : Mar 6 23:28:22 2006 GMT
* Subject: C=UK, ST=Scotland, L=Glasgow, O=Monkey Machine Ltd,
* OU=Open Source Development Lab., CN=Luke Taylor/emailAddress=luke@monkeymachine
* Subject Public Key Info:
* Public Key Algorithm: rsaEncryption
* RSA Public Key: (512 bit)
* [omitted]
* X509v3 extensions:
* X509v3 Basic Constraints:
* CA:FALSE
* Netscape Cert Type:
* SSL Client
* X509v3 Key Usage:
* Digital Signature, Non Repudiation, Key Encipherment
* X509v3 Subject Key Identifier:
* 6E:E6:5B:57:33:CF:0E:2F:15:C2:F4:DF:EC:14:BE:FB:CF:54:56:3C
* X509v3 Authority Key Identifier:
* keyid:AB:78:EC:AF:10:1B:8A:9B:1F:C7:B1:25:8F:16:28:F2:17:9A:AD:36
* DirName:/CN=Monkey Machine CA/C=UK/ST=Scotland/L=Glasgow/O=monkeymachine.co.uk/emailAddress=ca@monkeymachine
* serial:00
* Netscape CA Revocation Url:
* https://monkeymachine.co.uk/ca-crl.pem
* Signature Algorithm: sha1WithRSAEncryption
* [signature omitted]
* </pre>
*/
public static X509Certificate buildTestCertificate() throws Exception {
String cert = "-----BEGIN CERTIFICATE-----\n"
+ "MIIEQTCCAymgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBkzEaMBgGA1UEAxMRTW9u\n"
+ "a2V5IE1hY2hpbmUgQ0ExCzAJBgNVBAYTAlVLMREwDwYDVQQIEwhTY290bGFuZDEQ\n"
+ "MA4GA1UEBxMHR2xhc2dvdzEcMBoGA1UEChMTbW9ua2V5bWFjaGluZS5jby51azEl\n"
+ "MCMGCSqGSIb3DQEJARYWY2FAbW9ua2V5bWFjaGluZS5jby51azAeFw0wNTAzMDYy\n"
+ "MzI4MjJaFw0wNjAzMDYyMzI4MjJaMIGvMQswCQYDVQQGEwJVSzERMA8GA1UECBMI\n"
+ "U2NvdGxhbmQxEDAOBgNVBAcTB0dsYXNnb3cxGzAZBgNVBAoTEk1vbmtleSBNYWNo\n"
+ "aW5lIEx0ZDElMCMGA1UECxMcT3BlbiBTb3VyY2UgRGV2ZWxvcG1lbnQgTGFiLjEU\n"
+ "MBIGA1UEAxMLTHVrZSBUYXlsb3IxITAfBgkqhkiG9w0BCQEWEmx1a2VAbW9ua2V5\n"
+ "bWFjaGluZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDItxZr07mm65ttYH7RMaVo\n"
+ "VeMCq4ptfn+GFFEk4+54OkDuh1CHlk87gEc1jx3ZpQPJRTJx31z3YkiAcP+RDzxr\n"
+ "AgMBAAGjggFIMIIBRDAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIHgDALBgNV\n"
+ "HQ8EBAMCBeAwHQYDVR0OBBYEFG7mW1czzw4vFcL03+wUvvvPVFY8MIHABgNVHSME\n"
+ "gbgwgbWAFKt47K8QG4qbH8exJY8WKPIXmq02oYGZpIGWMIGTMRowGAYDVQQDExFN\n"
+ "b25rZXkgTWFjaGluZSBDQTELMAkGA1UEBhMCVUsxETAPBgNVBAgTCFNjb3RsYW5k\n"
+ "MRAwDgYDVQQHEwdHbGFzZ293MRwwGgYDVQQKExNtb25rZXltYWNoaW5lLmNvLnVr\n"
+ "MSUwIwYJKoZIhvcNAQkBFhZjYUBtb25rZXltYWNoaW5lLmNvLnVrggEAMDUGCWCG\n"
+ "SAGG+EIBBAQoFiZodHRwczovL21vbmtleW1hY2hpbmUuY28udWsvY2EtY3JsLnBl\n"
+ "bTANBgkqhkiG9w0BAQUFAAOCAQEAZ961bEgm2rOq6QajRLeoljwXDnt0S9BGEWL4\n"
+ "PMU2FXDog9aaPwfmZ5fwKaSebwH4HckTp11xwe/D9uBZJQ74Uf80UL9z2eo0GaSR\n"
+ "nRB3QPZfRvop0I4oPvwViKt3puLsi9XSSJ1w9yswnIf89iONT7ZyssPg48Bojo8q\n"
+ "lcKwXuDRBWciODK/xWhvQbaegGJ1BtXcEHtvNjrUJLwSMDSr+U5oUYdMohG0h1iJ\n"
+ "R+JQc49I33o2cTc77wfEWLtVdXAyYY4GSJR6VfgvV40x85ItaNS3HHfT/aXU1x4m\n"
+ "W9YQkWlA6t0blGlC+ghTOY1JbgWnEfXMmVgg9a9cWaYQ+NQwqA==\n" + "-----END CERTIFICATE-----";
ByteArrayInputStream in = new ByteArrayInputStream(cert.getBytes());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(in);
}
}

View File

@@ -0,0 +1,283 @@
package org.springframework.security.ui.rememberme;
import static org.junit.Assert.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.util.StringUtils;
/**
* @author Luke Taylor
* @version $Id$
*/
public class AbstractRememberMeServicesTests {
static User joe = new User("joe", "password", true, true,true,true, AuthorityUtils.createAuthorityList("ROLE_A"));
@Test(expected = InvalidCookieException.class)
public void nonBase64CookieShouldBeDetected() {
new MockRememberMeServices().decodeCookie("nonBase64CookieValue%");
}
@Test
public void cookieShouldBeCorrectlyEncodedAndDecoded() {
String[] cookie = new String[] {"the", "cookie", "tokens", "blah"};
MockRememberMeServices services = new MockRememberMeServices();
String encoded = services.encodeCookie(cookie);
// '=' aren't alowed in version 0 cookies.
assertFalse(encoded.endsWith("="));
String[] decoded = services.decodeCookie(encoded);
assertEquals(4, decoded.length);
assertEquals("the", decoded[0]);
assertEquals("cookie", decoded[1]);
assertEquals("tokens", decoded[2]);
assertEquals("blah", decoded[3]);
}
@Test
public void autoLoginShouldReturnNullIfNoLoginCookieIsPresented() {
MockRememberMeServices services = new MockRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
// shouldn't try to invalidate our cookie
assertNull(response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
// set non-login cookie
request.setCookies(new Cookie[] {new Cookie("mycookie", "cookie")});
assertNull(services.autoLogin(request, response));
assertNull(response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
}
@Test
public void successfulAutoLoginReturnsExpectedAuthentication() {
MockRememberMeServices services = new MockRememberMeServices();
services.setUserDetailsService(new MockUserDetailsService(joe, false));
assertNotNull(services.getUserDetailsService());
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(createLoginCookie("cookie:1:2"));
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNotNull(result);
}
@Test
public void autoLoginShouldFailIfInvalidCookieExceptionIsRaised() {
MockRememberMeServices services = new MockRememberMeServices();
services.setUserDetailsService(new MockUserDetailsService(joe, true));
MockHttpServletRequest request = new MockHttpServletRequest();
// Wrong number of tokes
request.setCookies(createLoginCookie("cookie:1"));
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertCookieCancelled(response);
}
@Test
public void autoLoginShouldFailIfUserNotFound() {
MockRememberMeServices services = new MockRememberMeServices();
services.setUserDetailsService(new MockUserDetailsService(joe, true));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(createLoginCookie("cookie:1:2"));
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertCookieCancelled(response);
}
@Test
public void autoLoginShouldFailIfUserAccountIsLocked() {
MockRememberMeServices services = new MockRememberMeServices();
User joeLocked = new User("joe", "password",false,true,true,true,joe.getAuthorities());
services.setUserDetailsService(new MockUserDetailsService(joeLocked, false));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(createLoginCookie("cookie:1:2"));
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertCookieCancelled(response);
}
@Test
public void loginFailShouldCancelCookie() {
MockRememberMeServices services = new MockRememberMeServices();
services.setUserDetailsService(new MockUserDetailsService(joe, true));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setContextPath("contextpath");
request.setCookies(createLoginCookie("cookie:1:2"));
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginFail(request, response);
assertCookieCancelled(response);
}
@Test(expected = CookieTheftException.class)
public void cookieTheftExceptionShouldBeRethrown() {
MockRememberMeServices services = new MockRememberMeServices() {
protected UserDetails processAutoLoginCookie(String[] cookieTokens, HttpServletRequest request, HttpServletResponse response) {
throw new CookieTheftException("Pretending cookie was stolen");
}
};
services.setUserDetailsService(new MockUserDetailsService(joe, false));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(createLoginCookie("cookie:1:2"));
MockHttpServletResponse response = new MockHttpServletResponse();
services.autoLogin(request, response);
}
@Test
public void loginSuccessCallsOnLoginSuccessCorrectly() {
MockRememberMeServices services = new MockRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication auth = new UsernamePasswordAuthenticationToken("joe","password");
// No parameter set
services = new MockRememberMeServices();
services.loginSuccess(request, response, auth);
assertFalse(services.loginSuccessCalled);
// Parameter set to true
services = new MockRememberMeServices();
request.setParameter(MockRememberMeServices.DEFAULT_PARAMETER, "true");
services.loginSuccess(request, response, auth);
assertTrue(services.loginSuccessCalled);
// Different parameter name, set to true
services = new MockRememberMeServices();
services.setParameter("my_parameter");
request.setParameter("my_parameter", "true");
services.loginSuccess(request, response, auth);
assertTrue(services.loginSuccessCalled);
// Parameter set to false
services = new MockRememberMeServices();
request.setParameter(MockRememberMeServices.DEFAULT_PARAMETER, "false");
services.loginSuccess(request, response, auth);
assertFalse(services.loginSuccessCalled);
// alwaysRemember set to true
services = new MockRememberMeServices();
services.setAlwaysRemember(true);
services.loginSuccess(request, response, auth);
assertTrue(services.loginSuccessCalled);
}
@Test
public void setCookieUsesCorrectNamePathAndValue() {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContextPath("contextpath");
MockRememberMeServices services = new MockRememberMeServices() {
protected String encodeCookie(String[] cookieTokens) {
return cookieTokens[0];
}
};
services.setCookieName("mycookiename");
services.setCookie(new String[] {"mycookie"}, 1000, request, response);
Cookie cookie = response.getCookie("mycookiename");
assertNotNull(cookie);
assertEquals("mycookie", cookie.getValue());
assertEquals("mycookiename", cookie.getName());
assertEquals("contextpath", cookie.getPath());
}
private Cookie[] createLoginCookie(String cookieToken) {
MockRememberMeServices services = new MockRememberMeServices();
Cookie cookie = new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
services.encodeCookie(StringUtils.delimitedListToStringArray(cookieToken, ":")));
return new Cookie[] {cookie};
}
private void assertCookieCancelled(MockHttpServletResponse response) {
Cookie returnedCookie = response.getCookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
//~ Inner Classes ==================================================================================================
private class MockRememberMeServices extends AbstractRememberMeServices {
boolean loginSuccessCalled;
private MockRememberMeServices() {
setKey("key");
}
protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
loginSuccessCalled = true;
}
protected UserDetails processAutoLoginCookie(String[] cookieTokens, HttpServletRequest request, HttpServletResponse response) throws RememberMeAuthenticationException {
if(cookieTokens.length != 3) {
throw new InvalidCookieException("deliberate exception");
}
UserDetails user = getUserDetailsService().loadUserByUsername("joe");
return user;
}
}
public static class MockUserDetailsService implements UserDetailsService {
private UserDetails toReturn;
private boolean throwException;
public MockUserDetailsService(UserDetails toReturn, boolean throwException) {
this.toReturn = toReturn;
this.throwException = throwException;
}
public UserDetails loadUserByUsername(String username) {
if (throwException) {
throw new UsernameNotFoundException("as requested by mock");
}
return toReturn;
}
}
}

View File

@@ -0,0 +1,136 @@
package org.springframework.security.ui.rememberme;
import org.springframework.security.TestDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Luke Taylor
* @version $Id$
*/
@SuppressWarnings("unchecked")
public class JdbcTokenRepositoryImplTests {
private static TestDataSource dataSource;
private JdbcTokenRepositoryImpl repo;
private JdbcTemplate template;
@BeforeClass
public static void createDataSource() {
dataSource = new TestDataSource("tokenrepotest");
}
@AfterClass
public static void clearDataSource() throws Exception {
dataSource.destroy();
dataSource = null;
}
@Before
public void populateDatabase() {
repo = new JdbcTokenRepositoryImpl();
repo.setDataSource(dataSource);
repo.initDao();
template = repo.getJdbcTemplate();
template.execute("create table persistent_logins (username varchar not null, " +
"series varchar not null, token varchar not null, last_used timestamp not null)");
}
@After
public void clearData() {
template.execute("drop table persistent_logins");
}
@Test
public void createNewTokenInsertsCorrectData() {
Date currentDate = new Date();
PersistentRememberMeToken token = new PersistentRememberMeToken("joeuser", "joesseries", "atoken", currentDate);
repo.createNewToken(token);
Map<String,Object> results = template.queryForMap("select * from persistent_logins");
assertEquals(currentDate, results.get("last_used"));
assertEquals("joeuser", results.get("username"));
assertEquals("joesseries", results.get("series"));
assertEquals("atoken", results.get("token"));
}
@Test
public void retrievingTokenReturnsCorrectData() {
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries', 'joeuser', 'atoken', '2007-10-09 18:19:25.000000000')");
PersistentRememberMeToken token = repo.getTokenForSeries("joesseries");
assertEquals("joeuser", token.getUsername());
assertEquals("joesseries", token.getSeries());
assertEquals("atoken", token.getTokenValue());
assertEquals(Timestamp.valueOf("2007-10-09 18:19:25.000000000"), token.getDate());
}
@Test
public void retrievingTokenWithDuplicateSeriesReturnsNull() {
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries', 'joeuser', 'atoken2', '2007-10-19 18:19:25.000000000')");
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries', 'joeuser', 'atoken', '2007-10-09 18:19:25.000000000')");
// List results = template.queryForList("select * from persistent_logins where series = 'joesseries'");
assertNull(repo.getTokenForSeries("joesseries"));
}
@Test
public void removingUserTokensDeletesData() {
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries2', 'joeuser', 'atoken2', '2007-10-19 18:19:25.000000000')");
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries', 'joeuser', 'atoken', '2007-10-09 18:19:25.000000000')");
// List results = template.queryForList("select * from persistent_logins where series = 'joesseries'");
repo.removeUserTokens("joeuser");
List results = template.queryForList("select * from persistent_logins where username = 'joeuser'");
assertEquals(0, results.size());
}
@Test
public void updatingTokenModifiesTokenValueAndLastUsed() {
Timestamp ts = new Timestamp(System.currentTimeMillis() - 1);
template.execute("insert into persistent_logins (series, username, token, last_used) values " +
"('joesseries', 'joeuser', 'atoken', '" + ts.toString() + "')");
repo.updateToken("joesseries", "newtoken", new Date());
Map results = template.queryForMap("select * from persistent_logins where series = 'joesseries'");
assertEquals("joeuser", results.get("username"));
assertEquals("joesseries", results.get("series"));
assertEquals("newtoken", results.get("token"));
Date lastUsed = (Date) results.get("last_used");
assertTrue(lastUsed.getTime() > ts.getTime());
}
@Test
public void createTableOnStartupCreatesCorrectTable() {
template.execute("drop table persistent_logins");
repo = new JdbcTokenRepositoryImpl();
repo.setDataSource(dataSource);
repo.setCreateTableOnStartup(true);
repo.initDao();
template.queryForList("select username,series,token,last_used from persistent_logins");
}
}

View File

@@ -0,0 +1,51 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.rememberme;
import junit.framework.TestCase;
/**
* Tests {@link org.springframework.security.ui.rememberme.NullRememberMeServices}.
*
* @author Ben Alex
* @version $Id$
*/
public class NullRememberMeServicesTests extends TestCase {
//~ Constructors ===================================================================================================
public NullRememberMeServicesTests() {
super();
}
public NullRememberMeServicesTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public static void main(String[] args) {
junit.textui.TestRunner.run(NullRememberMeServicesTests.class);
}
public void testAlwaysReturnsNull() {
NullRememberMeServices services = new NullRememberMeServices();
assertNull(services.autoLogin(null, null));
services.loginFail(null, null);
services.loginSuccess(null, null, null);
assertTrue(true);
}
}

View File

@@ -0,0 +1,145 @@
package org.springframework.security.ui.rememberme;
import static org.junit.Assert.*;
import java.util.Date;
import javax.servlet.http.Cookie;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
/**
* @author Luke Taylor
* @version $Id$
*/
public class PersistentTokenBasedRememberMeServicesTests {
private PersistentTokenBasedRememberMeServices services;
@Before
public void setUpData() throws Exception {
services = new PersistentTokenBasedRememberMeServices();
services.setCookieName("mycookiename");
services.setUserDetailsService(
new AbstractRememberMeServicesTests.MockUserDetailsService(AbstractRememberMeServicesTests.joe, false));
}
@Test(expected = InvalidCookieException.class)
public void loginIsRejectedWithWrongNumberOfCookieTokens() {
services.processAutoLoginCookie(new String[] {"series", "token", "extra"}, new MockHttpServletRequest(),
new MockHttpServletResponse());
}
@Test(expected = RememberMeAuthenticationException.class)
public void loginIsRejectedWhenNoTokenMatchingSeriesIsFound() {
services.setTokenRepository(new MockTokenRepository(null));
services.processAutoLoginCookie(new String[] {"series", "token"}, new MockHttpServletRequest(),
new MockHttpServletResponse());
}
@Test(expected = RememberMeAuthenticationException.class)
public void loginIsRejectedWhenTokenIsExpired() {
MockTokenRepository repo =
new MockTokenRepository(new PersistentRememberMeToken("joe", "series","token", new Date()));
services.setTokenRepository(repo);
services.setTokenValiditySeconds(1);
try {
Thread.sleep(1100);
} catch (InterruptedException e) {
}
services.setTokenRepository(repo);
services.processAutoLoginCookie(new String[] {"series", "token"}, new MockHttpServletRequest(),
new MockHttpServletResponse());
}
@Test(expected = CookieTheftException.class)
public void cookieTheftIsDetectedWhenSeriesAndTokenDontMatch() {
PersistentRememberMeToken token = new PersistentRememberMeToken("joe", "series","wrongtoken", new Date());
services.setTokenRepository(new MockTokenRepository(token));
services.processAutoLoginCookie(new String[] {"series", "token"}, new MockHttpServletRequest(),
new MockHttpServletResponse());
}
@Test
public void successfulAutoLoginCreatesNewTokenAndCookieWithSameSeries() {
MockTokenRepository repo =
new MockTokenRepository(new PersistentRememberMeToken("joe", "series","token", new Date()));
services.setTokenRepository(repo);
// 12 => b64 length will be 16
services.setTokenLength(12);
MockHttpServletResponse response = new MockHttpServletResponse();
services.processAutoLoginCookie(new String[] {"series", "token"}, new MockHttpServletRequest(), response);
assertEquals("series",repo.getStoredToken().getSeries());
assertEquals(16, repo.getStoredToken().getTokenValue().length());
String[] cookie = services.decodeCookie(response.getCookie("mycookiename").getValue());
assertEquals("series", cookie[0]);
assertEquals(repo.getStoredToken().getTokenValue(), cookie[1]);
}
@Test
public void loginSuccessCreatesNewTokenAndCookieWithNewSeries() {
services.setAlwaysRemember(true);
MockTokenRepository repo = new MockTokenRepository(null);
services.setTokenRepository(repo);
services.setTokenLength(12);
services.setSeriesLength(12);
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(new MockHttpServletRequest(),
response, new UsernamePasswordAuthenticationToken("joe","password"));
assertEquals(16, repo.getStoredToken().getSeries().length());
assertEquals(16, repo.getStoredToken().getTokenValue().length());
String[] cookie = services.decodeCookie(response.getCookie("mycookiename").getValue());
assertEquals(repo.getStoredToken().getSeries(), cookie[0]);
assertEquals(repo.getStoredToken().getTokenValue(), cookie[1]);
}
@Test
public void logoutClearsUsersTokenAndCookie() throws Exception {
Cookie cookie = new Cookie("mycookiename", "somevalue");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
MockTokenRepository repo =
new MockTokenRepository(new PersistentRememberMeToken("joe", "series","token", new Date()));
services.setTokenRepository(repo);
services.logout(request, response, new TestingAuthenticationToken("joe","somepass","SOME_AUTH"));
Cookie returnedCookie = response.getCookie("mycookiename");
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
private class MockTokenRepository implements PersistentTokenRepository {
private PersistentRememberMeToken storedToken;
private MockTokenRepository(PersistentRememberMeToken token) {
storedToken = token;
}
public void createNewToken(PersistentRememberMeToken token) {
storedToken = token;
}
public void updateToken(String series, String tokenValue, Date lastUsed) {
storedToken = new PersistentRememberMeToken(storedToken.getUsername(), storedToken.getSeries(),
tokenValue, lastUsed);
}
public PersistentRememberMeToken getTokenForSeries(String seriesId) {
return storedToken;
}
public void removeUserTokens(String username) {
}
PersistentRememberMeToken getStoredToken() {
return storedToken;
}
}
}

View File

@@ -0,0 +1,205 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.rememberme;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.MockApplicationEventPublisher;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.MockFilterConfig;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
/**
* Tests {@link RememberMeProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class RememberMeProcessingFilterTests extends TestCase {
Authentication remembered = new TestingAuthenticationToken("remembered", "password","ROLE_REMEMBERED");
//~ Methods ========================================================================================================
private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request,
ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filter.init(filterConfig);
filter.doFilter(request, response, filterChain);
filter.destroy();
}
protected void setUp() throws Exception {
super.setUp();
SecurityContextHolder.clearContext();
}
protected void tearDown() throws Exception {
super.tearDown();
SecurityContextHolder.clearContext();
}
public void testDetectsAuthenticationManagerProperty() throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setRememberMeServices(new NullRememberMeServices());
filter.afterPropertiesSet();
assertTrue(true);
filter.setAuthenticationManager(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testDetectsRememberMeServicesProperty() throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
// check default is NullRememberMeServices
// assertEquals(NullRememberMeServices.class, filter.getRememberMeServices().getClass());
// check getter/setter
filter.setRememberMeServices(new TokenBasedRememberMeServices());
assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass());
// check detects if made null
filter.setRememberMeServices(null);
try {
filter.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testOperationWhenAuthenticationExistsInContextHolder() throws Exception {
// Put an Authentication object into the SecurityContextHolder
Authentication originalAuth = new TestingAuthenticationToken("user", "password","ROLE_A");
SecurityContextHolder.getContext().setAuthentication(originalAuth);
// Setup our filter correctly
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setRememberMeServices(new MockRememberMeServices(remembered));
filter.afterPropertiesSet();
// Test
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("x");
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
// Ensure filter didn't change our original object
assertEquals(originalAuth, SecurityContextHolder.getContext().getAuthentication());
}
public void testOperationWhenNoAuthenticationInContextHolder() throws Exception {
RememberMeProcessingFilter filter = new RememberMeProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager());
filter.setRememberMeServices(new MockRememberMeServices(remembered));
filter.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("x");
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
// Ensure filter setup with our remembered authentication object
assertEquals(remembered, SecurityContextHolder.getContext().getAuthentication());
}
public void testOnunsuccessfulLoginIsCalledWhenProviderRejectsAuth() throws Exception {
final Authentication failedAuth = new TestingAuthenticationToken("failed", "");
RememberMeProcessingFilter filter = new RememberMeProcessingFilter() {
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
super.onUnsuccessfulAuthentication(request, response, failed);
SecurityContextHolder.getContext().setAuthentication(failedAuth);
}
};
filter.setAuthenticationManager(new MockAuthenticationManager(false));
filter.setRememberMeServices(new MockRememberMeServices(remembered));
filter.setApplicationEventPublisher(new MockApplicationEventPublisher());
filter.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("x");
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, new MockHttpServletResponse(),
new MockFilterChain(true));
assertEquals(failedAuth, SecurityContextHolder.getContext().getAuthentication());
}
//~ Inner Classes ==================================================================================================
private class MockFilterChain implements FilterChain {
private boolean expectToProceed;
public MockFilterChain(boolean expectToProceed) {
this.expectToProceed = expectToProceed;
}
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (expectToProceed) {
assertTrue(true);
} else {
fail("Did not expect filter chain to proceed");
}
}
}
private class MockRememberMeServices implements RememberMeServices {
private Authentication authToReturn;
public MockRememberMeServices(Authentication authToReturn) {
this.authToReturn = authToReturn;
}
public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
return authToReturn;
}
public void loginFail(HttpServletRequest request, HttpServletResponse response) {}
public void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication) {}
}
}

View File

@@ -0,0 +1,333 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.rememberme;
import static org.junit.Assert.*;
import static org.springframework.security.ui.rememberme.TokenBasedRememberMeServices.*;
import java.util.Date;
import javax.servlet.http.Cookie;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.util.StringUtils;
/**
* Tests {@link org.springframework.security.ui.rememberme.TokenBasedRememberMeServices}.
*
* @author Ben Alex
* @version $Id$
*/
public class TokenBasedRememberMeServicesTests {
private Mockery jmock = new JUnit4Mockery();
private UserDetailsService uds;
private UserDetails user = new User("someone", "password", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_ABC"));
private TokenBasedRememberMeServices services;
private Expectations udsWillReturnUser;
private Expectations udsWillThrowNotFound;
//~ Methods ========================================================================================================
@Before
public void createTokenBasedRememberMeServices() {
services = new TokenBasedRememberMeServices();
uds = jmock.mock(UserDetailsService.class);
services.setKey("key");
services.setUserDetailsService(uds);
udsWillReturnUser = new Expectations() {{
oneOf(uds).loadUserByUsername(with(aNonNull(String.class))); will(returnValue(user));
}};
udsWillThrowNotFound = new Expectations() {{
oneOf(uds).loadUserByUsername(with(aNonNull(String.class)));
will(throwException(new UsernameNotFoundException("")));
}};
}
private long determineExpiryTimeFromBased64EncodedToken(String validToken) {
String cookieAsPlainText = new String(Base64.decodeBase64(validToken.getBytes()));
String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":");
if (cookieTokens.length == 3) {
try {
return new Long(cookieTokens[1]).longValue();
} catch (NumberFormatException nfe) {}
}
return -1;
}
private String generateCorrectCookieContentForToken(long expiryTime, String username, String password, String key) {
// format is:
// username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)
String signatureValue = new String(DigestUtils.md5Hex(username + ":" + expiryTime + ":" + password + ":" + key));
String tokenValue = username + ":" + expiryTime + ":" + signatureValue;
String tokenValueBase64 = new String(Base64.encodeBase64(tokenValue.getBytes()));
return tokenValueBase64;
}
@Test
public void autoLoginReturnsNullIfNoCookiePresented() throws Exception {
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(new MockHttpServletRequest(), response);
assertNull(result);
// No cookie set
assertNull(response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
}
@Test
public void autoLoginIgnoresUnrelatedCookie() throws Exception {
Cookie cookie = new Cookie("unrelated_cookie", "foobar");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNull(result);
assertNull(response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY));
}
@Test
public void autoLoginReturnsNullForExpiredCookieAndClearsCookie() throws Exception {
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis() - 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginReturnsNullAndClearsCookieIfMissingThreeTokensInCookieValue() throws Exception {
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
new String(Base64.encodeBase64("x".getBytes())));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginClearsNonBase64EncodedCookie() throws Exception {
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
"NOT_BASE_64_ENCODED");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginClearsCookieIfSignatureBlocksDoesNotMatchExpectedValue() throws Exception {
jmock.checking(udsWillReturnUser);
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password",
"WRONG_KEY"));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginClearsCookieIfTokenDoesNotContainANumberInCookieValue() throws Exception {
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
new String(Base64.encodeBase64("username:NOT_A_NUMBER:signature".getBytes())));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginClearsCookieIfUserNotFound() throws Exception {
jmock.checking(udsWillThrowNotFound);
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
assertNull(services.autoLogin(request, response));
Cookie returnedCookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(returnedCookie);
assertEquals(0, returnedCookie.getMaxAge());
}
@Test
public void autoLoginWithValidTokenAndUserSucceeds() throws Exception {
jmock.checking(udsWillReturnUser);
Cookie cookie = new Cookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY,
generateCorrectCookieContentForToken(System.currentTimeMillis() + 1000000, "someone", "password", "key"));
MockHttpServletRequest request = new MockHttpServletRequest();
request.setCookies(new Cookie[] {cookie});
MockHttpServletResponse response = new MockHttpServletResponse();
Authentication result = services.autoLogin(request, response);
assertNotNull(result);
assertEquals(user, result.getPrincipal());
}
@Test
public void testGettersSetters() {
assertEquals(uds, services.getUserDetailsService());
services.setKey("d");
assertEquals("d", services.getKey());
assertEquals(DEFAULT_PARAMETER, services.getParameter());
services.setParameter("some_param");
assertEquals("some_param", services.getParameter());
services.setTokenValiditySeconds(12);
assertEquals(12, services.getTokenValiditySeconds());
}
@Test
public void loginFailClearsCookie() {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginFail(request, response);
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
assertEquals(0, cookie.getMaxAge());
}
@Test
public void loginSuccessIgnoredIfParameterNotSetOrFalse() {
TokenBasedRememberMeServices services = new TokenBasedRememberMeServices();
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(DEFAULT_PARAMETER, "false");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNull(cookie);
}
@Test
public void loginSuccessNormalWithNonUserDetailsBasedPrincipalSetsExpectedCookie() {
// SEC-822
services.setTokenValiditySeconds(500000000);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, "true");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
String expiryTime = services.decodeCookie(cookie.getValue())[1];
long expectedExpiryTime = 1000L * 500000000;
expectedExpiryTime += System.currentTimeMillis();
assertTrue(Long.parseLong(expiryTime) > expectedExpiryTime - 10000);
assertNotNull(cookie);
assertEquals(services.getTokenValiditySeconds(), cookie.getMaxAge());
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()))));
}
@Test
public void loginSuccessNormalWithUserDetailsBasedPrincipalSetsExpectedCookie() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(TokenBasedRememberMeServices.DEFAULT_PARAMETER, "true");
MockHttpServletResponse response = new MockHttpServletResponse();
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
assertEquals(services.getTokenValiditySeconds(), cookie.getMaxAge());
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
assertTrue(new Date().before(new Date(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()))));
}
// SEC-933
@Test
public void obtainPasswordReturnsNullForTokenWithNullCredentials() throws Exception {
TestingAuthenticationToken token = new TestingAuthenticationToken("username", null);
assertNull(services.retrievePassword(token));
}
// SEC-949
@Test
public void negativeValidityPeriodIsSetOnCookieButExpiryTimeRemainsAtTwoWeeks() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(DEFAULT_PARAMETER, "true");
MockHttpServletResponse response = new MockHttpServletResponse();
services.setTokenValiditySeconds(-1);
services.loginSuccess(request, response, new TestingAuthenticationToken("someone", "password","ROLE_ABC"));
Cookie cookie = response.getCookie(SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY);
assertNotNull(cookie);
// Check the expiry time is within 50ms of two weeks from current time
assertTrue(determineExpiryTimeFromBased64EncodedToken(cookie.getValue()) - System.currentTimeMillis() >
TWO_WEEKS_S - 50);
assertEquals(-1, cookie.getMaxAge());
assertTrue(Base64.isArrayByteBase64(cookie.getValue().getBytes()));
}
}

View File

@@ -0,0 +1,67 @@
package org.springframework.security.ui.savedrequest;
import junit.framework.TestCase;
import javax.servlet.http.Cookie;
import java.io.Serializable;
public class SavedCookieTests extends TestCase {
Cookie cookie;
SavedCookie savedCookie;
protected void setUp() throws Exception {
cookie = new Cookie("name", "value");
cookie.setComment("comment");
cookie.setDomain("domain");
cookie.setMaxAge(100);
cookie.setPath("path");
cookie.setSecure(true);
cookie.setVersion(11);
savedCookie = new SavedCookie(cookie);
}
public void testGetName() throws Exception {
assertEquals(cookie.getName(), savedCookie.getName());
}
public void testGetValue() throws Exception {
assertEquals(cookie.getValue(), savedCookie.getValue());
}
public void testGetComment() throws Exception {
assertEquals(cookie.getComment(), savedCookie.getComment());
}
public void testGetDomain() throws Exception {
assertEquals(cookie.getDomain(), savedCookie.getDomain());
}
public void testGetMaxAge() throws Exception {
assertEquals(cookie.getMaxAge(), savedCookie.getMaxAge());
}
public void testGetPath() throws Exception {
assertEquals(cookie.getPath(), savedCookie.getPath());
}
public void testGetVersion() throws Exception {
assertEquals(cookie.getVersion(), savedCookie.getVersion());
}
public void testGetCookie() throws Exception {
Cookie other = savedCookie.getCookie();
assertEquals(cookie.getComment(), other.getComment());
assertEquals(cookie.getDomain(), other.getDomain());
assertEquals(cookie.getMaxAge(), other.getMaxAge());
assertEquals(cookie.getName(), other.getName());
assertEquals(cookie.getPath(), other.getPath());
assertEquals(cookie.getSecure(), other.getSecure());
assertEquals(cookie.getValue(), other.getValue());
assertEquals(cookie.getVersion(), other.getVersion());
}
public void testSerializable() throws Exception {
assertTrue(savedCookie instanceof Serializable);
}
}

View File

@@ -0,0 +1,22 @@
package org.springframework.security.ui.savedrequest;
import junit.framework.TestCase;
import org.springframework.security.MockPortResolver;
import org.springframework.mock.web.MockHttpServletRequest;
public class SavedRequestTests extends TestCase {
public void testCaseInsensitveHeaders() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("USER-aGenT", "Mozilla");
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
assertEquals("Mozilla", saved.getHeaderValues("user-agent").next());
}
public void testCaseInsensitveParameters() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("ThisIsATest", "Hi mom");
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
assertEquals("Hi mom", saved.getParameterValues("thisisatest")[0]);
}
}

View File

@@ -0,0 +1,72 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.session;
import static org.junit.Assert.*;
import javax.servlet.http.HttpSessionEvent;
import org.junit.Test;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
/**
* The HttpSessionEventPublisher tests
*
* @author Ray Krueger
* @version $Id$
*/
public class HttpSessionEventPublisherTests {
//~ Methods ========================================================================================================
/**
* It's not that complicated so we'll just run it straight through here.
*/
@Test
public void publishedEventIsReceivedbyListener() {
HttpSessionEventPublisher publisher = new HttpSessionEventPublisher();
StaticWebApplicationContext context = new StaticWebApplicationContext();
MockServletContext servletContext = new MockServletContext();
servletContext.setAttribute(StaticWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
context.setServletContext(servletContext);
context.registerSingleton("listener", MockApplicationListener.class, null);
context.refresh();
MockHttpSession session = new MockHttpSession(servletContext);
MockApplicationListener listener = (MockApplicationListener) context.getBean("listener");
HttpSessionEvent event = new HttpSessionEvent(session);
publisher.sessionCreated(event);
assertNotNull(listener.getCreatedEvent());
assertNull(listener.getDestroyedEvent());
assertEquals(session, listener.getCreatedEvent().getSession());
listener.setCreatedEvent(null);
listener.setDestroyedEvent(null);
publisher.sessionDestroyed(event);
assertNotNull(listener.getDestroyedEvent());
assertNull(listener.getCreatedEvent());
assertEquals(session, listener.getDestroyedEvent().getSession());
}
}

View File

@@ -0,0 +1,58 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.session;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
/**
* Listener for tests
*
* @author Ray Krueger
*/
public class MockApplicationListener implements ApplicationListener {
//~ Instance fields ================================================================================================
private HttpSessionCreatedEvent createdEvent;
private HttpSessionDestroyedEvent destroyedEvent;
//~ Methods ========================================================================================================
public HttpSessionCreatedEvent getCreatedEvent() {
return createdEvent;
}
public HttpSessionDestroyedEvent getDestroyedEvent() {
return destroyedEvent;
}
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof HttpSessionCreatedEvent) {
createdEvent = (HttpSessionCreatedEvent) event;
} else if (event instanceof HttpSessionDestroyedEvent) {
destroyedEvent = (HttpSessionDestroyedEvent) event;
}
}
public void setCreatedEvent(HttpSessionCreatedEvent createdEvent) {
this.createdEvent = createdEvent;
}
public void setDestroyedEvent(HttpSessionDestroyedEvent destroyedEvent) {
this.destroyedEvent = destroyedEvent;
}
}

View File

@@ -0,0 +1,406 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.switchuser;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.FilterChain;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.AccountExpiredException;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.CredentialsExpiredException;
import org.springframework.security.DisabledException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.util.FieldUtils;
/**
* Tests {@link org.springframework.security.ui.switchuser.SwitchUserProcessingFilter}.
*
* @author Mark St.Godard
* @author Luke Taylor
* @version $Id$
*/
public class SwitchUserProcessingFilterTests {
private final static List<GrantedAuthority> ROLES_12 = AuthorityUtils.createAuthorityList("ROLE_ONE", "ROLE_TWO");
@Before
public void authenticateCurrentUser() {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50");
SecurityContextHolder.getContext().setAuthentication(auth);
}
@After
public void clearContext() {
SecurityContextHolder.clearContext();
}
private MockHttpServletRequest createMockSwitchRequest() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("http");
request.setServerName("localhost");
request.setRequestURI("/j_spring_security_switch_user");
return request;
}
private Authentication switchToUser(String name) {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, name);
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
return filter.attemptSwitchUser(request);
}
@Test
public void requiresExitUserMatchesCorrectly() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setExitUserUrl("/j_spring_security_my_exit_user");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/j_spring_security_my_exit_user");
assertTrue(filter.requiresExitUser(request));
}
@Test
public void requiresSwitchMatchesCorrectly() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setSwitchUserUrl("/j_spring_security_my_switch_user");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/j_spring_security_my_switch_user");
assertTrue(filter.requiresSwitchUser(request));
}
@Test(expected=UsernameNotFoundException.class)
public void attemptSwitchToUnknownUserFails() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "user-that-doesnt-exist");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.attemptSwitchUser(request);
}
@Test(expected=DisabledException.class)
public void attemptSwitchToUserThatIsDisabledFails() throws Exception {
switchToUser("mcgarrett");
}
@Test(expected=AccountExpiredException.class)
public void attemptSwitchToUserWithAccountExpiredFails() throws Exception {
switchToUser("wofat");
}
@Test(expected=CredentialsExpiredException.class)
public void attemptSwitchToUserWithExpiredCredentialsFails() throws Exception {
switchToUser("steve");
}
@Test(expected=UsernameNotFoundException.class)
public void switchUserWithNullUsernameThrowsException() throws Exception {
switchToUser(null);
}
@Test
public void attemptSwitchUserIsSuccessfulWithValidUser() throws Exception {
assertNotNull(switchToUser("jacklord"));
}
@Test
public void switchToLockedAccountCausesRedirectToSwitchFailureUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/j_spring_security_switch_user");
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "mcgarrett");
MockHttpServletResponse response = new MockHttpServletResponse();
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setTargetUrl("/target");
filter.setUserDetailsService(new MockUserDetailsService());
filter.afterPropertiesSet();
// Check it with no url set (should get a text response)
FilterChain chain = mock(FilterChain.class);
filter.doFilterHttp(request, response, chain);
verify(chain, never()).doFilter(request, response);
assertEquals("Authentication Failed: User is disabled", response.getErrorMessage());
// Now check for the redirect
request.setContextPath("/mywebapp");
request.setRequestURI("/mywebapp/j_spring_security_switch_user");
filter = new SwitchUserProcessingFilter();
filter.setTargetUrl("/target");
filter.setUserDetailsService(new MockUserDetailsService());
filter.setSwitchFailureUrl("/switchfailed");
filter.afterPropertiesSet();
response = new MockHttpServletResponse();
chain = mock(FilterChain.class);
filter.doFilterHttp(request, response, chain);
verify(chain, never()).doFilter(request, response);
assertEquals("/mywebapp/switchfailed", response.getRedirectedUrl());
assertEquals("/switchfailed", FieldUtils.getFieldValue(filter, "switchFailureUrl"));
}
@Test(expected=IllegalArgumentException.class)
public void configMissingUserDetailsServiceFails() throws Exception {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setSwitchUserUrl("/j_spring_security_switch_user");
filter.setExitUserUrl("/j_spring_security_exit_user");
filter.setTargetUrl("/main.jsp");
filter.afterPropertiesSet();
}
@Test(expected=IllegalArgumentException.class)
public void testBadConfigMissingTargetUrl() throws Exception {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.setSwitchUserUrl("/j_spring_security_switch_user");
filter.setExitUserUrl("/j_spring_security_exit_user");
filter.afterPropertiesSet();
}
@Test
public void defaultProcessesFilterUrlMatchesUrlWithPathParameter() {
MockHttpServletRequest request = createMockSwitchRequest();
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setSwitchUserUrl("/j_spring_security_switch_user");
request.setRequestURI("/webapp/j_spring_security_switch_user;jsessionid=8JHDUD723J8");
assertTrue(filter.requiresSwitchUser(request));
}
@Test
public void exitUserJackLordToDanoSucceeds() throws Exception {
// original user
UsernamePasswordAuthenticationToken source = new UsernamePasswordAuthenticationToken("dano", "hawaii50", ROLES_12);
// set current user (Admin)
List<GrantedAuthority> adminAuths = new ArrayList<GrantedAuthority>();
adminAuths.addAll(ROLES_12);
adminAuths.add(new SwitchUserGrantedAuthority("PREVIOUS_ADMINISTRATOR", source));
UsernamePasswordAuthenticationToken admin =
new UsernamePasswordAuthenticationToken("jacklord", "hawaii50", adminAuths);
SecurityContextHolder.getContext().setAuthentication(admin);
MockHttpServletRequest request = createMockSwitchRequest();
request.setRequestURI("/j_spring_security_exit_user");
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.setExitUserUrl("/j_spring_security_exit_user");
filter.setSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/webapp/someOtherUrl"));
// run 'exit'
FilterChain chain = mock(FilterChain.class);
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
verify(chain, never()).doFilter(request, response);
// check current user, should be back to original user (dano)
Authentication targetAuth = SecurityContextHolder.getContext().getAuthentication();
assertNotNull(targetAuth);
assertEquals("dano", targetAuth.getPrincipal());
}
@Test(expected=AuthenticationException.class)
public void exitUserWithNoCurrentUserFails() throws Exception {
// no current user in secure context
SecurityContextHolder.clearContext();
MockHttpServletRequest request = createMockSwitchRequest();
request.setRequestURI("/j_spring_security_exit_user");
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.setExitUserUrl("/j_spring_security_exit_user");
// run 'exit', expect fail due to no current user
FilterChain chain = mock(FilterChain.class);
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
verify(chain, never()).doFilter(request, response);
}
@Test
public void redirectToTargetUrlIsCorrect() throws Exception {
MockHttpServletRequest request = createMockSwitchRequest();
request.setContextPath("/webapp");
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "jacklord");
request.setRequestURI("/webapp/j_spring_security_switch_user");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setSwitchUserUrl("/j_spring_security_switch_user");
filter.setSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/someOtherUrl"));
filter.setUserDetailsService(new MockUserDetailsService());
FilterChain chain = mock(FilterChain.class);
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
verify(chain, never()).doFilter(request, response);
assertEquals("/webapp/someOtherUrl", response.getRedirectedUrl());
}
@Test
public void redirectOmitsContextPathIfUseRelativeContextSet() throws Exception {
// set current user
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = createMockSwitchRequest();
request.setContextPath("/webapp");
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "jacklord");
request.setRequestURI("/webapp/j_spring_security_switch_user");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setSwitchUserUrl("/j_spring_security_switch_user");
SimpleUrlAuthenticationSuccessHandler switchSuccessHandler =
new SimpleUrlAuthenticationSuccessHandler("/someOtherUrl");
switchSuccessHandler.setUseRelativeContext(true);
filter.setSuccessHandler(switchSuccessHandler);
filter.setUserDetailsService(new MockUserDetailsService());
FilterChain chain = mock(FilterChain.class);
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, chain);
verify(chain, never()).doFilter(request, response);
assertEquals("/someOtherUrl", response.getRedirectedUrl());
}
@Test
public void testSwitchRequestFromDanoToJackLord() throws Exception {
// set current user
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50");
SecurityContextHolder.getContext().setAuthentication(auth);
// http request
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/webapp/j_spring_security_switch_user");
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "jacklord");
// http response
MockHttpServletResponse response = new MockHttpServletResponse();
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.setSwitchUserUrl("/j_spring_security_switch_user");
filter.setSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/webapp/someOtherUrl"));
FilterChain chain = mock(FilterChain.class);
// test updates user token and context
filter.doFilter(request, response, chain);
verify(chain, never()).doFilter(request, response);
// check current user
Authentication targetAuth = SecurityContextHolder.getContext().getAuthentication();
assertNotNull(targetAuth);
assertTrue(targetAuth.getPrincipal() instanceof UserDetails);
assertEquals("jacklord", ((User) targetAuth.getPrincipal()).getUsername());
}
@Test
public void modificationOfAuthoritiesWorks() {
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("dano", "hawaii50");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(SwitchUserProcessingFilter.SPRING_SECURITY_SWITCH_USERNAME_KEY, "jacklord");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setUserDetailsService(new MockUserDetailsService());
filter.setSwitchUserAuthorityChanger(new SwitchUserAuthorityChanger() {
public List<GrantedAuthority> modifyGrantedAuthorities(UserDetails targetUser, Authentication currentAuthentication, List<GrantedAuthority> authoritiesToBeGranted) {
List <GrantedAuthority>auths = new ArrayList<GrantedAuthority>();
auths.add(new GrantedAuthorityImpl("ROLE_NEW"));
return auths;
}
});
Authentication result = filter.attemptSwitchUser(request);
assertTrue(result != null);
assertEquals(2, result.getAuthorities().size());
assertEquals("ROLE_NEW", result.getAuthorities().get(0).getAuthority());
}
//~ Inner Classes ==================================================================================================
private class MockUserDetailsService implements UserDetailsService {
private String password = "hawaii50";
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// jacklord, dano (active)
// mcgarrett (disabled)
// wofat (account expired)
// steve (credentials expired)
if ("jacklord".equals(username) || "dano".equals(username)) {
return new User(username, password, true, true, true, true, ROLES_12);
} else if ("mcgarrett".equals(username)) {
return new User(username, password, false, true, true, true, ROLES_12);
} else if ("wofat".equals(username)) {
return new User(username, password, true, false, true, true, ROLES_12);
} else if ("steve".equals(username)) {
return new User(username, password, true, true, false, true, ROLES_12);
} else {
throw new UsernameNotFoundException("Could not find: " + username);
}
}
public void setPassword(String password) {
this.password = password;
}
}
}

View File

@@ -0,0 +1,256 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.webapp;
import junit.framework.TestCase;
import org.springframework.security.MockPortResolver;
import org.springframework.security.web.util.PortMapperImpl;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Tests {@link AuthenticationProcessingFilterEntryPoint}.
*
* @author Ben Alex
* @author colin sampaleanu
* @version $Id$
*/
public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
//~ Methods ========================================================================================================
public void testDetectsMissingLoginFormUrl() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testDetectsMissingPortMapper() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("xxx");
ep.setPortMapper(null);
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testDetectsMissingPortResolver() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("xxx");
ep.setPortResolver(null);
try {
ep.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
}
}
public void testGettersSetters() {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8080, 8443));
assertEquals("/hello", ep.getLoginFormUrl());
assertTrue(ep.getPortMapper() != null);
assertTrue(ep.getPortResolver() != null);
ep.setForceHttps(false);
assertFalse(ep.isForceHttps());
ep.setForceHttps(true);
assertTrue(ep.isForceHttps());
}
public void testHttpsOperationFromOriginalHttpUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
ep.commence(request, response, null);
assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
request.setServerPort(8080);
response = new MockHttpServletResponse();
ep.setPortResolver(new MockPortResolver(8080, 8443));
ep.commence(request, response, null);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
// Now test an unusual custom HTTP:HTTPS is handled properly
request.setServerPort(8888);
response = new MockHttpServletResponse();
ep.commence(request, response, null);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
PortMapperImpl portMapper = new PortMapperImpl();
Map<String,String> map = new HashMap<String,String>();
map.put("8888", "9999");
portMapper.setPortMappings(map);
response = new MockHttpServletResponse();
ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(portMapper);
ep.setPortResolver(new MockPortResolver(8888, 9999));
ep.afterPropertiesSet();
ep.commence(request, response, null);
assertEquals("https://www.example.com:9999/bigWebApp/hello", response.getRedirectedUrl());
}
public void testHttpsOperationFromOriginalHttpsUrl() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setScheme("https");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(443);
MockHttpServletResponse response = new MockHttpServletResponse();
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
ep.commence(request, response, null);
assertEquals("https://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
request.setServerPort(8443);
response = new MockHttpServletResponse();
ep.setPortResolver(new MockPortResolver(8080, 8443));
ep.commence(request, response, null);
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
}
public void testNormalOperation() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setContextPath("/bigWebApp");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
ep.commence(request, response, null);
assertEquals("http://www.example.com/bigWebApp/hello", response.getRedirectedUrl());
}
public void testOperationWhenHttpsRequestsButHttpsPortUnknown() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortResolver(new MockPortResolver(8888, 1234));
ep.setForceHttps(true);
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/some_path");
request.setContextPath("/bigWebApp");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(8888); // NB: Port we can't resolve
MockHttpServletResponse response = new MockHttpServletResponse();
ep.commence(request, response, null);
// Response doesn't switch to HTTPS, as we didn't know HTTP port 8888 to HTTP port mapping
assertEquals("http://www.example.com:8888/bigWebApp/hello", response.getRedirectedUrl());
}
public void testServerSideRedirectWithoutForceHttpsForwardsToLoginPage() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setUseForward(true);
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/bigWebApp/some_path");
request.setServletPath("/some_path");
request.setContextPath("/bigWebApp");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
ep.commence(request, response, null);
assertEquals("/hello", response.getForwardedUrl());
}
public void testServerSideRedirectWithForceHttpsRedirectsCurrentRequest() throws Exception {
AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setUseForward(true);
ep.setForceHttps(true);
ep.afterPropertiesSet();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/bigWebApp/some_path");
request.setServletPath("/some_path");
request.setContextPath("/bigWebApp");
request.setScheme("http");
request.setServerName("www.example.com");
request.setContextPath("/bigWebApp");
request.setServerPort(80);
MockHttpServletResponse response = new MockHttpServletResponse();
ep.commence(request, response, null);
assertEquals("https://www.example.com/bigWebApp/some_path", response.getRedirectedUrl());
}
}

View File

@@ -0,0 +1,144 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.ui.webapp;
import javax.servlet.ServletException;
import junit.framework.TestCase;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.MockAuthenticationManager;
import org.springframework.security.ui.WebAuthenticationDetails;
/**
* Tests {@link AuthenticationProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class AuthenticationProcessingFilterTests extends TestCase {
//~ Methods ========================================================================================================
@Test
public void testNormalOperation() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
assertEquals("/j_spring_security_check", filter.getFilterProcessesUrl());
filter.setAuthenticationManager(new MockAuthenticationManager(true));
filter.init(null);
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
assertEquals("rod", request.getSession().getAttribute(
AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
}
@Test
public void testNullPasswordHandledGracefully() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(true));
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
}
@Test
public void testNullUsernameHandledGracefully() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(true));
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
}
@Test
public void testUsingDifferentParameterNamesWorksAsExpected() throws ServletException {
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(true));
filter.setUsernameParameter("x");
filter.setPasswordParameter("y");
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter("x", "rod");
request.addParameter("y", "koala");
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
}
@Test
public void testSpacesAreTrimmedCorrectlyFromUsername() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, " rod ");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(true));
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertEquals("rod", result.getName());
}
@Test
public void testFailedAuthenticationThrowsException() {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAuthenticationManager(new MockAuthenticationManager(false));
try {
filter.attemptAuthentication(request, new MockHttpServletResponse());
fail("Expected AuthenticationException");
} catch (AuthenticationException e) {
}
// Check username has still been set
assertEquals("rod", request.getSession().getAttribute(
AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
}
/**
* SEC-571
*/
@Test
public void noSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
filter.setAllowSessionCreation(false);
filter.setAuthenticationManager(new MockAuthenticationManager(true));
filter.attemptAuthentication(request, new MockHttpServletResponse());
assertNull(request.getSession(false));
}
}

View File

@@ -0,0 +1,59 @@
package org.springframework.security.ui.webapp;
import static org.mockito.Mockito.mock;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.ui.AbstractProcessingFilter;
import org.springframework.security.ui.FilterChainOrder;
/**
*
* @author Luke Taylor
* @version $Id$
* @since 2.5
*/
public class DefaultLoginPageGeneratingFilterTests {
FilterChain chain = mock(FilterChain.class);
@Test
public void generatingPageWithAuthenticationProcessingFilterOnlyIsSuccessFul() throws Exception {
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new AuthenticationProcessingFilter());
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login"), new MockHttpServletResponse(), chain);
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login;pathparam=unused"), new MockHttpServletResponse(), chain);
}
@Test
public void generatingPageWithOpenIdFilterOnlyIsSuccessFul() throws Exception {
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new MockProcessingFilter());
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login"), new MockHttpServletResponse(), chain);
}
// Fake OpenID filter (since it's not in this module
private static class MockProcessingFilter extends AbstractProcessingFilter {
protected MockProcessingFilter() {
super("/someurl");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
return null;
}
public int getOrder() {
return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
}
public String getClaimedIdentityFieldName() {
return "unused";
}
}
}

View File

@@ -0,0 +1,68 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* A simple filter that the test case can delegate to.
*
* @author Ben Alex
* @version $Id$
*/
public class MockFilter implements Filter {
//~ Instance fields ================================================================================================
private boolean wasDestroyed = false;
private boolean wasDoFiltered = false;
private boolean wasInitialized = false;
//~ Methods ========================================================================================================
public void destroy() {
wasDestroyed = true;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
wasDoFiltered = true;
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
wasInitialized = true;
}
public boolean isWasDestroyed() {
return wasDestroyed;
}
public boolean isWasDoFiltered() {
return wasDoFiltered;
}
public boolean isWasInitialized() {
return wasInitialized;
}
}

View File

@@ -0,0 +1,98 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.util;
import junit.framework.TestCase;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.web.util.PortMapperImpl;
/**
* Tests {@link PortMapperImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class PortMapperImplTests extends TestCase {
//~ Methods ========================================================================================================
public void testDefaultMappingsAreKnown() throws Exception {
PortMapperImpl portMapper = new PortMapperImpl();
assertEquals(new Integer(80), portMapper.lookupHttpPort(new Integer(443)));
assertEquals(new Integer(8080), portMapper.lookupHttpPort(new Integer(8443)));
assertEquals(new Integer(443), portMapper.lookupHttpsPort(new Integer(80)));
assertEquals(new Integer(8443), portMapper.lookupHttpsPort(new Integer(8080)));
}
public void testDetectsEmptyMap() throws Exception {
PortMapperImpl portMapper = new PortMapperImpl();
try {
portMapper.setPortMappings(new HashMap<String,String>());
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testDetectsNullMap() throws Exception {
PortMapperImpl portMapper = new PortMapperImpl();
try {
portMapper.setPortMappings(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGetTranslatedPortMappings() {
PortMapperImpl portMapper = new PortMapperImpl();
assertEquals(2, portMapper.getTranslatedPortMappings().size());
}
public void testRejectsOutOfRangeMappings() {
PortMapperImpl portMapper = new PortMapperImpl();
Map<String, String> map = new HashMap<String, String>();
map.put("79", "80559");
try {
portMapper.setPortMappings(map);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testReturnsNullIfHttpPortCannotBeFound() {
PortMapperImpl portMapper = new PortMapperImpl();
assertTrue(portMapper.lookupHttpPort(new Integer("34343")) == null);
}
public void testSupportsCustomMappings() {
PortMapperImpl portMapper = new PortMapperImpl();
Map<String, String> map = new HashMap<String, String>();
map.put("79", "442");
portMapper.setPortMappings(map);
assertEquals(new Integer(79), portMapper.lookupHttpPort(new Integer(442)));
assertEquals(new Integer(442), portMapper.lookupHttpsPort(new Integer(79)));
}
}

View File

@@ -0,0 +1,92 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.util;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.web.util.PortMapperImpl;
import org.springframework.security.web.util.PortResolverImpl;
/**
* Tests {@link PortResolverImpl}.
*
* @author Ben Alex
* @version $Id$
*/
public class PortResolverImplTests extends TestCase {
//~ Constructors ===================================================================================================
public PortResolverImplTests() {
super();
}
public PortResolverImplTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
public final void setUp() throws Exception {
super.setUp();
}
public void testDetectsBuggyIeHttpRequest() throws Exception {
PortResolverImpl pr = new PortResolverImpl();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServerPort(8443);
request.setScheme("HTtP"); // proves case insensitive handling
assertEquals(8080, pr.getServerPort(request));
}
public void testDetectsBuggyIeHttpsRequest() throws Exception {
PortResolverImpl pr = new PortResolverImpl();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServerPort(8080);
request.setScheme("HTtPs"); // proves case insensitive handling
assertEquals(8443, pr.getServerPort(request));
}
public void testDetectsEmptyPortMapper() throws Exception {
PortResolverImpl pr = new PortResolverImpl();
try {
pr.setPortMapper(null);
fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGettersSetters() throws Exception {
PortResolverImpl pr = new PortResolverImpl();
assertTrue(pr.getPortMapper() != null);
pr.setPortMapper(new PortMapperImpl());
assertTrue(pr.getPortMapper() != null);
}
public void testNormalOperation() throws Exception {
PortResolverImpl pr = new PortResolverImpl();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setScheme("http");
request.setServerPort(1021);
assertEquals(1021, pr.getServerPort(request));
}
}

View File

@@ -0,0 +1,202 @@
package org.springframework.security.wrapper;
import static org.junit.Assert.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import javax.servlet.http.Cookie;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.ui.savedrequest.FastHttpDateFormat;
import org.springframework.security.ui.savedrequest.SavedRequest;
import org.springframework.security.web.util.PortResolverImpl;
public class SavedRequestAwareWrapperTests {
private SavedRequestAwareWrapper createWrapper(MockHttpServletRequest requestToSave, MockHttpServletRequest requestToWrap) {
if (requestToSave != null) {
SavedRequest savedRequest = new SavedRequest(requestToSave, new PortResolverImpl());
requestToWrap.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
}
return new SavedRequestAwareWrapper(requestToWrap, new PortResolverImpl(),"ROLE_");
}
@Test
public void wrappedRequestCookiesAreReturnedIfNoSavedRequestIsSet() throws Exception {
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
wrappedRequest.setCookies(new Cookie[] {new Cookie("cookie", "fromwrapped")});
SavedRequestAwareWrapper wrapper = createWrapper(null, wrappedRequest);
assertEquals(1, wrapper.getCookies().length);
assertEquals("fromwrapped", wrapper.getCookies()[0].getValue());
}
@Test
public void savedRequestCookiesAreReturnedIfSavedRequestIsSet() throws Exception {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.setCookies(new Cookie[] {new Cookie("cookie", "fromsaved")});
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, new MockHttpServletRequest());
assertEquals(1, wrapper.getCookies().length);
assertEquals("fromsaved", wrapper.getCookies()[0].getValue());
}
@Test
@SuppressWarnings("unchecked")
public void savedRequesthHeaderIsReturnedIfSavedRequestIsSet() throws Exception {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.addHeader("header", "savedheader");
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, new MockHttpServletRequest());
assertNull(wrapper.getHeader("nonexistent"));
Enumeration headers = wrapper.getHeaders("nonexistent");
assertFalse(headers.hasMoreElements());
assertEquals("savedheader", wrapper.getHeader("header"));
headers = wrapper.getHeaders("header");
assertTrue(headers.hasMoreElements());
assertEquals("savedheader", headers.nextElement());
assertFalse(headers.hasMoreElements());
assertTrue(wrapper.getHeaderNames().hasMoreElements());
assertEquals("header", wrapper.getHeaderNames().nextElement());
}
@Test
@SuppressWarnings("unchecked")
public void wrappedRequestHeaderIsReturnedIfSavedRequestIsNotSet() throws Exception {
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
wrappedRequest.addHeader("header", "wrappedheader");
SavedRequestAwareWrapper wrapper = createWrapper(null, wrappedRequest);
assertNull(wrapper.getHeader("nonexistent"));
Enumeration headers = wrapper.getHeaders("nonexistent");
assertFalse(headers.hasMoreElements());
assertEquals("wrappedheader", wrapper.getHeader("header"));
headers = wrapper.getHeaders("header");
assertTrue(headers.hasMoreElements());
assertEquals("wrappedheader", headers.nextElement());
assertFalse(headers.hasMoreElements());
assertTrue(wrapper.getHeaderNames().hasMoreElements());
assertEquals("header", wrapper.getHeaderNames().nextElement());
}
@Test
/* SEC-830. Assume we have a request to /someUrl?action=foo (the saved request)
* and then RequestDispatcher.forward() it to /someUrl?action=bar.
* What should action parameter be before and during the forward?
**/
public void wrappedRequestParameterTakesPrecedenceOverSavedRequest() {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.setParameter("action", "foo");
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, wrappedRequest);
assertEquals("foo", wrapper.getParameter("action"));
// The request after forward
wrappedRequest.setParameter("action", "bar");
assertEquals("bar", wrapper.getParameter("action"));
// Both values should be set, but "bar" should be first
assertEquals(2, wrapper.getParameterValues("action").length);
assertEquals("bar", wrapper.getParameterValues("action")[0]);
}
@Test
public void savedRequestDoesntCreateDuplicateParams() {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.setParameter("action", "foo");
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
wrappedRequest.setParameter("action", "foo");
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, wrappedRequest);
assertEquals(1, wrapper.getParameterValues("action").length);
assertEquals(1, wrapper.getParameterMap().size());
assertEquals(1, ((String[])wrapper.getParameterMap().get("action")).length);
}
@Test
public void savedRequestHeadersTakePrecedence() {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.addHeader("Authorization","foo");
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
wrappedRequest.addHeader("Authorization","bar");
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, wrappedRequest);
assertEquals("foo", wrapper.getHeader("Authorization"));
}
@Test
public void getParameterValuesReturnsNullIfParameterIsntSet() {
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
SavedRequestAwareWrapper wrapper = new SavedRequestAwareWrapper(wrappedRequest, new PortResolverImpl(), "ROLE_");
assertNull(wrapper.getParameterValues("action"));
assertNull(wrapper.getParameterMap().get("action"));
}
@Test
public void getParameterValuesReturnsCombinedSavedAndWrappedRequestValues() {
MockHttpServletRequest savedRequest = new MockHttpServletRequest();
savedRequest.setParameter("action", "foo");
MockHttpServletRequest wrappedRequest = new MockHttpServletRequest();
SavedRequestAwareWrapper wrapper = createWrapper(savedRequest, wrappedRequest);
assertArrayEquals(new Object[] {"foo"}, wrapper.getParameterValues("action"));
wrappedRequest.setParameter("action", "bar");
assertArrayEquals(new Object[] {"bar","foo"}, wrapper.getParameterValues("action"));
// Check map is consistent
String[] valuesFromMap = (String[]) wrapper.getParameterMap().get("action");
assertEquals(2, valuesFromMap.length);
assertEquals("bar", valuesFromMap[0]);
}
@Test
public void expecteDateHeaderIsReturnedFromSavedAndWrappedRequests() throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
String nowString = FastHttpDateFormat.getCurrentDate();
Date now = formatter.parse(nowString);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("header", nowString);
SavedRequestAwareWrapper wrapper = createWrapper(request, new MockHttpServletRequest());
assertEquals(now.getTime(), wrapper.getDateHeader("header"));
assertEquals(-1L, wrapper.getDateHeader("nonexistent"));
// Now try with no saved request
request = new MockHttpServletRequest();
request.addHeader("header", now);
wrapper = createWrapper(null, request);
assertEquals(now.getTime(), wrapper.getDateHeader("header"));
}
@Test(expected=IllegalArgumentException.class)
public void invalidDateHeaderIsRejected() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("header", "notadate");
SavedRequestAwareWrapper wrapper = createWrapper(request, new MockHttpServletRequest());
wrapper.getDateHeader("header");
}
@Test
public void correctHttpMethodIsReturned() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/notused");
SavedRequestAwareWrapper wrapper = createWrapper(request, new MockHttpServletRequest("GET", "/notused"));
assertEquals("PUT", wrapper.getMethod());
wrapper = createWrapper(null, request);
assertEquals("PUT", wrapper.getMethod());
}
@Test
public void correctIntHeaderIsReturned() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("header", "999");
request.addHeader("header", "1000");
SavedRequestAwareWrapper wrapper = createWrapper(request, new MockHttpServletRequest());
assertEquals(999, wrapper.getIntHeader("header"));
assertEquals(-1, wrapper.getIntHeader("nonexistent"));
wrapper = createWrapper(null, request);
assertEquals(999, wrapper.getIntHeader("header"));
}
}

View File

@@ -0,0 +1,63 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.wrapper;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletResponse;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.util.PortResolverImpl;
/**
* Tests {@link SecurityContextHolderAwareRequestFilter}.
*
* @author Ben Alex
* @version $Id$
*/
public class SecurityContextHolderAwareRequestFilterTests {
Mockery jmock = new JUnit4Mockery();
//~ Methods ========================================================================================================
@Test
public void expectedRequestWrapperClassIsUsed() throws Exception {
SecurityContextHolderAwareRequestFilter filter = new SecurityContextHolderAwareRequestFilter();
filter.setPortResolver(new PortResolverImpl());
filter.setWrapperClass(SavedRequestAwareWrapper.class);
filter.setRolePrefix("ROLE_");
filter.init(jmock.mock(FilterConfig.class));
final FilterChain filterChain = jmock.mock(FilterChain.class);
jmock.checking(new Expectations() {{
exactly(2).of(filterChain).doFilter(
with(aNonNull(SavedRequestAwareWrapper.class)), with(aNonNull(HttpServletResponse.class)));
}});
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), filterChain);
// Now re-execute the filter, ensuring our replacement wrapper is still used
filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(), filterChain);
filter.destroy();
}
}

View File

@@ -0,0 +1,123 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.wrapper;
import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.userdetails.User;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.web.util.PortResolverImpl;
/**
* Tests {@link SecurityContextHolderAwareRequestWrapper}.
*
* @author Ben Alex
* @version $Id$
*/
public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
//~ Constructors ===================================================================================================
public SecurityContextHolderAwareRequestWrapperTests() {
}
public SecurityContextHolderAwareRequestWrapperTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================
protected void tearDown() throws Exception {
SecurityContextHolder.clearContext();
}
public void testCorrectOperationWithStringBasedPrincipal() throws Exception {
Authentication auth = new TestingAuthenticationToken("rod", "koala","ROLE_FOO");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertEquals("rod", wrapper.getRemoteUser());
assertTrue(wrapper.isUserInRole("ROLE_FOO"));
assertFalse(wrapper.isUserInRole("ROLE_NOT_GRANTED"));
assertEquals(auth, wrapper.getUserPrincipal());
}
public void testUseOfRolePrefixMeansItIsntNeededWhenCallngIsUserInRole() {
Authentication auth = new TestingAuthenticationToken("rod", "koala", "ROLE_FOO");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "ROLE_");
assertTrue(wrapper.isUserInRole("FOO"));
}
public void testCorrectOperationWithUserDetailsBasedPrincipal() throws Exception {
Authentication auth = new TestingAuthenticationToken(new User("rodAsUserDetails", "koala", true, true,
true, true, AuthorityUtils.NO_AUTHORITIES ), "koala", "ROLE_HELLO", "ROLE_FOOBAR");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertEquals("rodAsUserDetails", wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_FOO"));
assertFalse(wrapper.isUserInRole("ROLE_NOT_GRANTED"));
assertTrue(wrapper.isUserInRole("ROLE_FOOBAR"));
assertTrue(wrapper.isUserInRole("ROLE_HELLO"));
assertEquals(auth, wrapper.getUserPrincipal());
}
public void testRoleIsntHeldIfAuthenticationIsNull() throws Exception {
SecurityContextHolder.getContext().setAuthentication(null);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request,new PortResolverImpl(), "");
assertNull(wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_ANY"));
assertNull(wrapper.getUserPrincipal());
}
public void testRolesArentHeldIfAuthenticationPrincipalIsNull() throws Exception {
Authentication auth = new TestingAuthenticationToken(null, "koala","ROLE_HELLO","ROLE_FOOBAR");
SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/");
SecurityContextHolderAwareRequestWrapper wrapper = new SecurityContextHolderAwareRequestWrapper(request, new PortResolverImpl(), "");
assertNull(wrapper.getRemoteUser());
assertFalse(wrapper.isUserInRole("ROLE_HELLO")); // principal is null, so reject
assertFalse(wrapper.isUserInRole("ROLE_FOOBAR")); // principal is null, so reject
assertNull(wrapper.getUserPrincipal());
}
}