See the separate Remember-Me chapter for information on remember-me namespace configuration.
If your application supports both HTTP and HTTPS, and you require that particular URLs can only be accessed over HTTPS, then this is
directly supported using the requires-channel
attribute on <intercept-url>
:
<http> <intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/> <intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/> ... </http>
With this configuration in place, if a user attempts to access anything matching the "/secure/**" pattern using HTTP, they will first be redirected to an HTTPS URL. The available options are "http", "https" or "any". Using the value "any" means that either HTTP or HTTPS can be used.
If your application uses non-standard ports for HTTP and/or HTTPS, you can specify a list of port mappings as follows:
<http> ... <port-mappings> <port-mapping http="9080" https="9443"/> </port-mappings> </http>
You can find a more in-depth discussion of channel security in Chapter 7, Channel Security.
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 web.xml
file to keep Spring Security updated about
session lifecycle events:
<listener> <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class> </listener>
Then add the following line to your application context:
<http> ... <concurrent-session-control max-sessions="1" /> </http>
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
<http> ... <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/> </http>
The second login will then be rejected.
The namespace supports OpenID login either instead of, or in addition to normal form-based login, with a simple change:
<http> <intercept-url pattern="/**" access="ROLE_USER" /> <openid-login /> </http>
You should then register yourself with an OpenID provider (such as myopenid.com), and
add the user information to your in-memory <user-service>
:
<user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
You should be able to login using the myopenid.com
site to authenticate.
If you've used Spring Security before, you'll know that the framework maintains a chain
of filters in order to apply its services. You may want to add your own filters to the stack at
particular locations or use a Spring Security filter for which there isn't currently a namespace
configuration option (CAS, for example). Or you might want to use a customized version of a
standard namespace filter, such as the AuthenticationProcessingFilter
which is created by the
<form-login>
element, taking advantage of some of the extra configuration options which are
available by using defining the bean directly. How can you do this with namespace configuration,
since the filter chain is not directly exposed?
The order of the filters is always strictly enforced when using the namespace. Each Spring Security
filter implements the Spring Ordered
interface and the filters created by the namespace
are sorted during initialization. The standard Spring Security filters each have an alias in the namespace. The filters, aliases
and namespace elements/attributes which create the filters are shown in Table 2.1, “Standard Filter Aliases and Ordering”.
Table 2.1. Standard Filter Aliases and Ordering
Alias | Filter Class | Namespace Element or Attribute |
---|---|---|
CHANNEL_FILTER | ChannelProcessingFilter | http/intercept-url |
CONCURRENT_SESSION_FILTER | ConcurrentSessionFilter
| http/concurrent-session-control |
SESSION_CONTEXT_INTEGRATION_FILTER | HttpSessionContextIntegrationFilter | http |
LOGOUT_FILTER | LogoutFilter | http/logout |
X509_FILTER | X509PreAuthenticatedProcessigFilter | http/x509 |
PRE_AUTH_FILTER | AstractPreAuthenticatedProcessingFilter Subclasses | N/A |
CAS_PROCESSING_FILTER | CasProcessingFilter | N/A |
AUTHENTICATION_PROCESSING_FILTER | AuthenticationProcessingFilter | http/form-login |
BASIC_PROCESSING_FILTER | BasicProcessingFilter | http/http-basic |
SERVLET_API_SUPPORT_FILTER | SecurityContextHolderAwareRequestFilter | http/@servlet-api-provision |
REMEMBER_ME_FILTER | RememberMeProcessingFilter | http/remember-me |
ANONYMOUS_FILTER | AnonymousProcessingFilter | http/anonymous |
EXCEPTION_TRANSLATION_FILTER | ExceptionTranslationFilter | http |
NTLM_FILTER | NtlmProcessingFilter | N/A |
FILTER_SECURITY_INTERCEPTOR | FilterSecurityInterceptor | http |
SWITCH_USER_FILTER | SwitchUserProcessingFilter | N/A |
You can add your own filter to the stack, using the custom-filter
element and one of these
names to specify the position your filter should appear at:
<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"> <custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/> </beans:bean>
You can also use the after
or before
attribtues if you want your filter
to be inserted before or after another filter in the stack. The names "FIRST" and "LAST" can be used with the
position
attribute to indicate that you want your filter to appear before or after the entire stack, respectively.
If you are inserting a custom filter which may occupy the same position as one of the standard filters created by the namespace
then it's important that you don't include the namespace versions by mistake. Avoid using the
auto-config
attribute and remove any elements which create filters whose functionality you want to replace.
Note that you can't replace filters which are created by the use of the <http>
element itself - HttpSessionContextIntegrationFilter
, ExceptionTranslationFilter
or
FilterSecurityInterceptor
.
If you're replacing a namespace filter which requires an authentication entry point (i.e. where the authentication process is triggered by an attempt by an unauthenticated user to access to a secured resource), you will need to add a custom entry point bean too.
If you aren't using form login, OpenID or basic authentication through the namespace, you may
want to define an authentication filter and entry point using a traditional bean syntax and link them
into the namespace, as we've just seen. The corresponding AuthenticationEntryPoint
can be set using the
entry-point-ref
attribute on the <http>
element.
The CAS sample application is a good example of the use of custom beans with the namespace, including this syntax. If you aren't familiar with authentication entry points, they are discussed in the technical overview chapter.
Session fixation
attacks are a potential risk where it is possible for a malicious attacker to create
a session by accessing a site, then persuade another user to log in with the same session
(by sending them a link containing the session identifier as a parameter, for example). Spring Security
protects against this automatically by creating a new session when a user logs in. If you don't require
this protection, or it conflicts with some other requirement, you can control the behaviour using the
session-fixation-protection
attribute on <http>
, which
has three options
migrateSession
- creates a new session and copies the existing
session attributes to the new session. This is the default.
none
- Don't do anything. The original session will be retained.
newSession
- Create a new "clean" session, without copying the existing session data.