For the latest stable version, please use Spring Security 6.4.0!

Security Namespace Configuration

Namespace configuration has been available since version 2.0 of the Spring Framework. It lets you supplement the traditional Spring beans application context syntax with elements from additional XML schema. You can find more information in the Spring Reference Documentation. You can use a namespace element to more concisely configure an individual bean or, more powerfully, to define an alternative configuration syntax that more closely matches the problem domain and hides the underlying complexity from the user. A simple element can conceal the fact that multiple beans and processing steps are being added to the application context. For example, adding the following element from the security namespace to an application context starts up an embedded LDAP server for testing use within the application:

<security:ldap-server />

This is much simpler than wiring up the equivalent Apache Directory Server beans. The most common alternative configuration requirements are supported by attributes on the ldap-server element, and the user is isolated from worrying about which beans they need to create and what the bean property names are. You can find out more about the use of the ldap-server element in the chapter on LDAP Authentication. A good XML editor while editing the application context file should provide information on the attributes and elements that are available. We recommend that you try the Spring Tool Suite, as it has special features for working with standard Spring namespaces.

To start using the security namespace in your application context, add the spring-security-config jar to your classpath. Then, all you need to do is add the schema declaration to your application context file:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/security
		https://www.springframework.org/schema/security/spring-security.xsd">
	...
</beans>

In many of the examples you can see (and in the sample applications), we often use security (rather than beans) as the default namespace, which means we can omit the prefix on all the security namespace elements, making the content easier to read. You may also want to do this if you have your application context divided up into separate files and have most of your security configuration in one of them. Your security application context file would then start like this:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/security
		https://www.springframework.org/schema/security/spring-security.xsd">
	...
</beans:beans>

We assume this syntax is being used from now on in this chapter.

Design of the Namespace

The namespace is designed to capture the most common uses of the framework and provide a simplified and concise syntax for enabling them within an application. The design is based around the large-scale dependencies within the framework and can be divided up into the following areas:

  • Web/HTTP Security is the most complex part. It sets up the filters and related service beans used to apply the framework authentication mechanisms, to secure URLs, render login and error pages, and much more.

  • Business Object (Method) Security defines options for securing the service layer.

  • AuthenticationManager handles authentication requests from other parts of the framework.

  • AccessDecisionManager provides access decisions for web and method security. A default one is registered, but you can choose to use a custom one, declared with normal Spring bean syntax.

  • AuthenticationProvider instances provide mechanisms against which the authentication manager authenticates users. The namespace provides supports for several standard options and a means of adding custom beans declared with a traditional syntax.

  • UserDetailsService is closely related to authentication providers but is often also required by other beans.

We see how to configure these in the following sections.

Getting Started with Security Namespace Configuration

This section looks at how you can build up a namespace configuration to use some of the main features of the framework. We assume that you initially want to get up and running as quickly as possible and add authentication support and access control to an existing web application, with a few test logins. Then we look at how to change over to authenticating against a database or other security repository. In later sections, we introduce more advanced namespace configuration options.

web.xml Configuration

The first thing you need to do is add the following filter declaration to your web.xml file:

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

DelegatingFilterProxy is a Spring Framework class that delegates to a filter implementation that is defined as a Spring bean in your application context. In this case, the bean is named springSecurityFilterChain, which is an internal infrastructure bean created by the namespace to handle web security. In this case, the bean is named "springSecurityFilterChain", which is an internal infrastructure bean created by the namespace to handle web security. Note that you should not use this bean name yourself. Once you have added this bean to your web.xml, you are ready to start editing your application context file. Web security services are configured by the <http> element.

A Minimal <http> Configuration

To enable web security, you need the following configuration:

<http>
<intercept-url pattern="/**" access="hasRole('USER')" />
<form-login />
<logout />
</http>

That listing says that we want:

  • All URLs within our application to be secured, requiring the role ROLE_USER to access them

  • To log in to the application using a form with username and password

  • A logout URL registered which will allow us to log out of the application

The <http> element is the parent for all web-related namespace functionality. The <intercept-url> element defines a pattern, which is matched against the URLs of incoming requests using Ant path syntax. See the section on HttpFirewall for more details on how matches are actually performed. You can also use regular-expression matching as an alternative (see the namespace appendix for more details). The access attribute defines the access requirements for requests that match the given pattern. With the default configuration, this is typically a comma-separated list of roles, one of which a user must have to be allowed to make the request. The ROLE_ prefix is a marker that indicates that a simple comparison with the user’s authorities should be made. In other words, a normal role-based check should be used. Access-control in Spring Security is not limited to the use of simple roles (hence the use of the prefix to differentiate between different types of security attributes). We see later how the interpretation can vary. The interpretation of the comma-separated values in the access attribute depends on the which implementation of the AccessDecisionManager is used. Since Spring Security 3.0, you can also populate the attribute with an EL expression.

You can use multiple <intercept-url> elements to define different access requirements for different sets of URLs, but they are evaluated in the order listed and the first match is used. So you must put the most specific matches at the top. You can also add a method attribute to limit the match to a particular HTTP method (GET, POST, PUT, and so on).

To add users, you can define a set of test data directly in the namespace:

<authentication-manager>
<authentication-provider>
	<user-service>
	<!-- Password is prefixed with {noop} to indicate to DelegatingPasswordEncoder that
	NoOpPasswordEncoder should be used. This is not safe for production, but makes reading
	in samples easier. Normally passwords should be hashed using BCrypt -->
	<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
	<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
	</user-service>
</authentication-provider>
</authentication-manager>

The preceding listing shows an example of a secure way to store the same passwords. The password is prefixed with {bcrypt} to instruct DelegatingPasswordEncoder, which supports any configured PasswordEncoder for matching, that the passwords are hashed using BCrypt:

<authentication-manager>
<authentication-provider>
	<user-service>
	<user name="jimi" password="{bcrypt}$2a$10$ddEWZUl8aU0GdZPPpy7wbu82dvEw/pBpbRvDQRqA41y6mK1CoH00m"
			authorities="ROLE_USER, ROLE_ADMIN" />
	<user name="bob" password="{bcrypt}$2a$10$/elFpMBnAYYig6KRR5bvOOYeZr1ie1hSogJryg9qDlhza4oCw1Qka"
			authorities="ROLE_USER" />
	<user name="jimi" password="{noop}jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
	<user name="bob" password="{noop}bobspassword" authorities="ROLE_USER" />
	</user-service>
</authentication-provider>
</authentication-manager>

The <http> element is responsible for creating a FilterChainProxy and the filter beans that it uses. Previously common problems, such as incorrect filter ordering, are no longer an issue, as the filter positions are predefined.

The <authentication-provider> element creates a DaoAuthenticationProvider bean, and the <user-service> element creates an InMemoryDaoImpl. All authentication-provider elements must be children of the <authentication-manager> element, which creates a ProviderManager and registers the authentication providers with it. You can find more detailed information on the beans that are created in the namespace appendix. You should cross-check this appendix if you want to start understanding what the important classes in the framework are and how they are used, particularly if you want to customize things later.

The preceding configuration defines two users, their passwords, and their roles within the application (which are used for access control). You can also possible load user information from a standard properties file by setting the properties attribute on the user-service element. See the section on in-memory authentication for more details on the file format. Using the <authentication-provider> element means that the user information is used by the authentication manager to process authentication requests. You can have multiple <authentication-provider> elements to define different authentication sources. Each is consulted in turn.

At this point, you should be able to start up your application, and you should be required to log in to proceed. Try it out, or try experimenting with the “tutorial” sample application that comes with the project.

Setting a Default Post-Login Destination

If a form login is not prompted by an attempt to access a protected resource, the default-target-url option comes into play. This is the URL to which the user is taken after successfully logging in. it defaults to /. You can also configure things so that the user always ends up at this page (regardless of whether the login was “on-demand” or they explicitly chose to log in) by setting the always-use-default-target attribute to true. This is useful if your application always requires that the user starts at a “home” page, for example:

<http pattern="/login.htm*" security="none"/>
<http use-expressions="false">
<intercept-url pattern='/**' access='ROLE_USER' />
<form-login login-page='/login.htm' default-target-url='/home.htm'
		always-use-default-target='true' />
</http>

For even more control over the destination, you can use the authentication-success-handler-ref attribute as an alternative to default-target-url. The referenced bean should be an instance of AuthenticationSuccessHandler.

Advanced Web Features

This section covers various features that go beyond the basics.

Adding in Your Own Filters

If you have used Spring Security before, you know that the framework maintains a chain of filters that it uses 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 is not currently a namespace configuration option (CAS, for example). Alternatively, you might want to use a customized version of a standard namespace filter, such as the UsernamePasswordAuthenticationFilter (which is created by the <form-login> element) to take advantage of some of the extra configuration options that are available when you use the bean explicitly. 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 you use the namespace. When the application context is being created, the filter beans are sorted by the namespace handling code, and the standard Spring Security filters each have an alias in the namespace and a well-known position.

In previous versions, the sorting took place after the filter instances had been created, during post-processing of the application context. In version 3.0+ the sorting is now done at the bean metadata level, before the classes have been instantiated. This has implications for how you add your own filters to the stack as the entire filter list must be known during the parsing of the <http> element, so the syntax has changed slightly in 3.0.

The filters, aliases, and namespace elements and attributes that create the filters are shown in the following table, in the order in which they occur in the filter chain:

Table 1. Standard Filter Aliases and Ordering
Alias Filter Class Namespace Element or Attribute

DISABLE_ENCODE_URL_FILTER

DisableEncodeUrlFilter

http@disable-url-rewriting

FORCE_EAGER_SESSION_FILTER

ForceEagerSessionCreationFilter

http@create-session="ALWAYS"

CHANNEL_FILTER

ChannelProcessingFilter

http/intercept-url@requires-channel

SECURITY_CONTEXT_FILTER

SecurityContextPersistenceFilter

http

CONCURRENT_SESSION_FILTER

ConcurrentSessionFilter

session-management/concurrency-control

HEADERS_FILTER

HeaderWriterFilter

http/headers

CSRF_FILTER

CsrfFilter

http/csrf

LOGOUT_FILTER

LogoutFilter

http/logout

X509_FILTER

X509AuthenticationFilter

http/x509

PRE_AUTH_FILTER

AbstractPreAuthenticatedProcessingFilter Subclasses

N/A

CAS_FILTER

CasAuthenticationFilter

N/A

FORM_LOGIN_FILTER

UsernamePasswordAuthenticationFilter

http/form-login

BASIC_AUTH_FILTER

BasicAuthenticationFilter

http/http-basic

SERVLET_API_SUPPORT_FILTER

SecurityContextHolderAwareRequestFilter

http/@servlet-api-provision

JAAS_API_SUPPORT_FILTER

JaasApiIntegrationFilter

http/@jaas-api-provision

REMEMBER_ME_FILTER

RememberMeAuthenticationFilter

http/remember-me

ANONYMOUS_FILTER

AnonymousAuthenticationFilter

http/anonymous

SESSION_MANAGEMENT_FILTER

SessionManagementFilter

session-management

EXCEPTION_TRANSLATION_FILTER

ExceptionTranslationFilter

http

FILTER_SECURITY_INTERCEPTOR

FilterSecurityInterceptor

http

SWITCH_USER_FILTER

SwitchUserFilter

N/A

You can add your own filter to the stack by using the custom-filter element and one of these names to specify the position at which your filter should appear:

<http>
<custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" />
</http>

<beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter"/>

You can also use the after or before attributes if you want your filter to be inserted before or after another filter in the stack. You can use FIRST and LAST with the position attribute to indicate that you want your filter to appear before or after the entire stack, respectively.

Avoiding filter position conflicts

If you insert a custom filter that may occupy the same position as one of the standard filters created by the namespace, you should not include the namespace versions by mistake. Remove any elements that create filters whose functionality you want to replace.

Note that you cannot replace filters that are created by the use of the <http> element itself: SecurityContextPersistenceFilter, ExceptionTranslationFilter, or FilterSecurityInterceptor. By default, an AnonymousAuthenticationFilter is added and unless you have session-fixation protection disabled, a SessionManagementFilter is also added to the filter chain.

If you replace a namespace filter that requires an authentication entry point (that is, where the authentication process is triggered by an unauthenticated user’s attempt to access to a secured resource), you need to add a custom entry-point bean too.

Method Security

Since version 2.0, Spring Security has substantial support for adding security to your service layer methods. It provides support for JSR-250 annotation security as well as the framework’s original @Secured annotation. Since version 3.0, you can also make use of expression-based annotations. You can apply security to a single bean (by using the intercept-methods element to decorate the bean declaration), or you can secure multiple beans across the entire service layer using the AspectJ style pointcuts.

The Default AccessDecisionManager

This section assumes that you have some knowledge of the underlying architecture for access-control within Spring Security. If you do not, you can skip it and come back to it later, as this section is relevant only for people who need to do some customization to use more than simple role-based security.

When you use a namespace configuration, a default instance of AccessDecisionManager is automatically registered for you and is used to make access decisions for method invocations and web URL access, based on the access attributes you specify in your intercept-url and protect-pointcut declarations (and in annotations, if you use annotations to secure methods).

The default strategy is to use an AffirmativeBased AccessDecisionManager with a RoleVoter and an AuthenticatedVoter. You can find out more about these in the chapter on authorization.

Customizing the AccessDecisionManager

If you need to use a more complicated access control strategy, you can set an alternative for both method and web security.

For method security, you do so by setting the access-decision-manager-ref attribute on global-method-security to the id of the appropriate AccessDecisionManager bean in the application context:

<global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">
...
</global-method-security>

The syntax for web security is the same, but the attribute is on the http element:

<http access-decision-manager-ref="myAccessDecisionManagerBean">
...
</http>