|
@@ -14,14 +14,13 @@
|
|
|
<para>The <classname>SessionManagementFilter</classname> checks the contents of the
|
|
|
<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
|
|
|
+ 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
|
|
@@ -34,10 +33,11 @@
|
|
|
<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[
|
|
|
+ <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 this:<programlisting><![CDATA[
|
|
|
<http>
|
|
|
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myAuthFilter" />
|
|
|
<session-management session-authentication-strategy-ref="sas"/>
|
|
@@ -55,9 +55,7 @@
|
|
|
<beans:property name="maximumSessions" value="1" />
|
|
|
</beans:bean>
|
|
|
]]>
|
|
|
- </programlisting>
|
|
|
-
|
|
|
- </para>
|
|
|
+ </programlisting></para>
|
|
|
</section>
|
|
|
<section xml:id="concurrent-sessions">
|
|
|
<title>Concurrency Control</title>
|
|
@@ -70,15 +68,15 @@
|
|
|
for the simplest configuration. Sometimes you need to customize things though. </para>
|
|
|
<para>The implementation uses a specialized version of
|
|
|
<interfacename>SessionAuthenticationStrategy</interfacename>, called
|
|
|
- <classname>ConcurrentSessionControlStrategy</classname>.
|
|
|
- <note><para>Previously the concurrent authentication check was made by the
|
|
|
- <classname>ProviderManager</classname>, which could be injected with a
|
|
|
- <literal>ConcurrentSessionController</literal> which would check if the user was
|
|
|
- attempting to exceed the number of sessions permitted. However, this approach required that
|
|
|
- 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>
|
|
|
+ <classname>ConcurrentSessionControlStrategy</classname>. <note><para>Previously the
|
|
|
+ concurrent authentication check was made by the <classname>ProviderManager</classname>,
|
|
|
+ which could be injected with a <literal>ConcurrentSessionController</literal>. The latter
|
|
|
+ would check if the user was attempting to exceed the number of permitted sessions.
|
|
|
+ However, this approach required that 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
|
|
|
<literal>web.xml</literal>: <programlisting><![CDATA[
|
|
|
<listener>
|
|
@@ -87,15 +85,13 @@
|
|
|
</listener-class>
|
|
|
</listener> ]]>
|
|
|
</programlisting></para>
|
|
|
- <para>In addition, you will need to add the
|
|
|
- <literal>org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter</literal>
|
|
|
- to your <classname>FilterChainProxy</classname>. The
|
|
|
- <classname>ConcurrentSessionFilter</classname> requires two properties,
|
|
|
- <literal>sessionRegistry</literal>, which generally points to an instance of
|
|
|
- <literal>SessionRegistryImpl</literal>, and <literal>expiredUrl</literal>, which points to
|
|
|
- the page to display when a session has expired. A configuration using the namespace to create the
|
|
|
- <classname>FilterChainProxy</classname> and other default beans might look like this:
|
|
|
- <programlisting><![CDATA[
|
|
|
+ <para>In addition, you will need to add the <literal>ConcurrentSessionFilter</literal> to your
|
|
|
+ <classname>FilterChainProxy</classname>. The <classname>ConcurrentSessionFilter</classname>
|
|
|
+ requires two properties, <literal>sessionRegistry</literal>, which generally points to an
|
|
|
+ instance of <literal>SessionRegistryImpl</literal>, and <literal>expiredUrl</literal>, which
|
|
|
+ points to the page to display when a session has expired. A configuration using the namespace
|
|
|
+ to create the <classname>FilterChainProxy</classname> and other default beans might look like
|
|
|
+ this: <programlisting><![CDATA[
|
|
|
<http>
|
|
|
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
|
|
|
<custom-filter position="AUTHENTICATION_PROCESSING_FILTER" ref="myAuthFilter" />
|
|
@@ -104,7 +100,7 @@
|
|
|
</http>
|
|
|
|
|
|
<beans:bean id="concurrencyFilter"
|
|
|
- class="org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter">
|
|
|
+ class="org.springframework.security.web.session.ConcurrentSessionFilter">
|
|
|
<beans:property name="sessionRegistry" ref="sessionRegistry" />
|
|
|
<beans:property name="expiredUrl" value="/session-expired.htm" />
|
|
|
</beans:bean>
|
|
@@ -121,15 +117,15 @@
|
|
|
<beans:property name="maximumSessions" value="1" />
|
|
|
</beans:bean>
|
|
|
|
|
|
- <beans:bean id="sessionRegistry" class="org.springframework.security.authentication.concurrent.SessionRegistryImpl" />
|
|
|
+ <beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
|
|
|
]]>
|
|
|
- </programlisting>
|
|
|
- </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>
|
|
|
+ </programlisting></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>
|
|
|
</chapter>
|