SEC-1229: Further doc and mods to namespace config/naming to make it more consistent
This commit is contained in:
+1
-1
@@ -120,7 +120,7 @@ public class FormLoginBeanDefinitionParser {
|
||||
}
|
||||
|
||||
if (sessionStrategy != null) {
|
||||
filterBuilder.addPropertyValue("authenticatedSessionStrategy", sessionStrategy);
|
||||
filterBuilder.addPropertyValue("sessionAuthenticationStrategy", sessionStrategy);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(failureHandlerRef)) {
|
||||
|
||||
+32
-20
@@ -41,7 +41,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
|
||||
import org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.security.web.session.ConcurrentSessionControlAuthenticatedSessionStrategy;
|
||||
import org.springframework.security.web.session.ConcurrentSessionControlStrategy;
|
||||
import org.springframework.security.web.session.DefaultSessionAuthenticationStrategy;
|
||||
import org.springframework.security.web.session.SessionManagementFilter;
|
||||
import org.springframework.security.web.util.AntUrlPathMatcher;
|
||||
@@ -71,7 +71,8 @@ class HttpConfigurationBuilder {
|
||||
private static final String OPT_SESSION_FIXATION_MIGRATE_SESSION = "migrateSession";
|
||||
|
||||
private static final String ATT_INVALID_SESSION_URL = "invalid-session-url";
|
||||
|
||||
private static final String ATT_SESSION_AUTH_STRATEGY_REF = "session-authentication-strategy-ref";
|
||||
private static final String ATT_SESSION_AUTH_ERROR_URL = "session-authentication-error-url";
|
||||
private static final String ATT_SECURITY_CONTEXT_REPOSITORY = "security-context-repository-ref";
|
||||
|
||||
private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting";
|
||||
@@ -197,29 +198,41 @@ class HttpConfigurationBuilder {
|
||||
|
||||
String sessionFixationAttribute = null;
|
||||
String invalidSessionUrl = null;
|
||||
String sessionAuthStratRef = null;
|
||||
String errorUrl = null;
|
||||
|
||||
if (sessionMgmtElt != null) {
|
||||
sessionFixationAttribute = sessionMgmtElt.getAttribute(ATT_SESSION_FIXATION_PROTECTION);
|
||||
invalidSessionUrl = sessionMgmtElt.getAttribute(ATT_INVALID_SESSION_URL);
|
||||
sessionAuthStratRef = sessionMgmtElt.getAttribute(ATT_SESSION_AUTH_STRATEGY_REF);
|
||||
errorUrl = sessionMgmtElt.getAttribute(ATT_SESSION_AUTH_ERROR_URL);
|
||||
sessionCtrlElt = DomUtils.getChildElementByTagName(sessionMgmtElt, Elements.CONCURRENT_SESSIONS);
|
||||
|
||||
if (sessionCtrlElt != null) {
|
||||
if (StringUtils.hasText(sessionAuthStratRef)) {
|
||||
pc.getReaderContext().error(ATT_SESSION_AUTH_STRATEGY_REF + " attribute cannot be used" +
|
||||
" in combination with <" + Elements.CONCURRENT_SESSIONS + ">", pc.extractSource(sessionCtrlElt));
|
||||
}
|
||||
createConcurrencyControlFilterAndSessionRegistry(sessionCtrlElt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(sessionFixationAttribute)) {
|
||||
if (StringUtils.hasText(sessionAuthStratRef)) {
|
||||
pc.getReaderContext().error(ATT_SESSION_FIXATION_PROTECTION + " attribute cannot be used" +
|
||||
" in combination with " + ATT_SESSION_AUTH_STRATEGY_REF, pc.extractSource(sessionCtrlElt));
|
||||
}
|
||||
|
||||
sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;
|
||||
}
|
||||
|
||||
boolean sessionFixationProtectionRequired = !sessionFixationAttribute.equals(OPT_SESSION_FIXATION_NO_PROTECTION);
|
||||
|
||||
BeanDefinitionBuilder sessionStrategy;
|
||||
String concurrencyErrorUrl = null;
|
||||
|
||||
if (sessionCtrlElt != null) {
|
||||
assert sessionRegistryRef != null;
|
||||
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControlAuthenticatedSessionStrategy.class);
|
||||
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControlStrategy.class);
|
||||
sessionStrategy.addConstructorArgValue(sessionRegistryRef);
|
||||
|
||||
String maxSessions = sessionCtrlElt.getAttribute("max-sessions");
|
||||
@@ -232,10 +245,9 @@ class HttpConfigurationBuilder {
|
||||
|
||||
if (StringUtils.hasText(exceptionIfMaximumExceeded)) {
|
||||
sessionStrategy.addPropertyValue("exceptionIfMaximumExceeded", exceptionIfMaximumExceeded);
|
||||
|
||||
concurrencyErrorUrl = sessionCtrlElt.getAttribute("error-url");
|
||||
}
|
||||
} else if (sessionFixationProtectionRequired || StringUtils.hasText(invalidSessionUrl)) {
|
||||
} else if (sessionFixationProtectionRequired || StringUtils.hasText(invalidSessionUrl)
|
||||
|| StringUtils.hasText(sessionAuthStratRef)) {
|
||||
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(DefaultSessionAuthenticationStrategy.class);
|
||||
} else {
|
||||
sfpf = null;
|
||||
@@ -244,28 +256,31 @@ class HttpConfigurationBuilder {
|
||||
|
||||
BeanDefinitionBuilder sessionMgmtFilter = BeanDefinitionBuilder.rootBeanDefinition(SessionManagementFilter.class);
|
||||
RootBeanDefinition failureHandler = new RootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
|
||||
if (StringUtils.hasText(concurrencyErrorUrl)) {
|
||||
failureHandler.getPropertyValues().addPropertyValue("defaultFailureUrl", concurrencyErrorUrl);
|
||||
if (StringUtils.hasText(errorUrl)) {
|
||||
failureHandler.getPropertyValues().addPropertyValue("defaultFailureUrl", errorUrl);
|
||||
}
|
||||
sessionMgmtFilter.addPropertyValue("authenticationFailureHandler", failureHandler);
|
||||
sessionMgmtFilter.addConstructorArgValue(contextRepoRef);
|
||||
BeanDefinition strategyBean = sessionStrategy.getBeanDefinition();
|
||||
|
||||
String sessionStrategyId = pc.getReaderContext().registerWithGeneratedName(strategyBean);
|
||||
pc.registerBeanComponent(new BeanComponentDefinition(strategyBean, sessionStrategyId));
|
||||
sessionMgmtFilter.addPropertyReference("authenticatedSessionStrategy", sessionStrategyId);
|
||||
if (sessionFixationProtectionRequired) {
|
||||
if (!StringUtils.hasText(sessionAuthStratRef)) {
|
||||
BeanDefinition strategyBean = sessionStrategy.getBeanDefinition();
|
||||
|
||||
sessionStrategy.addPropertyValue("migrateSessionAttributes",
|
||||
Boolean.valueOf(sessionFixationAttribute.equals(OPT_SESSION_FIXATION_MIGRATE_SESSION)));
|
||||
if (sessionFixationProtectionRequired) {
|
||||
sessionStrategy.addPropertyValue("migrateSessionAttributes",
|
||||
Boolean.valueOf(sessionFixationAttribute.equals(OPT_SESSION_FIXATION_MIGRATE_SESSION)));
|
||||
}
|
||||
sessionAuthStratRef = pc.getReaderContext().registerWithGeneratedName(strategyBean);
|
||||
pc.registerBeanComponent(new BeanComponentDefinition(strategyBean, sessionAuthStratRef));
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(invalidSessionUrl)) {
|
||||
sessionMgmtFilter.addPropertyValue("invalidSessionUrl", invalidSessionUrl);
|
||||
}
|
||||
|
||||
sessionMgmtFilter.addPropertyReference("sessionAuthenticationStrategy", sessionAuthStratRef);
|
||||
|
||||
sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition();
|
||||
sessionStrategyRef = new RuntimeBeanReference(sessionStrategyId);
|
||||
sessionStrategyRef = new RuntimeBeanReference(sessionAuthStratRef);
|
||||
}
|
||||
|
||||
private void createConcurrencyControlFilterAndSessionRegistry(Element element) {
|
||||
@@ -399,9 +414,6 @@ class HttpConfigurationBuilder {
|
||||
return channelRequestMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void createFilterSecurityInterceptor(BeanReference authManager) {
|
||||
BeanDefinitionBuilder fidsBuilder;
|
||||
|
||||
|
||||
+7
-4
@@ -425,6 +425,12 @@ session-management.attlist &=
|
||||
session-management.attlist &=
|
||||
## The URL to which a user will be redirected if they submit an invalid session indentifier. Typically used to detect session timeouts.
|
||||
attribute invalid-session-url {xsd:token}?
|
||||
session-management.attlist &=
|
||||
## Allows injection of the SessionAuthenticationStrategy instance used by the SessionManagementFilter
|
||||
attribute session-authentication-strategy-ref {xsd:token}?
|
||||
session-management.attlist &=
|
||||
## Defines the URL of the error page which should be shown when the SessionAuthenticationStrategy raises an exception. If not set, an unauthorized (402) error code will be returned to the client. Note that this attribute doesn't apply if the error occurs during a form-based login, where the URL for authentication failure will take precedence.
|
||||
attribute session-authentication-error-url {xsd:token}?
|
||||
|
||||
|
||||
concurrency-control =
|
||||
@@ -438,11 +444,8 @@ concurrency-control.attlist &=
|
||||
## The URL a user will be redirected to if they attempt to use a session which has been "expired" because they have logged in again.
|
||||
attribute expired-url {xsd:token}?
|
||||
concurrency-control.attlist &=
|
||||
## Specifies that an unauthorized error should be reported when a user attempts to login when they already have the maximum configured sessions open. The default behaviour is to expire the original session.
|
||||
## Specifies that an unauthorized error should be reported when a user attempts to login when they already have the maximum configured sessions open. The default behaviour is to expire the original session. If the session-authentication-error-url attribute is set on the session-management URL, the user will be redirected to this URL.
|
||||
attribute error-if-maximum-exceeded {boolean}?
|
||||
concurrency-control.attlist &=
|
||||
## Defines the URL of the error page which should be shown when the maximum is exceeded and error-if-maximum-exceeded is 'true'. If not set, an unauthorized (402) error code will be returned to the client. Note that this attribute doesn't apply if the error occurs during a form-based login, where the URL for authentication failure will take precedence.
|
||||
attribute error-url {xsd:token}?
|
||||
concurrency-control.attlist &=
|
||||
## Allows you to define an alias for the SessionRegistry bean in order to access it in your own configuration.
|
||||
attribute session-registry-alias {xsd:token}?
|
||||
|
||||
+11
-6
@@ -953,6 +953,16 @@
|
||||
<xs:documentation>The URL to which a user will be redirected if they submit an invalid session indentifier. Typically used to detect session timeouts.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="session-authentication-strategy-ref" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Allows injection of the SessionAuthenticationStrategy instance used by the SessionManagementFilter</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="session-authentication-error-url" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Defines the URL of the error page which should be shown when the SessionAuthenticationStrategy raises an exception. If not set, an unauthorized (402) error code will be returned to the client. Note that this attribute doesn't apply if the error occurs during a form-based login, where the URL for authentication failure will take precedence. </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:attributeGroup>
|
||||
|
||||
<xs:attributeGroup name="concurrency-control.attlist">
|
||||
@@ -968,12 +978,7 @@
|
||||
</xs:attribute>
|
||||
<xs:attribute name="error-if-maximum-exceeded" type="security:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Specifies that an unauthorized error should be reported when a user attempts to login when they already have the maximum configured sessions open. The default behaviour is to expire the original session.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="error-url" type="xs:token">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Defines the URL of the error page which should be shown when the maximum is exceeded and error-if-maximum-exceeded is 'true'. If not set, an unauthorized (402) error code will be returned to the client. </xs:documentation>
|
||||
<xs:documentation>Specifies that an unauthorized error should be reported when a user attempts to login when they already have the maximum configured sessions open. The default behaviour is to expire the original session. If the session-authentication-error-url attribute is set on the session-management URL, the user will be redirected to this URL.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="session-registry-alias" type="xs:token">
|
||||
|
||||
+6
-6
@@ -706,22 +706,22 @@ public class HttpSecurityBeanDefinitionParserTests {
|
||||
public void concurrentSessionMaxSessionsIsCorrectlyConfigured() throws Exception {
|
||||
setContext(
|
||||
"<http auto-config='true'>" +
|
||||
" <session-management>" +
|
||||
" <concurrency-control max-sessions='2' error-if-maximum-exceeded='true' error-url='/max-exceeded' />" +
|
||||
" <session-management session-authentication-error-url='/max-exceeded'>" +
|
||||
" <concurrency-control max-sessions='2' error-if-maximum-exceeded='true' />" +
|
||||
" </session-management>" +
|
||||
"</http>" + AUTH_PROVIDER_XML);
|
||||
SessionManagementFilter seshStrategy = (SessionManagementFilter) getFilter(SessionManagementFilter.class);
|
||||
SessionManagementFilter seshFilter = (SessionManagementFilter) getFilter(SessionManagementFilter.class);
|
||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("bob", "pass");
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
// Register 2 sessions and then check a third
|
||||
// req.setSession(new MockHttpSession());
|
||||
// auth.setDetails(new WebAuthenticationDetails(req));
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
assertNull(response.getRedirectedUrl());
|
||||
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
assertNull(response.getRedirectedUrl());
|
||||
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
|
||||
assertEquals("/max-exceeded", response.getRedirectedUrl());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user