1. Overview

Spring Security provides several mechanisms to configure a request pattern as unsecured or allowing all access. Depending on each of these mechanisms – this can either mean not running the security filter chain on that path at all, or running the filter chain and allowing access.

2. access=”permitAll”

Setting up an element with access=”permitAll” will configure the authorization so that all requests are allowed on that particular path:

<intercept-url pattern="/login*" access="permitAll" />

Or, via Java configuration:

http.authorizeRequests().antMatchers("/login*").permitAll();

This is achieved without disabling the security filters – these still run, so any Spring Security related functionality will still be available.

3. filters=”none”

This is a pre-Spring 3.1 feature that has been deprecated and replaced in Spring 3.1.

The filters attribute disables the Spring Security filters chain entirely on that particular request path:

<intercept-url pattern="/login*" filters="none" />

This may cause problems when the processing of the request will require some functionality of Spring Security.

Since this is a deprecated feature Spring versions newer than 3.0, using it with Spring 3.1 will result in a runtime exception on startup:

SEVERE: Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: 
Configuration problem: The use of "filters='none'" is no longer supported. 
Please define a separate <http> element for the pattern you want to exclude 
and use the attribute "security='none'".
Offending resource: class path resource [webSecurityConfig.xml]
    at o.s.b.f.p.FailFastProblemReporter.error(FailFastProblemReporter.java:68)

4. security=”none”

As we saw in the error message above, Spring 3.1 replaces filters=”none” with a new expression – security=”none”.

The scope has changed as well – this is no longer specified at the element level. Instead, Spring 3.1 allows multiple elements to be defined – each with its own security filter chain configuration. And so, the new security attribute now belongs on at the element level.

In practice, this will look like:

<http pattern="/resources/**" security="none"/>

Or with Java configuration:

web.ignoring().antMatchers("/resources/**");

Instead of the old:

<intercept-url pattern="/resources/**" filters="none"/>

Similar to filters=”none”, this will also completely disable the Security filter chain for that request path – so when the request is handled in the application, Spring Security features will not be available.

This is not a problem for the examples above, which mainly deal with serving static resources – where no actual processing takes place. However, if the request is handled programmatically in some way – then security functionalities such as requires-channel, accessing the current user or calling secured methods will not be available.

For the same reason, there is no point specifying additional attributes on an element that has already been configured with security=”none” because that request path is unsecured and the attributes will simply be ignored.

Alternatively, access=’IS_AUTHENTICATED_ANONYMOUSLY’ can be used to allow anonymous access.

5. Caveats for security=”none”

When using multiple elements, some configured with security=”none”, keep in mind that the order in which these elements are defined is important. We want to have the specific paths first, followed the universal pattern at the very end.

Also note that, if an element doesn’t specify a pattern, then by default, that maps to the universal match pattern – “/**” – so again, this element needs to be last. If the order of the elements is not correct, the creation of the security filter chain will fail:

Caused by: java.lang.IllegalArgumentException: A universal match pattern ('/**') 
is defined  before other patterns in the filter chain, causing them to be ignored. 
Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
    at o.s.s.c.h.DefaultFilterChainValidator.checkPathOrder(DefaultFilterChainValidator.java:49)
    at o.s.s.c.h.DefaultFilterChainValidator.validate(DefaultFilterChainValidator.java:39)

6. Conclusion

This article discusses the options of allowing access to a path with Spring Security – focusing on the differences between filters=”none”, security=”none” and access=”permitAll”.

As usual, the examples are available over on GitHub.