SEC-1229: Further doc and mods to namespace config/naming to make it more consistent

This commit is contained in:
Luke Taylor 2009-10-03 16:08:51 +00:00
parent dd3b9553a0
commit 2b89ebdfbb
13 changed files with 276 additions and 181 deletions

View File

@ -120,7 +120,7 @@ public class FormLoginBeanDefinitionParser {
} }
if (sessionStrategy != null) { if (sessionStrategy != null) {
filterBuilder.addPropertyValue("authenticatedSessionStrategy", sessionStrategy); filterBuilder.addPropertyValue("sessionAuthenticationStrategy", sessionStrategy);
} }
if (StringUtils.hasText(failureHandlerRef)) { if (StringUtils.hasText(failureHandlerRef)) {

View File

@ -41,7 +41,7 @@ import org.springframework.security.web.authentication.SimpleUrlAuthenticationFa
import org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter; import org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextPersistenceFilter; 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.DefaultSessionAuthenticationStrategy;
import org.springframework.security.web.session.SessionManagementFilter; import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.util.AntUrlPathMatcher; 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 OPT_SESSION_FIXATION_MIGRATE_SESSION = "migrateSession";
private static final String ATT_INVALID_SESSION_URL = "invalid-session-url"; 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_SECURITY_CONTEXT_REPOSITORY = "security-context-repository-ref";
private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting"; private static final String ATT_DISABLE_URL_REWRITING = "disable-url-rewriting";
@ -197,29 +198,41 @@ class HttpConfigurationBuilder {
String sessionFixationAttribute = null; String sessionFixationAttribute = null;
String invalidSessionUrl = null; String invalidSessionUrl = null;
String sessionAuthStratRef = null;
String errorUrl = null;
if (sessionMgmtElt != null) { if (sessionMgmtElt != null) {
sessionFixationAttribute = sessionMgmtElt.getAttribute(ATT_SESSION_FIXATION_PROTECTION); sessionFixationAttribute = sessionMgmtElt.getAttribute(ATT_SESSION_FIXATION_PROTECTION);
invalidSessionUrl = sessionMgmtElt.getAttribute(ATT_INVALID_SESSION_URL); 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); sessionCtrlElt = DomUtils.getChildElementByTagName(sessionMgmtElt, Elements.CONCURRENT_SESSIONS);
if (sessionCtrlElt != null) { 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); createConcurrencyControlFilterAndSessionRegistry(sessionCtrlElt);
} }
} }
if (!StringUtils.hasText(sessionFixationAttribute)) { 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; sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;
} }
boolean sessionFixationProtectionRequired = !sessionFixationAttribute.equals(OPT_SESSION_FIXATION_NO_PROTECTION); boolean sessionFixationProtectionRequired = !sessionFixationAttribute.equals(OPT_SESSION_FIXATION_NO_PROTECTION);
BeanDefinitionBuilder sessionStrategy; BeanDefinitionBuilder sessionStrategy;
String concurrencyErrorUrl = null;
if (sessionCtrlElt != null) { if (sessionCtrlElt != null) {
assert sessionRegistryRef != null; assert sessionRegistryRef != null;
sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControlAuthenticatedSessionStrategy.class); sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(ConcurrentSessionControlStrategy.class);
sessionStrategy.addConstructorArgValue(sessionRegistryRef); sessionStrategy.addConstructorArgValue(sessionRegistryRef);
String maxSessions = sessionCtrlElt.getAttribute("max-sessions"); String maxSessions = sessionCtrlElt.getAttribute("max-sessions");
@ -232,10 +245,9 @@ class HttpConfigurationBuilder {
if (StringUtils.hasText(exceptionIfMaximumExceeded)) { if (StringUtils.hasText(exceptionIfMaximumExceeded)) {
sessionStrategy.addPropertyValue("exceptionIfMaximumExceeded", 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); sessionStrategy = BeanDefinitionBuilder.rootBeanDefinition(DefaultSessionAuthenticationStrategy.class);
} else { } else {
sfpf = null; sfpf = null;
@ -244,28 +256,31 @@ class HttpConfigurationBuilder {
BeanDefinitionBuilder sessionMgmtFilter = BeanDefinitionBuilder.rootBeanDefinition(SessionManagementFilter.class); BeanDefinitionBuilder sessionMgmtFilter = BeanDefinitionBuilder.rootBeanDefinition(SessionManagementFilter.class);
RootBeanDefinition failureHandler = new RootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class); RootBeanDefinition failureHandler = new RootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
if (StringUtils.hasText(concurrencyErrorUrl)) { if (StringUtils.hasText(errorUrl)) {
failureHandler.getPropertyValues().addPropertyValue("defaultFailureUrl", concurrencyErrorUrl); failureHandler.getPropertyValues().addPropertyValue("defaultFailureUrl", errorUrl);
} }
sessionMgmtFilter.addPropertyValue("authenticationFailureHandler", failureHandler); sessionMgmtFilter.addPropertyValue("authenticationFailureHandler", failureHandler);
sessionMgmtFilter.addConstructorArgValue(contextRepoRef); sessionMgmtFilter.addConstructorArgValue(contextRepoRef);
BeanDefinition strategyBean = sessionStrategy.getBeanDefinition();
String sessionStrategyId = pc.getReaderContext().registerWithGeneratedName(strategyBean); if (!StringUtils.hasText(sessionAuthStratRef)) {
pc.registerBeanComponent(new BeanComponentDefinition(strategyBean, sessionStrategyId)); BeanDefinition strategyBean = sessionStrategy.getBeanDefinition();
sessionMgmtFilter.addPropertyReference("authenticatedSessionStrategy", sessionStrategyId);
if (sessionFixationProtectionRequired) {
sessionStrategy.addPropertyValue("migrateSessionAttributes", if (sessionFixationProtectionRequired) {
Boolean.valueOf(sessionFixationAttribute.equals(OPT_SESSION_FIXATION_MIGRATE_SESSION))); 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)) { if (StringUtils.hasText(invalidSessionUrl)) {
sessionMgmtFilter.addPropertyValue("invalidSessionUrl", invalidSessionUrl); sessionMgmtFilter.addPropertyValue("invalidSessionUrl", invalidSessionUrl);
} }
sessionMgmtFilter.addPropertyReference("sessionAuthenticationStrategy", sessionAuthStratRef);
sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition(); sfpf = (RootBeanDefinition) sessionMgmtFilter.getBeanDefinition();
sessionStrategyRef = new RuntimeBeanReference(sessionStrategyId); sessionStrategyRef = new RuntimeBeanReference(sessionAuthStratRef);
} }
private void createConcurrencyControlFilterAndSessionRegistry(Element element) { private void createConcurrencyControlFilterAndSessionRegistry(Element element) {
@ -399,9 +414,6 @@ class HttpConfigurationBuilder {
return channelRequestMap; return channelRequestMap;
} }
void createFilterSecurityInterceptor(BeanReference authManager) { void createFilterSecurityInterceptor(BeanReference authManager) {
BeanDefinitionBuilder fidsBuilder; BeanDefinitionBuilder fidsBuilder;

View File

@ -425,6 +425,12 @@ session-management.attlist &=
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. ## 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}? 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 = 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. ## 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}? attribute expired-url {xsd:token}?
concurrency-control.attlist &= 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}? 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 &= concurrency-control.attlist &=
## Allows you to define an alias for the SessionRegistry bean in order to access it in your own configuration. ## 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}? attribute session-registry-alias {xsd:token}?

View File

@ -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: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:annotation>
</xs:attribute> </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>
<xs:attributeGroup name="concurrency-control.attlist"> <xs:attributeGroup name="concurrency-control.attlist">
@ -968,12 +978,7 @@
</xs:attribute> </xs:attribute>
<xs:attribute name="error-if-maximum-exceeded" type="security:boolean"> <xs:attribute name="error-if-maximum-exceeded" type="security:boolean">
<xs:annotation> <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: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="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:annotation> </xs:annotation>
</xs:attribute> </xs:attribute>
<xs:attribute name="session-registry-alias" type="xs:token"> <xs:attribute name="session-registry-alias" type="xs:token">

View File

@ -706,22 +706,22 @@ public class HttpSecurityBeanDefinitionParserTests {
public void concurrentSessionMaxSessionsIsCorrectlyConfigured() throws Exception { public void concurrentSessionMaxSessionsIsCorrectlyConfigured() throws Exception {
setContext( setContext(
"<http auto-config='true'>" + "<http auto-config='true'>" +
" <session-management>" + " <session-management session-authentication-error-url='/max-exceeded'>" +
" <concurrency-control max-sessions='2' error-if-maximum-exceeded='true' error-url='/max-exceeded' />" + " <concurrency-control max-sessions='2' error-if-maximum-exceeded='true' />" +
" </session-management>" + " </session-management>" +
"</http>" + AUTH_PROVIDER_XML); "</http>" + AUTH_PROVIDER_XML);
SessionManagementFilter seshStrategy = (SessionManagementFilter) getFilter(SessionManagementFilter.class); SessionManagementFilter seshFilter = (SessionManagementFilter) getFilter(SessionManagementFilter.class);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("bob", "pass"); UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("bob", "pass");
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
// Register 2 sessions and then check a third // Register 2 sessions and then check a third
// req.setSession(new MockHttpSession()); // req.setSession(new MockHttpSession());
// auth.setDetails(new WebAuthenticationDetails(req)); // auth.setDetails(new WebAuthenticationDetails(req));
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
assertNull(response.getRedirectedUrl()); assertNull(response.getRedirectedUrl());
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
assertNull(response.getRedirectedUrl()); assertNull(response.getRedirectedUrl());
seshStrategy.doFilter(new MockHttpServletRequest(), response, new MockFilterChain()); seshFilter.doFilter(new MockHttpServletRequest(), response, new MockFilterChain());
assertEquals("/max-exceeded", response.getRedirectedUrl()); assertEquals("/max-exceeded", response.getRedirectedUrl());
} }

View File

@ -17,16 +17,15 @@
<para> The <literal>&lt;http&gt;</literal> element encapsulates the security configuration for <para> The <literal>&lt;http&gt;</literal> element encapsulates the security configuration for
the web layer of your application. It creates a <classname>FilterChainProxy</classname> bean the web layer of your application. It creates a <classname>FilterChainProxy</classname> bean
named "springSecurityFilterChain" which maintains the stack of security filters which make up named "springSecurityFilterChain" which maintains the stack of security filters which make up
the web security configuration <footnote> the web security configuration <footnote><para>See the <link xlink:href="#ns-web-xml">
<para>See the <link xlink:href="#ns-web-xml"> introductory chapter</link> for how to set up introductory chapter</link> for how to set up the mapping from your
the mapping from your <literal>web.xml</literal></para> <literal>web.xml</literal></para></footnote>. Some core filters are always created and
</footnote>. Some core filters are always created and others will be added to the stack others will be added to the stack depending on the attributes child elements which are
depending on the attributes child elements which are present. The positions of the standard present. The positions of the standard filters are fixed (see <link xlink:href="#filter-stack"
filters are fixed (see <link xlink:href="#filter-stack">the filter order table</link> in the >the filter order table</link> in the namespace introduction), removing a common source of
namespace introduction), removing a common source of errors with previous versions of the errors with previous versions of the framework when users had to configure the filter chain
framework when users had to configure the filter chain explicitly in explicitly in the<classname>FilterChainProxy</classname> bean. You can, of course, still do
the<classname>FilterChainProxy</classname> bean. You can, of course, still do this if you this if you need full control of the configuration. </para>
need full control of the configuration. </para>
<para> All filters which require a reference to the <para> All filters which require a reference to the
<interfacename>AuthenticationManager</interfacename> will be automatically injected with the <interfacename>AuthenticationManager</interfacename> will be automatically injected with the
internal instance created by the namespace configuration (see the <link internal instance created by the namespace configuration (see the <link
@ -59,17 +58,6 @@
<para> Whether test URLs should be converted to lower case prior to comparing with defined <para> Whether test URLs should be converted to lower case prior to comparing with defined
path patterns. If unspecified, defaults to "true" </para> path patterns. If unspecified, defaults to "true" </para>
</section> </section>
<section xml:id="session-fixation-protection">
<title><literal>session-fixation-protection</literal></title>
<para> Indicates whether an existing session should be invalidated when a user authenticates
and a new session started. If set to "none" no change will be made. "newSession" will
create a new empty session. "migrateSession" will create a new session and copy the
session attributes to the new session. Defaults to "migrateSession". </para>
<para> If enabled this will add a <classname>SessionFixationProtectionFilter</classname> to
the stack. The session fixation protection options on namespace-created instances of
<classname>AbstractAuthenticationProcessingFilter</classname> will also be set
appropriately. </para>
</section>
<section xml:id="nsa-realm"> <section xml:id="nsa-realm">
<title><literal>realm</literal></title> <title><literal>realm</literal></title>
<para> Sets the realm name used for basic authentication (if enabled). Corresponds to the <para> Sets the realm name used for basic authentication (if enabled). Corresponds to the
@ -124,8 +112,9 @@
default <interfacename>AccessDeniedHandler</interfacename> used by the default <interfacename>AccessDeniedHandler</interfacename> used by the
<classname>ExceptionTranslationFilter</classname>, (using the <classname>ExceptionTranslationFilter</classname>, (using the
<literal>error-page</literal> attribute, or to supply your own implementation using the <literal>error-page</literal> attribute, or to supply your own implementation using the
<literal>ref</literal> attribute. This is discussed in more detail in the section on <literal>ref</literal> attribute. This is discussed in more detail in the section on <link
<link xlink:href="#access-denied-handler">the <classname>ExceptionTranslationFilter</classname></link>.</para> xlink:href="#access-denied-handler">the
<classname>ExceptionTranslationFilter</classname></link>.</para>
</section> </section>
<section> <section>
<title>The <literal>&lt;intercept-url&gt;</literal> Element</title> <title>The <literal>&lt;intercept-url&gt;</literal> Element</title>
@ -161,7 +150,8 @@
there is no preference. If this attribute is present on any there is no preference. If this attribute is present on any
<literal>&lt;intercept-url&gt;</literal> element, then a <literal>&lt;intercept-url&gt;</literal> element, then a
<classname>ChannelProcessingFilter</classname> will be added to the filter stack and its <classname>ChannelProcessingFilter</classname> will be added to the filter stack and its
additional dependencies added to the application context. <!--See the chapter on <link additional dependencies added to the application context.
<!--See the chapter on <link
xlink:href="#channel-security-config">channel security</link> for an example xlink:href="#channel-security-config">channel security</link> for an example
configuration using traditional beans. --></para> configuration using traditional beans. --></para>
<para> If a <literal>&lt;port-mappings&gt;</literal> configuration is added, this will be <para> If a <literal>&lt;port-mappings&gt;</literal> configuration is added, this will be
@ -185,14 +175,13 @@
the filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the the filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the
application context to provide authentication on demand. This will always take precedence application context to provide authentication on demand. This will always take precedence
over other namespace-created entry points. If no attributes are supplied, a login page will over other namespace-created entry points. If no attributes are supplied, a login page will
be generated automatically at the URL "/spring-security-login" <footnote> be generated automatically at the URL "/spring-security-login" <footnote><para>This feature
<para>This feature is really just provided for convenience and is not intended for is really just provided for convenience and is not intended for production (where a view
production (where a view technology will have been chosen and can be used to render a technology will have been chosen and can be used to render a customized login page). The
customized login page). The class class <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for
<classname>DefaultLoginPageGeneratingFilter</classname> is responsible for rendering rendering the login page and will provide login forms for both normal form login and/or
the login page and will provide login forms for both normal form login and/or OpenID if OpenID if required.</para></footnote> The behaviour can be customized using the
required.</para> following attributes. </para>
</footnote> The behaviour can be customized using the following attributes. </para>
<section> <section>
<title><literal>login-page</literal></title> <title><literal>login-page</literal></title>
<para> The URL that should be used to render the login page. Maps to the <para> The URL that should be used to render the login page. Maps to the
@ -232,18 +221,18 @@
</section> </section>
<section> <section>
<title><literal>authentication-success-handler-ref</literal></title> <title><literal>authentication-success-handler-ref</literal></title>
<para>This can be used as an alternative to <literal>default-target-url</literal> <para>This can be used as an alternative to <literal>default-target-url</literal> and
and <literal>always-use-default-target</literal>, giving you full control over the navigation flow <literal>always-use-default-target</literal>, giving you full control over the
after a successful authentication. The value should be he name of an <interfacename>AuthenticationSuccessHandler</interfacename> navigation flow after a successful authentication. The value should be he name of an
bean in the application context. <interfacename>AuthenticationSuccessHandler</interfacename> bean in the application
</para> context. </para>
</section> </section>
<section> <section>
<title><literal>authentication-failure-handler-ref</literal></title> <title><literal>authentication-failure-handler-ref</literal></title>
<para>Can be used as an alternative to <literal>authentication-failure-url</literal>, giving you full control over the navigation flow <para>Can be used as an alternative to <literal>authentication-failure-url</literal>, giving
after an authentication failure. The value should be he name of an <interfacename>AuthenticationFailureHandler</interfacename> you full control over the navigation flow after an authentication failure. The value
bean in the application context. should be he name of an <interfacename>AuthenticationFailureHandler</interfacename> bean
</para> in the application context. </para>
</section> </section>
</section> </section>
<section xml:id="nsa-http-basic"> <section xml:id="nsa-http-basic">
@ -286,11 +275,9 @@
<title>The <literal>key</literal> Attribute</title> <title>The <literal>key</literal> Attribute</title>
<para>Maps to the "key" property of <classname>AbstractRememberMeServices</classname>. <para>Maps to the "key" property of <classname>AbstractRememberMeServices</classname>.
Should be set to a unique value to ensure that remember-me cookies are only valid within Should be set to a unique value to ensure that remember-me cookies are only valid within
the one application <footnote> the one application <footnote><para>This doesn't affect the use of
<para>This doesn't affect the use of
<classname>PersistentTokenBasedRememberMeServices</classname>, where the tokens are <classname>PersistentTokenBasedRememberMeServices</classname>, where the tokens are
stored on the server side.</para> stored on the server side.</para></footnote>. </para>
</footnote>. </para>
</section> </section>
<section> <section>
<title><literal>token-validity-seconds</literal></title> <title><literal>token-validity-seconds</literal></title>
@ -308,21 +295,33 @@
explicitly using this attribute. </para> explicitly using this attribute. </para>
</section> </section>
</section> </section>
<section xml:id="nsa-session-mgmt">
<title>The <literal>&lt;session-management&gt;</literal> Element</title>
<para>Session-management related functionality is implemented by the addition of a
<classname>SessionManagementFilter</classname> to the filter stack.</para>
<section xml:id="session-fixation-protection">
<title><literal>session-fixation-protection</literal></title>
<para> Indicates whether an existing session should be invalidated when a user authenticates
and a new session started. If set to "none" no change will be made. "newSession" will
create a new empty session. "migrateSession" will create a new session and copy the
session attributes to the new session. Defaults to "migrateSession".</para>
<para>
If session fixation protection is enabled, the <classname>SessionManagementFilter</classname>
is inected with a appropriately configured <classname>DefaultSessionAuthenticationStrategy</classname>.
See the Javadoc for this class for more details.
</para>
</section>
</section>
<section xml:id="nsa-concurrent-session-control"> <section xml:id="nsa-concurrent-session-control">
<title>The <literal>&lt;concurrent-session-control&gt;</literal> Element</title> <title>The <literal>&lt;concurrency-control&gt;</literal> Element</title>
<para> Adds support for concurrent session control, allowing limits to be placed on the number <para> Adds support for concurrent session control, allowing limits to be placed on the number
of active sessions a user can have. A <classname>ConcurrentSessionFilter</classname> will be of active sessions a user can have. A <classname>ConcurrentSessionFilter</classname> will be
created, along with a <classname>ConcurrentSessionControllerImpl</classname> and an instance created, and a <classname>ConcurrentSessionControlStrategy</classname> will be used with the
of <interfacename>SessionRegistry</interfacename> (a <classname>SessionManagementFilter</classname>. If a <literal>form-login</literal>
element has been declared, the strategy object will also be injected into the created
authentication filter. An instance of <interfacename>SessionRegistry</interfacename> (a
<classname>SessionRegistryImpl</classname> instance unless the user wishes to use a custom <classname>SessionRegistryImpl</classname> instance unless the user wishes to use a custom
bean). The controller is registered with the namespace's bean) will be created for use by the strategy.</para>
<interfacename>AuthenticationManager</interfacename>
(<classname>ProviderManager</classname>). Other namespace-created beans which require a
reference to the <interfacename>SessionRegistry</interfacename> will automatically have it
injected. </para>
<para> Note that the <literal>forceEagerSessionCreation</literal> of
<classname>HttpSessionContextIntegrationFilter</classname> will be set to
<literal>true</literal> if concurrent session control is in use. </para>
<section> <section>
<title>The <literal>max-sessions</literal> attribute</title> <title>The <literal>max-sessions</literal> attribute</title>
<para>Maps to the <literal>maximumSessions</literal> property of <para>Maps to the <literal>maximumSessions</literal> property of
@ -337,10 +336,10 @@
expiry message will just be written directly back to the response. </para> expiry message will just be written directly back to the response. </para>
</section> </section>
<section> <section>
<title>The <literal>exception-if-maximum-exceeded</literal> attribute</title> <title>The <literal>error-if-maximum-exceeded</literal> attribute</title>
<para>If set to "true" a <exceptionname>ConcurrentLoginException</exceptionname> should be <para>If set to "true" a <exceptionname>SessionAuthenticationException</exceptionname> will
raised when a user attempts to exceed the maximum allowed number of sessions. The default be raised when a user attempts to exceed the maximum allowed number of sessions. The
behaviour is to expire the original session. </para> default behaviour is to expire the original session. </para>
</section> </section>
<section> <section>
<title>The <literal>session-registry-alias</literal> and <title>The <literal>session-registry-alias</literal> and
@ -438,7 +437,8 @@
<section> <section>
<title>The <literal>&lt;authentication-provider&gt;</literal> Element</title> <title>The <literal>&lt;authentication-provider&gt;</literal> Element</title>
<para> This element is basically a shorthand syntax for configuring a <link <para> This element is basically a shorthand syntax for configuring a <link
xlink:href="#core-services-dao-provider"><classname>DaoAuthenticationProvider</classname></link>. xlink:href="#core-services-dao-provider"
><classname>DaoAuthenticationProvider</classname></link>.
<classname>DaoAuthenticationProvider</classname> loads user information from a <classname>DaoAuthenticationProvider</classname> loads user information from a
<interfacename>UserDetailsService</interfacename> and compares the username/password <interfacename>UserDetailsService</interfacename> and compares the username/password
combination with the values supplied at login. The combination with the values supplied at login. The
@ -447,15 +447,15 @@
<literal>user-service-ref</literal> attribute to point to a bean defined elsewhere in <literal>user-service-ref</literal> attribute to point to a bean defined elsewhere in
the application context). You can find examples of these variations in the <link the application context). You can find examples of these variations in the <link
xlink:href="#ns-auth-providers">namespace introduction</link>. </para> xlink:href="#ns-auth-providers">namespace introduction</link>. </para>
<section> <section>
<title>The <literal>&lt;password-encoder&gt;</literal> Element</title> <title>The <literal>&lt;password-encoder&gt;</literal> Element</title>
<para>Authentication providers can optionally be configured to use a password encoder as <para>Authentication providers can optionally be configured to use a password encoder as
described in the <link xlink:href="#ns-password-encoder">namespace introduction</link>. described in the <link xlink:href="#ns-password-encoder">namespace introduction</link>.
This will result in the bean being injected with the appropriate <interfacename>PasswordEncoder</interfacename> This will result in the bean being injected with the appropriate
instance, potentially with an accompanying <interfacename>SaltSource</interfacename> bean to <interfacename>PasswordEncoder</interfacename> instance, potentially with an
provide salt values for hashing. accompanying <interfacename>SaltSource</interfacename> bean to provide salt values for
</para> hashing. </para>
</section> </section>
</section> </section>
<section> <section>
<title>Using <literal>&lt;authentication-provider&gt;</literal> to refer to an <title>Using <literal>&lt;authentication-provider&gt;</literal> to refer to an
@ -497,15 +497,11 @@
<para> Rather than defining security attributes on an individual method or class basis using <para> Rather than defining security attributes on an individual method or class basis using
the <literal>@Secured</literal> annotation, you can define cross-cutting security the <literal>@Secured</literal> annotation, you can define cross-cutting security
constraints across whole sets of methods and interfaces in your service layer using the constraints across whole sets of methods and interfaces in your service layer using the
<literal>&lt;protect-pointcut&gt;</literal> element. This has two attributes: <itemizedlist> <literal>&lt;protect-pointcut&gt;</literal> element. This has two attributes:
<listitem> <itemizedlist><listitem><para><literal>expression</literal> - the pointcut
<para><literal>expression</literal> - the pointcut expression</para> expression</para></listitem><listitem><para><literal>access</literal> - the security
</listitem> attributes which apply</para></listitem></itemizedlist> You can find an example in
<listitem> the <link xlink:href="#ns-protect-pointcut">namespace introduction</link>. </para>
<para><literal>access</literal> - the security attributes which apply</para>
</listitem>
</itemizedlist> You can find an example in the <link xlink:href="#ns-protect-pointcut"
>namespace introduction</link>. </para>
</section> </section>
<section xml:id="nsa-custom-after-invocation"> <section xml:id="nsa-custom-after-invocation">
<title>The <literal>&lt;after-invocation-provider&gt;</literal> Element</title> <title>The <literal>&lt;after-invocation-provider&gt;</literal> Element</title>

View File

@ -1,15 +1,65 @@
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="concurrent-sessions" <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="session-mgmt"
xmlns:xlink="http://www.w3.org/1999/xlink"> xmlns:xlink="http://www.w3.org/1999/xlink">
<info> <info>
<title>Session Management</title> <title>Session Management</title>
</info> </info>
<!-- TODO: Expand and refer to namespace options --> <para>HTTP session related functonality is handled by a combination of the
<classname>SessionManagementFilter</classname> and the
<interfacename>SessionAuthenticationStrategy</interfacename> interface, which the filter
delegates to. Typical usage includes session-fixation protection attack prevention, detection of
session timeouts and restrictions on how many sessions an authenticated user may have open
concurrently.</para>
<section> <section>
<title>SessionManagementFilter</title> <title>SessionManagementFilter</title>
<para>HTTP session related functonality is handled by the <para>The <classname>SessionManagementFilter</classname> checks the contents of the
<classname>SessionManagementFilter</classname>. This </para> <interfacename>SecurityContextRepository</interfacename> against the current contents of the
<classname>SecurityContextHolder</classname> to deterine whether a user has been
authenticated during the current request, typically by a non-interactive authentication mechanism, such
as pre-authentication or remember-me <footnote><para>Authentication by mechanisms which perform a redirect
after authenticating (such as form-login) will not be detected by <classname>SessionManagementFilter</classname>,
as the filter will not be invoked during the authenticating request. Session-management functionality has to be
handled separately in these cases.
</para></footnote>.
If the repository contains a security context, the
filter does nothing. If it doesn't, and the thread-local
<interfacename>SecurityContext</interfacename> contains a (non-anonymous)
<interfacename>Authentication</interfacename> object, the filter assumes they have been
authenticated by a previous filter in the stack. It will then invoke the configured
<interfacename>SessionAuthenticationStrategy</interfacename>.</para>
<para>If the user is not currently authenticated, the filter will check whether an invalid
session ID has been requested (because of a timeout, for example) and will redirect to the
configured <literal>invalidSessionUrl</literal> if set. The easiest way to configure this is
through the namespace, <link xlink:href="#ns-session-mgmt">as described earlier</link>.</para>
</section> </section>
<section> <section>
<title><interfacename>SessionAuthenticationStrategy</interfacename></title>
<para>
<interfacename>SessionAuthenticationStrategy</interfacename> is used by both <classname>SessionManagementFilter</classname>
and <classname>AbstractAutheticationProcessingFilter</classname>, so if you are using a customized form-login class, for example, you will need to inject
it into both of these. In this case, a typical configuration, combining the namespace and custom beans might look like
<programlisting><![CDATA[
<http>
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myAuthFilter" />
<session-management session-authentication-strategy-ref="sas"/>
</http>
<beans:bean id="myAuthFilter"
class="org.springframework.security.web.authentcation.UsernamePasswordAuthenticationProcessingFilter">
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
...
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.session.DefaultAuthenticatedSessionStrategy">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
]]>
</programlisting>
</para>
</section>
<section xml:id="concurrent-sessions">
<title>Concurrency Control</title> <title>Concurrency Control</title>
<para>Spring Security is able to prevent a principal from concurrently authenticating to the <para>Spring Security is able to prevent a principal from concurrently authenticating to the
same application more than a specified number of times. Many ISVs take advantage of this to same application more than a specified number of times. Many ISVs take advantage of this to
@ -18,14 +68,17 @@
the web application from two different sessions.</para> the web application from two different sessions.</para>
<para>This feature is supported by the namespace, so please check the earlier namespace chapter <para>This feature is supported by the namespace, so please check the earlier namespace chapter
for the simplest configuration. Sometimes you need to customize things though. </para> for the simplest configuration. Sometimes you need to customize things though. </para>
<para>The implementation has changed substantially in Spring Security 3. Previously the <para>The implementation uses a specialized version of
concurrent authentication check was made by the <classname>ProviderManager</classname>, which <interfacename>SessionAuthenticationStrategy</interfacename>, called
could be injected with a <literal>ConcurrentSessionController</literal> which would check if <classname>ConcurrentSessionControlStrategy</classname>.
the user was attempting to exceed the number of sessions permitted. However, this approach <note><para>Previously the concurrent authentication check was made by the
required that an HTTP session be created in advance, which is undesirable. In Spring Security <classname>ProviderManager</classname>, which could be injected with a
3, the user is first authenticated by the <interfacename>AuthenticationManager</interfacename> <literal>ConcurrentSessionController</literal> which would check if the user was
and once they are successfully authenticated, a session is created and the check is made attempting to exceed the number of sessions permitted. However, this approach required that
whether they are allowed to have another session open.</para> an HTTP session be created in advance, which is undesirable. In Spring Security 3, the user
is first authenticated by the <interfacename>AuthenticationManager</interfacename> and once
they are successfully authenticated, a session is created and the check is made whether they
are allowed to have another session open.</para></note></para>
<para>To use concurrent session support, you'll need to add the following to <para>To use concurrent session support, you'll need to add the following to
<literal>web.xml</literal>: <programlisting><![CDATA[ <literal>web.xml</literal>: <programlisting><![CDATA[
<listener> <listener>
@ -33,40 +86,50 @@
org.springframework.security.web.session.HttpSessionEventPublisher org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class> </listener-class>
</listener> ]]> </listener> ]]>
</programlisting></para> </programlisting></para>
<para>In addition, you will need to add the <para>In addition, you will need to add the
<literal>org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter</literal> <literal>org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter</literal>
to your <classname>FilterChainProxy</classname>. The to your <classname>FilterChainProxy</classname>. The
<classname>ConcurrentSessionFilter</classname> requires two properties, <classname>ConcurrentSessionFilter</classname> requires two properties,
<literal>sessionRegistry</literal>, which generally points to an instance of <literal>sessionRegistry</literal>, which generally points to an instance of
<literal>SessionRegistryImpl</literal>, and <literal>expiredUrl</literal>, which points to <literal>SessionRegistryImpl</literal>, and <literal>expiredUrl</literal>, which points to
the page to display when a session has expired.</para> the page to display when a session has expired. A configuration using the namespace to create the
<para>The <literal>web.xml</literal> <classname>FilterChainProxy</classname> and other default beans might look like this:
<literal>HttpSessionEventPublisher</literal> causes an <literal>ApplicationEvent</literal> to <programlisting><![CDATA[
be published to the Spring <literal>ApplicationContext</literal> every time a <http>
<literal>HttpSession</literal> commences or terminates. This is critical, as it allows the <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<classname>SessionRegistryImpl</classname> to be notified when a session ends.</para> <custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myAuthFilter" />
<para>You will also need to wire up the <classname>ConcurrentSessionControllerImpl</classname>
and refer to it from your <literal>ProviderManager</literal> bean:</para> <session-management session-authentication-strategy-ref="sas"/>
<para> </http>
<programlisting><![CDATA[
<bean id="authenticationManager" <beans:bean id="concurrencyFilter"
class="org.springframework.security.authentication.ProviderManager"> class="org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter">
<property name="providers"> <beans:property name="sessionRegistry" ref="sessionRegistry" />
<!-- your providers go here --> <beans:property name="expiredUrl" value="/session-expired.htm" />
</property> </beans:bean>
<property name="sessionController" ref="concurrentSessionController"/>
</bean> <beans:bean id="myAuthFilter"
class="org.springframework.security.web.authentcation.UsernamePasswordAuthenticationProcessingFilter">
<bean id="concurrentSessionController" class= <beans:property name="sessionAuthenticationStrategy" ref="sas" />
"org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl"> ...
<property name="maximumSessions" value="1"/> </beans:bean>
<property name="sessionRegistry">
<bean <beans:bean id="sas"
class="org.springframework.security.authentication.concurrent.SessionRegistryImpl"/> class="org.springframework.security.web.session.ConcurrentSessionControlStrategy">
<property> <beans:property name="sessionRegistry" ref="sessionRegistry" />
</bean> <beans:property name="maximumSessions" value="1" />
]]></programlisting> </beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.authentication.concurrent.SessionRegistryImpl" />
]]>
</programlisting>
</para> </para>
<para>Adding the listener to <filename>web.xml</filename> causes an <literal>ApplicationEvent</literal> to
be published to the Spring <literal>ApplicationContext</literal> every time a
<literal>HttpSession</literal> commences or terminates. This is critical, as it allows the
<classname>SessionRegistryImpl</classname> to be notified when a session ends. Without it, a user
will never be able to log back in again once they have exceeded their session allowance, even if they log out
of another session or it times out.</para>
</section> </section>
</chapter> </chapter>

View File

@ -355,19 +355,31 @@
in <xref xlink:href="#channel-security"/--> in <xref xlink:href="#channel-security"/-->
</para> </para>
</section> </section>
<section xml:id="ns-concurrent-session"> <section xml:id="ns-session-mgmt">
<title>Session Management</title> <title>Session Management</title>
<para> If you wish to place constraints on a single user's ability to log in to your <section>
application, Spring Security supports this out of the box with the following simple <title>Detecting Timeouts</title>
additions. First you need to add the following listener to your <filename>web.xml</filename> <para> You can configure Spring Security to detect the submission of an invalid session ID
file to keep Spring Security updated about session lifecycle events: <programlisting language="xml"> and redirect the user to an appropriate URL. This is achieved through the
<![CDATA[ <literal>session-management</literal> element:<![CDATA[
<http>
...
<session-management invalid-session-url="/sessionTimeout.htm" />
</http>]]></para>
</section>
<section xml:id="ns-concurrent-sessions">
<title>Concurrent Session Control</title>
<para>If you wish to place constraints on a single user's ability to log in to your
application, Spring Security supports this out of the box with the following simple
additions. First you need to add the following listener to your
<filename>web.xml</filename> file to keep Spring Security updated about session
lifecycle events: <![CDATA[
<listener> <listener>
<listener-class> <listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class> </listener-class>
</listener> </listener>
]]></programlisting> Then add the following lines to your application context: <programlisting language="xml"><![CDATA[ ]]> Then add the following lines to your application context: <programlisting language="xml"><![CDATA[
<http> <http>
... ...
<session-management> <session-management>
@ -375,8 +387,8 @@
</session-management> </session-management>
</http>]]> </http>]]>
</programlisting> This will prevent a user from logging in multiple times - a </programlisting> This will prevent a user from logging in multiple times - a
second login will cause the first to be invalidated. Often you would prefer to prevent a second login will cause the first to be invalidated. Often you would prefer to prevent a
second login, in which case you can use <programlisting language="xml"><![CDATA[ second login, in which case you can use <programlisting language="xml"><![CDATA[
<http> <http>
... ...
<session-management> <session-management>
@ -384,13 +396,17 @@
</session-management> </session-management>
</http>]]> </http>]]>
</programlisting> The second login will then be rejected. By </programlisting> The second login will then be rejected. By
<quote>rejected</quote>, we mean that the user will be sent to the <quote>rejected</quote>, we mean that the user will be sent to the
<literal>authentication-failure-url</literal> if form-based login is being used. If the <literal>authentication-failure-url</literal> if form-based login is being used. If the
second authentication takes place through another non-interactive mechanism, such as second authentication takes place through another non-interactive mechanism, such as
<quote>remember-me</quote>, an <quote>unauthorized</quote> (402) error will be sent to the <quote>remember-me</quote>, an <quote>unauthorized</quote> (402) error will be sent to
client. If instead you want to use an error page, you can add the attribute the client. If instead you want to use an error page, you can add the attribute
<literal>error-url</literal> to the <literal>concurrency-control</literal> <literal>session-authentication-error-url</literal> to the
element.<!-- TODO: Link to main section in docs --></para> <literal>session-management</literal> element. </para>
<para> If you are using a customized authentication filter for form-based login, then you
have to configure concurrent session control support explicitly. More details can be found
in the <link xlink:href="#session-mgmt">Session Management chapter</link>. </para>
</section>
</section> </section>
<section xml:id="ns-openid"> <section xml:id="ns-openid">
<title>OpenID Login</title> <title>OpenID Login</title>

View File

@ -400,7 +400,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* @param sessionStrategy the implementation to use. If not set a null implementation is * @param sessionStrategy the implementation to use. If not set a null implementation is
* used. * used.
*/ */
public void setAuthenticatedSessionStrategy(SessionAuthenticationStrategy sessionStrategy) { public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) {
this.sessionStrategy = sessionStrategy; this.sessionStrategy = sessionStrategy;
} }

View File

@ -22,7 +22,7 @@ import org.springframework.util.Assert;
* @version $Id$ * @version $Id$
* @since 3.0 * @since 3.0
*/ */
public class ConcurrentSessionControlAuthenticatedSessionStrategy extends DefaultSessionAuthenticationStrategy public class ConcurrentSessionControlStrategy extends DefaultSessionAuthenticationStrategy
implements MessageSourceAware { implements MessageSourceAware {
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor(); protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private final SessionRegistry sessionRegistry; private final SessionRegistry sessionRegistry;
@ -32,7 +32,7 @@ public class ConcurrentSessionControlAuthenticatedSessionStrategy extends Defaul
/** /**
* @param sessionRegistry the session registry which should be updated when the authenticated session is changed. * @param sessionRegistry the session registry which should be updated when the authenticated session is changed.
*/ */
public ConcurrentSessionControlAuthenticatedSessionStrategy(SessionRegistry sessionRegistry) { public ConcurrentSessionControlStrategy(SessionRegistry sessionRegistry) {
Assert.notNull(sessionRegistry, "The sessionRegistry cannot be null"); Assert.notNull(sessionRegistry, "The sessionRegistry cannot be null");
super.setAlwaysCreateSession(true); super.setAlwaysCreateSession(true);
this.sessionRegistry = sessionRegistry; this.sessionRegistry = sessionRegistry;

View File

@ -98,7 +98,7 @@ public class SessionManagementFilter extends GenericFilterBean {
* *
* @param sessionStrategy the strategy object. If not set, a {@link DefaultSessionAuthenticationStrategy} is used. * @param sessionStrategy the strategy object. If not set, a {@link DefaultSessionAuthenticationStrategy} is used.
*/ */
public void setAuthenticatedSessionStrategy(SessionAuthenticationStrategy sessionStrategy) { public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) {
Assert.notNull(sessionStrategy, "authenticatedSessionStratedy must not be null"); Assert.notNull(sessionStrategy, "authenticatedSessionStratedy must not be null");
this.sessionStrategy = sessionStrategy; this.sessionStrategy = sessionStrategy;
} }

View File

@ -240,7 +240,7 @@ public class AbstractProcessingFilterTests extends TestCase {
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true); MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
filter.setFilterProcessesUrl("/j_mock_post"); filter.setFilterProcessesUrl("/j_mock_post");
filter.setAuthenticatedSessionStrategy(mock(SessionAuthenticationStrategy.class)); filter.setSessionAuthenticationStrategy(mock(SessionAuthenticationStrategy.class));
filter.setAuthenticationSuccessHandler(successHandler); filter.setAuthenticationSuccessHandler(successHandler);
filter.setAuthenticationFailureHandler(failureHandler); filter.setAuthenticationFailureHandler(failureHandler);
filter.setAuthenticationManager(mock(AuthenticationManager.class)); filter.setAuthenticationManager(mock(AuthenticationManager.class));

View File

@ -48,7 +48,7 @@ public class SessionManagementFilterTests {
// mock that repo contains a security context // mock that repo contains a security context
when(repo.containsContext(any(HttpServletRequest.class))).thenReturn(true); when(repo.containsContext(any(HttpServletRequest.class))).thenReturn(true);
SessionManagementFilter filter = new SessionManagementFilter(repo); SessionManagementFilter filter = new SessionManagementFilter(repo);
filter.setAuthenticatedSessionStrategy(strategy); filter.setSessionAuthenticationStrategy(strategy);
HttpServletRequest request = new MockHttpServletRequest(); HttpServletRequest request = new MockHttpServletRequest();
authenticateUser(); authenticateUser();
@ -62,7 +62,7 @@ public class SessionManagementFilterTests {
SecurityContextRepository repo = mock(SecurityContextRepository.class); SecurityContextRepository repo = mock(SecurityContextRepository.class);
SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class); SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class);
SessionManagementFilter filter = new SessionManagementFilter(repo); SessionManagementFilter filter = new SessionManagementFilter(repo);
filter.setAuthenticatedSessionStrategy(strategy); filter.setSessionAuthenticationStrategy(strategy);
HttpServletRequest request = new MockHttpServletRequest(); HttpServletRequest request = new MockHttpServletRequest();
filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain()); filter.doFilter(request, new MockHttpServletResponse(), new MockFilterChain());
@ -76,7 +76,7 @@ public class SessionManagementFilterTests {
// repo will return false to containsContext() // repo will return false to containsContext()
SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class); SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class);
SessionManagementFilter filter = new SessionManagementFilter(repo); SessionManagementFilter filter = new SessionManagementFilter(repo);
filter.setAuthenticatedSessionStrategy(strategy); filter.setSessionAuthenticationStrategy(strategy);
HttpServletRequest request = new MockHttpServletRequest(); HttpServletRequest request = new MockHttpServletRequest();
authenticateUser(); authenticateUser();
@ -94,7 +94,7 @@ public class SessionManagementFilterTests {
// repo will return false to containsContext() // repo will return false to containsContext()
SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class); SessionAuthenticationStrategy strategy = mock(SessionAuthenticationStrategy.class);
SessionManagementFilter filter = new SessionManagementFilter(repo); SessionManagementFilter filter = new SessionManagementFilter(repo);
filter.setAuthenticatedSessionStrategy(strategy); filter.setSessionAuthenticationStrategy(strategy);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestedSessionId("xxx"); request.setRequestedSessionId("xxx");
request.setRequestedSessionIdValid(false); request.setRequestedSessionIdValid(false);