Spring Security part I : Configuration & Security Chain
22/01/2012 2 Comments
In this series of articles we’ll dig into the Spring Security framework.
Spring Security can be considered as a flexible and portable security manager. It is a real alternative to built-in security manager available on many application servers.
All transversal tasks related to security management (login, logout, authentication, authorization …) usually handled by the application server can be delegated to Spring Security. It helps decoupling the application logic & security management from the proprietary security implementation provided by different JEE application servers.
To enable Spring Security, you should add the following jar as Maven dependency to your project:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>3.0.5.RELEASE</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.0.5.RELEASE</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.0.5.RELEASE</version> <type>jar</type> <scope>compile</scope> </dependency>
It is strongly recommended to create a separate spring-security.xml configuration file to manage all beans related to the security aspect.
In the web.xml file, Spring’s DelegatingFilterProxy class should be declared as a servlet filter
<filter> <filter-name>filterChainProxy</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter>
and declared as the first filter in the to secure all the filter chain.
<filter-mapping> <filter-name>filterChainProxy</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>ndcLogFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ...
Please notice that the property <filter-name> should point to a valid bean id in the Spring context.
The security management process comes down to the following aspects:
- Security chain: to be able to secure an application, we should clearly define a security chain with an entry and exit point. Every resource inside this chain will be secured according to user defined rules. The security chain is the main entry point for Spring Security
- Login/Logout: any decent security framework should provides a consistent way to handle login & logout events
- Authentication: during this step, the framework tries to identify the end user with the provided credentials. The authentication can be done against a third party system plugged into Spring Security
- Anonymous role: it is sometimes necessary to allow unsecured access to some resources (such as style sheet, image, login page …). In this case the anonymous role management is required
- Exception handling: a robust security system should provide a clean way to handle exceptions (invalid login/password, access denied …)
- Access management: in this step the framework will grant or deny access to requested resources based on the roles/authorities granted to the user. These authorities(roles) are determined at the Authentication step
III Security Chain
Let’s have a closer look into the spring-security.xml configuration file
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy"> <sec:filter-chain-map path-type="ant"> <sec:filter-chain pattern="/webServices/**" filters=" securityContextPersistenceFilterForWebServices, WSAuthenticationFilter, exceptionTranslationFilter, filterSecurityInterceptor" /> <sec:filter-chain pattern="/**" filters=" securityContextPersistentFilter, logoutFilter, authenticationProcessingFilter, anonymousFilter, exceptionTranslationFilter, filterSecurityInterceptor" /> </sec:filter-chain-map> </bean>
First, the id of the FilterChainProxy bean is set to filterChainProxy. This id is also the filter name of the Spring’s DelegatingFilterProxy declared previously in the web.xml file. It is the default convention.
Next, the <filter-chain-map> allows to match a particular path pattern agains a security filter chain defined in <filter-chain> tag.
The path pattern can be expressed using Ant style or regular expression and is configured by the propery path-type.
You can set as many filter chains as there are different path patterns. In the above configuration, we have a filter chain dedicated to Web Services calls and a generic filter chain for all other requests.
Please notice that the Web Services filter chain is defined before the generic filter chain because its path pattern is a subset of the generic filter chain pattern. Since the filter chains are examined in the order of their definition we are sure that Web Services requests will always be intercepted first and never be processed through the generic filter chain.
Let’s examine the generic filter chain in depth.
- securityContextPersistentFilter: this filter is used to store and retrieve the security context (user credentials, if any) between successive accesses to the application
- logoutFilter: this filter handles the logout. It should be placed at the beginning of the filter chain so a click on the logout link (or button) will not go through the rest of the chain
- authenticationProcessingFilter: this filter handles all the authentication process
- anonymousFilter: this filter handles anonymous login and creates an Authentication object in the HTTP session for later use
- exceptionTranslationFilter: this filter re-direct the user to an error page when Security exception is encountered
- filterSecurityInterceptor: this filter is manaing the access management
to be continued…