I use Spring Security 3.1.4 to secure a Spring MVC 3.2.4 application deployed to Tomcat. I have the following Spring Security configuration:
<http auto-config="true" use-expressions="true">
<http-basic />
<logout ... />
<form-login ... />
<intercept-url pattern="/" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/about" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/login" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/under-construction" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/admin-task*" access="hasRole('ROLE_USER') and hasRole('ROLE_ADMINISTRATOR')" />
<intercept-url pattern="/resources/**" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
</http>
I noticed that URL patterns without a trailing slash (e.g., /about
) do not match URLs with a trailing slash (e.g., /about/
) and vice-versa. In other words, a URL with a slash and an identical URL without a slash are treated as two different URLs by Spring Security. The problem could be fixed by using two security rules:
<intercept-url pattern="/about" access="isAnonymous() or hasRole('ROLE_USER')" />
<intercept-url pattern="/about/" access="isAnonymous() or hasRole('ROLE_USER')" />
Is there a better solution?
I know that path-type="regex"
allows to define URL patterns with regular expressions, but I would like to avoid any unnecessary complexity if it's possible.
Update
As Adam Gent noted, there is an additional problem that involves URLs with a dot: /about.foo
and /about
are treated as the same URL by Spring MVC. However, Spring Security treats them as two different URLs. So, one more security rule may be necessary:
<intercept-url pattern="/about.*" .../>
<intercept-url pattern="/about.*" ...
. The reason is your Spring MVC request mappings will map/about.stuff -> /about
but your security filter will not intercept it. I found this out during a lovely security audit. – Saskatchewan