1
0
mirror of synced 2026-08-05 01:36:56 +00:00

SEC-1229: Redesign Concurrent Session Control implementation. Renamed session strategy interface and introduced SessionAuthenticationException for rejection of session/Authentication combination.

This commit is contained in:
Luke Taylor
2009-08-31 22:48:49 +00:00
parent 0d7b990e0a
commit dbcb13ad14
12 changed files with 66 additions and 84 deletions
@@ -33,7 +33,6 @@ import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AnonymousAuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.RememberMeAuthenticationProvider;
import org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.Elements;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
@@ -64,7 +63,7 @@ import org.springframework.security.web.context.SecurityContextPersistenceFilter
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
import org.springframework.security.web.session.ConcurrentSessionControlAuthenticatedSessionStrategy;
import org.springframework.security.web.session.DefaultAuthenticatedSessionStrategy;
import org.springframework.security.web.session.DefaultSessionAuthenticationStrategy;
import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.RegexUrlPathMatcher;
@@ -130,8 +129,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting";
private static final String ATT_SESSION_CONTROLLER_REF = "session-controller-ref";
static final String OPEN_ID_AUTHENTICATION_PROCESSING_FILTER_CLASS = "org.springframework.security.openid.OpenIDAuthenticationProcessingFilter";
static final String OPEN_ID_AUTHENTICATION_PROVIDER_CLASS = "org.springframework.security.openid.OpenIDAuthenticationProvider";
static final String OPEN_ID_CONSUMER_CLASS = "org.springframework.security.openid.OpenID4JavaConsumer";
@@ -726,45 +723,6 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
return sessionControlFilter;
}
private BeanReference createConcurrentSessionController(Element elt, BeanDefinition filter, BeanReference sessionRegistry, ParserContext pc) {
Element sessionCtrlElement = DomUtils.getChildElementByTagName(elt, Elements.CONCURRENT_SESSIONS);
// Check for a custom controller
// String sessionControllerRef = sessionCtrlElement.getAttribute(ATT_SESSION_CONTROLLER_REF);
//
// if (StringUtils.hasText(sessionControllerRef)) {
// if (!StringUtils.hasText(sessionCtrlElement.getAttribute(ConcurrentSessionsBeanDefinitionParser.ATT_SESSION_REGISTRY_REF))) {
// pc.getReaderContext().error("Use of " + ATT_SESSION_CONTROLLER_REF + " requires that " +
// ConcurrentSessionsBeanDefinitionParser.ATT_SESSION_REGISTRY_REF + " is also set.",
// pc.extractSource(sessionCtrlElement));
// }
// return new RuntimeBeanReference(sessionControllerRef);
// }
BeanDefinitionBuilder controllerBuilder = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControllerImpl.class);
controllerBuilder.getRawBeanDefinition().setSource(filter.getSource());
controllerBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
controllerBuilder.addPropertyValue("sessionRegistry", sessionRegistry);
String maxSessions = sessionCtrlElement.getAttribute("max-sessions");
if (StringUtils.hasText(maxSessions)) {
controllerBuilder.addPropertyValue("maximumSessions", maxSessions);
}
String exceptionIfMaximumExceeded = sessionCtrlElement.getAttribute("exception-if-maximum-exceeded");
if (StringUtils.hasText(exceptionIfMaximumExceeded)) {
controllerBuilder.addPropertyValue("exceptionIfMaximumExceeded", exceptionIfMaximumExceeded);
}
BeanDefinition controller = controllerBuilder.getBeanDefinition();
String id = pc.getReaderContext().registerWithGeneratedName(controller);
pc.registerComponent(new BeanComponentDefinition(controller, id));
return new RuntimeBeanReference(id);
}
private BeanReference createRequestCache(Element element, ParserContext pc, boolean allowSessionCreation,
String portMapperName) {
BeanDefinitionBuilder requestCache = BeanDefinitionBuilder.rootBeanDefinition(HttpSessionRequestCache.class);
@@ -948,7 +906,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
sessionStrategy.addPropertyValue("exceptionIfMaximumExceeded", exceptionIfMaximumExceeded);
}
} else if (sessionFixationProtectionRequired || StringUtils.hasText(invalidSessionUrl)) {
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(DefaultAuthenticatedSessionStrategy.class);
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(DefaultSessionAuthenticationStrategy.class);
} else {
return null;
}
@@ -71,7 +71,7 @@ import org.springframework.security.web.authentication.www.BasicProcessingFilter
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
import org.springframework.security.web.session.AuthenticatedSessionStrategy;
import org.springframework.security.web.session.SessionAuthenticationStrategy;
import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.wrapper.SecurityContextHolderAwareRequestFilter;
import org.springframework.util.ReflectionUtils;
@@ -115,7 +115,7 @@ public class HttpSecurityBeanDefinitionParserTests {
checkAutoConfigFilters(filterList);
assertEquals(true, FieldUtils.getFieldValue(appContext.getBean("_filterChainProxy"), "stripQueryStringFromUrls"));
assertEquals(true, FieldUtils.getFieldValue(appContext.getBean(BeanIds.FILTER_CHAIN_PROXY), "stripQueryStringFromUrls"));
assertEquals(true, FieldUtils.getFieldValue(filterList.get(AUTO_CONFIG_FILTERS-1), "securityMetadataSource.stripQueryStringFromUrls"));
}
@@ -138,8 +138,8 @@ public class HttpSecurityBeanDefinitionParserTests {
assertTrue(filters.next() instanceof RequestCacheAwareFilter);
assertTrue(filters.next() instanceof SecurityContextHolderAwareRequestFilter);
assertTrue(filters.next() instanceof AnonymousProcessingFilter);
assertTrue(filters.next() instanceof ExceptionTranslationFilter);
assertTrue(filters.next() instanceof SessionManagementFilter);
assertTrue(filters.next() instanceof ExceptionTranslationFilter);
Object fsiObj = filters.next();
assertTrue(fsiObj instanceof FilterSecurityInterceptor);
FilterSecurityInterceptor fsi = (FilterSecurityInterceptor) fsiObj;
@@ -363,7 +363,7 @@ public class HttpSecurityBeanDefinitionParserTests {
setContext("<http access-denied-page='/access-denied'><http-basic /></http>" + AUTH_PROVIDER_XML);
List<Filter> filters = getFilters("/someurl");
ExceptionTranslationFilter etf = (ExceptionTranslationFilter) filters.get(filters.size() - 3);
ExceptionTranslationFilter etf = (ExceptionTranslationFilter) filters.get(filters.size() - 2);
assertEquals("/access-denied", FieldUtils.getFieldValue(etf, "accessDeniedHandler.errorPage"));
}
@@ -755,7 +755,7 @@ public class HttpSecurityBeanDefinitionParserTests {
"<http auto-config='true'>" +
" <concurrent-session-control max-sessions='2' exception-if-maximum-exceeded='true' />" +
"</http>" + AUTH_PROVIDER_XML);
AuthenticatedSessionStrategy seshStrategy = (AuthenticatedSessionStrategy) FieldUtils.getFieldValue(
SessionAuthenticationStrategy seshStrategy = (SessionAuthenticationStrategy) FieldUtils.getFieldValue(
getFilter(SessionManagementFilter.class), "sessionStrategy");
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("bob", "pass");
// Register 2 sessions and then check a third
@@ -782,7 +782,7 @@ public class HttpSecurityBeanDefinitionParserTests {
"<http auto-config='true' entry-point-ref='entryPoint'/>" +
"<b:bean id='entryPoint' class='" + MockEntryPoint.class.getName() + "'>" +
"</b:bean>" + AUTH_PROVIDER_XML);
ExceptionTranslationFilter etf = (ExceptionTranslationFilter) getFilters("/someurl").get(AUTO_CONFIG_FILTERS-3);
ExceptionTranslationFilter etf = (ExceptionTranslationFilter) getFilters("/someurl").get(AUTO_CONFIG_FILTERS-2);
assertTrue("ExceptionTranslationFilter should be configured with custom entry point",
etf.getAuthenticationEntryPoint() instanceof MockEntryPoint);
}
@@ -810,8 +810,7 @@ public class HttpSecurityBeanDefinitionParserTests {
setContext(
"<http auto-config='true' session-fixation-protection='none'/>" + AUTH_PROVIDER_XML);
List<Filter> filters = getFilters("/someurl");
assertTrue(filters.get(8) instanceof ExceptionTranslationFilter);
assertFalse(filters.get(9) instanceof SessionManagementFilter);
assertFalse(filters.get(8) instanceof SessionManagementFilter);
}
@Test
@@ -820,7 +819,7 @@ public class HttpSecurityBeanDefinitionParserTests {
"<http auto-config='true' session-fixation-protection='none'" +
" invalid-session-url='/timeoutUrl' />" + AUTH_PROVIDER_XML);
List<Filter> filters = getFilters("/someurl");
Object filter = filters.get(9);
Object filter = filters.get(8);
assertTrue(filter instanceof SessionManagementFilter);
assertEquals("/timeoutUrl", FieldUtils.getProtectedFieldValue("invalidSessionUrl", filter));
}