SEC-1229: Further doc and mods to namespace config/naming to make it more consistent
This commit is contained in:
@@ -17,16 +17,15 @@
|
||||
<para> The <literal><http></literal> element encapsulates the security configuration for
|
||||
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
|
||||
the web security configuration <footnote>
|
||||
<para>See the <link xlink:href="#ns-web-xml"> introductory chapter</link> for how to set up
|
||||
the mapping from your <literal>web.xml</literal></para>
|
||||
</footnote>. Some core filters are always created and others will be added to the stack
|
||||
depending on the attributes child elements which are present. The positions of the standard
|
||||
filters are fixed (see <link xlink:href="#filter-stack">the filter order table</link> in the
|
||||
namespace introduction), removing a common source of errors with previous versions of the
|
||||
framework when users had to configure the filter chain explicitly in
|
||||
the<classname>FilterChainProxy</classname> bean. You can, of course, still do this if you
|
||||
need full control of the configuration. </para>
|
||||
the web security configuration <footnote><para>See the <link xlink:href="#ns-web-xml">
|
||||
introductory chapter</link> for how to set up the mapping from your
|
||||
<literal>web.xml</literal></para></footnote>. Some core filters are always created and
|
||||
others will be added to the stack depending on the attributes child elements which are
|
||||
present. The positions of the standard filters are fixed (see <link xlink:href="#filter-stack"
|
||||
>the filter order table</link> in the namespace introduction), removing a common source of
|
||||
errors with previous versions of the framework when users had to configure the filter chain
|
||||
explicitly in the<classname>FilterChainProxy</classname> bean. You can, of course, still do
|
||||
this if you need full control of the configuration. </para>
|
||||
<para> All filters which require a reference to the
|
||||
<interfacename>AuthenticationManager</interfacename> will be automatically injected with the
|
||||
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
|
||||
path patterns. If unspecified, defaults to "true" </para>
|
||||
</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">
|
||||
<title><literal>realm</literal></title>
|
||||
<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
|
||||
<classname>ExceptionTranslationFilter</classname>, (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
|
||||
<link xlink:href="#access-denied-handler">the <classname>ExceptionTranslationFilter</classname></link>.</para>
|
||||
<literal>ref</literal> attribute. This is discussed in more detail in the section on <link
|
||||
xlink:href="#access-denied-handler">the
|
||||
<classname>ExceptionTranslationFilter</classname></link>.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>The <literal><intercept-url></literal> Element</title>
|
||||
@@ -161,7 +150,8 @@
|
||||
there is no preference. If this attribute is present on any
|
||||
<literal><intercept-url></literal> element, then a
|
||||
<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
|
||||
configuration using traditional beans. --></para>
|
||||
<para> If a <literal><port-mappings></literal> configuration is added, this will be
|
||||
@@ -185,14 +175,13 @@
|
||||
the filter stack and an <classname>LoginUrlAuthenticationEntryPoint</classname> to the
|
||||
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
|
||||
be generated automatically at the URL "/spring-security-login" <footnote>
|
||||
<para>This feature is really just provided for convenience and is not intended for
|
||||
production (where a view technology will have been chosen and can be used to render a
|
||||
customized login page). The class
|
||||
<classname>DefaultLoginPageGeneratingFilter</classname> is responsible for rendering
|
||||
the login page and will provide login forms for both normal form login and/or OpenID if
|
||||
required.</para>
|
||||
</footnote> The behaviour can be customized using the following attributes. </para>
|
||||
be generated automatically at the URL "/spring-security-login" <footnote><para>This feature
|
||||
is really just provided for convenience and is not intended for production (where a view
|
||||
technology will have been chosen and can be used to render a customized login page). The
|
||||
class <classname>DefaultLoginPageGeneratingFilter</classname> is responsible for
|
||||
rendering the login page and will provide login forms for both normal form login and/or
|
||||
OpenID if required.</para></footnote> The behaviour can be customized using the
|
||||
following attributes. </para>
|
||||
<section>
|
||||
<title><literal>login-page</literal></title>
|
||||
<para> The URL that should be used to render the login page. Maps to the
|
||||
@@ -232,18 +221,18 @@
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>authentication-success-handler-ref</literal></title>
|
||||
<para>This can be used as an alternative to <literal>default-target-url</literal>
|
||||
and <literal>always-use-default-target</literal>, giving you full control over the navigation flow
|
||||
after a successful authentication. The value should be he name of an <interfacename>AuthenticationSuccessHandler</interfacename>
|
||||
bean in the application context.
|
||||
</para>
|
||||
<para>This can be used as an alternative to <literal>default-target-url</literal> and
|
||||
<literal>always-use-default-target</literal>, giving you full control over the
|
||||
navigation flow after a successful authentication. The value should be he name of an
|
||||
<interfacename>AuthenticationSuccessHandler</interfacename> bean in the application
|
||||
context. </para>
|
||||
</section>
|
||||
<section>
|
||||
<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
|
||||
after an authentication failure. The value should be he name of an <interfacename>AuthenticationFailureHandler</interfacename>
|
||||
bean in the application context.
|
||||
</para>
|
||||
<para>Can be used as an alternative to <literal>authentication-failure-url</literal>, giving
|
||||
you full control over the navigation flow after an authentication failure. The value
|
||||
should be he name of an <interfacename>AuthenticationFailureHandler</interfacename> bean
|
||||
in the application context. </para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="nsa-http-basic">
|
||||
@@ -286,11 +275,9 @@
|
||||
<title>The <literal>key</literal> Attribute</title>
|
||||
<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
|
||||
the one application <footnote>
|
||||
<para>This doesn't affect the use of
|
||||
the one application <footnote><para>This doesn't affect the use of
|
||||
<classname>PersistentTokenBasedRememberMeServices</classname>, where the tokens are
|
||||
stored on the server side.</para>
|
||||
</footnote>. </para>
|
||||
stored on the server side.</para></footnote>. </para>
|
||||
</section>
|
||||
<section>
|
||||
<title><literal>token-validity-seconds</literal></title>
|
||||
@@ -308,21 +295,33 @@
|
||||
explicitly using this attribute. </para>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="nsa-session-mgmt">
|
||||
<title>The <literal><session-management></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">
|
||||
<title>The <literal><concurrent-session-control></literal> Element</title>
|
||||
<title>The <literal><concurrency-control></literal> Element</title>
|
||||
<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
|
||||
created, along with a <classname>ConcurrentSessionControllerImpl</classname> and an instance
|
||||
of <interfacename>SessionRegistry</interfacename> (a
|
||||
created, and a <classname>ConcurrentSessionControlStrategy</classname> will be used with the
|
||||
<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
|
||||
bean). The controller is registered with the namespace's
|
||||
<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>
|
||||
bean) will be created for use by the strategy.</para>
|
||||
<section>
|
||||
<title>The <literal>max-sessions</literal> attribute</title>
|
||||
<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>
|
||||
</section>
|
||||
<section>
|
||||
<title>The <literal>exception-if-maximum-exceeded</literal> attribute</title>
|
||||
<para>If set to "true" a <exceptionname>ConcurrentLoginException</exceptionname> should be
|
||||
raised when a user attempts to exceed the maximum allowed number of sessions. The default
|
||||
behaviour is to expire the original session. </para>
|
||||
<title>The <literal>error-if-maximum-exceeded</literal> attribute</title>
|
||||
<para>If set to "true" a <exceptionname>SessionAuthenticationException</exceptionname> will
|
||||
be raised when a user attempts to exceed the maximum allowed number of sessions. The
|
||||
default behaviour is to expire the original session. </para>
|
||||
</section>
|
||||
<section>
|
||||
<title>The <literal>session-registry-alias</literal> and
|
||||
@@ -438,7 +437,8 @@
|
||||
<section>
|
||||
<title>The <literal><authentication-provider></literal> Element</title>
|
||||
<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
|
||||
<interfacename>UserDetailsService</interfacename> and compares the username/password
|
||||
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
|
||||
the application context). You can find examples of these variations in the <link
|
||||
xlink:href="#ns-auth-providers">namespace introduction</link>. </para>
|
||||
<section>
|
||||
<title>The <literal><password-encoder></literal> Element</title>
|
||||
<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>.
|
||||
This will result in the bean being injected with the appropriate <interfacename>PasswordEncoder</interfacename>
|
||||
instance, potentially with an accompanying <interfacename>SaltSource</interfacename> bean to
|
||||
provide salt values for hashing.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>The <literal><password-encoder></literal> Element</title>
|
||||
<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>.
|
||||
This will result in the bean being injected with the appropriate
|
||||
<interfacename>PasswordEncoder</interfacename> instance, potentially with an
|
||||
accompanying <interfacename>SaltSource</interfacename> bean to provide salt values for
|
||||
hashing. </para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title>Using <literal><authentication-provider></literal> to refer to an
|
||||
@@ -497,15 +497,11 @@
|
||||
<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
|
||||
constraints across whole sets of methods and interfaces in your service layer using the
|
||||
<literal><protect-pointcut></literal> element. This has two attributes: <itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>expression</literal> - the pointcut expression</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<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>
|
||||
<literal><protect-pointcut></literal> element. This has two attributes:
|
||||
<itemizedlist><listitem><para><literal>expression</literal> - the pointcut
|
||||
expression</para></listitem><listitem><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 xml:id="nsa-custom-after-invocation">
|
||||
<title>The <literal><after-invocation-provider></literal> Element</title>
|
||||
|
||||
@@ -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">
|
||||
<info>
|
||||
<title>Session Management</title>
|
||||
</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>
|
||||
<title>SessionManagementFilter</title>
|
||||
<para>HTTP session related functonality is handled by the
|
||||
<classname>SessionManagementFilter</classname>. This </para>
|
||||
<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
|
||||
<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>
|
||||
<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>
|
||||
<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
|
||||
@@ -18,14 +68,17 @@
|
||||
the web application from two different sessions.</para>
|
||||
<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>
|
||||
<para>The implementation has changed substantially in Spring Security 3. 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>
|
||||
<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>
|
||||
<para>To use concurrent session support, you'll need to add the following to
|
||||
<literal>web.xml</literal>: <programlisting><![CDATA[
|
||||
<listener>
|
||||
@@ -33,40 +86,50 @@
|
||||
org.springframework.security.web.session.HttpSessionEventPublisher
|
||||
</listener-class>
|
||||
</listener> ]]>
|
||||
</programlisting></para>
|
||||
</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.</para>
|
||||
<para>The <literal>web.xml</literal>
|
||||
<literal>HttpSessionEventPublisher</literal> 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.</para>
|
||||
<para>You will also need to wire up the <classname>ConcurrentSessionControllerImpl</classname>
|
||||
and refer to it from your <literal>ProviderManager</literal> bean:</para>
|
||||
<para>
|
||||
<programlisting><![CDATA[
|
||||
<bean id="authenticationManager"
|
||||
class="org.springframework.security.authentication.ProviderManager">
|
||||
<property name="providers">
|
||||
<!-- your providers go here -->
|
||||
</property>
|
||||
<property name="sessionController" ref="concurrentSessionController"/>
|
||||
</bean>
|
||||
|
||||
<bean id="concurrentSessionController" class=
|
||||
"org.springframework.security.authentication.concurrent.ConcurrentSessionControllerImpl">
|
||||
<property name="maximumSessions" value="1"/>
|
||||
<property name="sessionRegistry">
|
||||
<bean
|
||||
class="org.springframework.security.authentication.concurrent.SessionRegistryImpl"/>
|
||||
<property>
|
||||
</bean>
|
||||
]]></programlisting>
|
||||
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" />
|
||||
|
||||
<session-management session-authentication-strategy-ref="sas"/>
|
||||
</http>
|
||||
|
||||
<beans:bean id="concurrencyFilter"
|
||||
class="org.springframework.security.web.authentication.concurrent.ConcurrentSessionFilter">
|
||||
<beans:property name="sessionRegistry" ref="sessionRegistry" />
|
||||
<beans:property name="expiredUrl" value="/session-expired.htm" />
|
||||
</beans:bean>
|
||||
|
||||
<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.ConcurrentSessionControlStrategy">
|
||||
<beans:property name="sessionRegistry" ref="sessionRegistry" />
|
||||
<beans:property name="maximumSessions" value="1" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="sessionRegistry" class="org.springframework.security.authentication.concurrent.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>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -355,19 +355,31 @@
|
||||
in <xref xlink:href="#channel-security"/-->
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="ns-concurrent-session">
|
||||
<section xml:id="ns-session-mgmt">
|
||||
<title>Session Management</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: <programlisting language="xml">
|
||||
<![CDATA[
|
||||
<section>
|
||||
<title>Detecting Timeouts</title>
|
||||
<para> You can configure Spring Security to detect the submission of an invalid session ID
|
||||
and redirect the user to an appropriate URL. This is achieved through the
|
||||
<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-class>
|
||||
org.springframework.security.web.session.HttpSessionEventPublisher
|
||||
</listener-class>
|
||||
</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>
|
||||
...
|
||||
<session-management>
|
||||
@@ -375,8 +387,8 @@
|
||||
</session-management>
|
||||
</http>]]>
|
||||
</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, in which case you can use <programlisting language="xml"><![CDATA[
|
||||
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[
|
||||
<http>
|
||||
...
|
||||
<session-management>
|
||||
@@ -384,13 +396,17 @@
|
||||
</session-management>
|
||||
</http>]]>
|
||||
</programlisting> The second login will then be rejected. By
|
||||
<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
|
||||
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
|
||||
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>
|
||||
element.<!-- TODO: Link to main section in docs --></para>
|
||||
<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
|
||||
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 client. If instead you want to use an error page, you can add the attribute
|
||||
<literal>session-authentication-error-url</literal> to the
|
||||
<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 xml:id="ns-openid">
|
||||
<title>OpenID Login</title>
|
||||
|
||||
Reference in New Issue
Block a user