Spring Security Integration Tutorial
About this tutorial
This Spring Security tutorial guides you through the various Spring Security integration points present in the project that SpringFuse has generated for you.
If you have not generated a project yet, please generate one now!. The generated project is a full functional Spring 3 web application. It is of a great help to learn Spring Security by the example.
Spring Security Files
Here is the list of files that are involved with Spring Security in your generated project:
| File types | Description |
|---|---|
| pom.xml | Contains the Spring Security's version (currently 3.0.3.RELEASE) and the various jar dependencies required by Spring Security. |
| src/main/webapp/WEB-INF/web.xml | Spring Security's Filter is declared for all urls under /app/** The filter's name "springSecurityFilterChain" matches an internal infrastructure bean created by Spring Security. Bear in mind that URL are rewritten by urlrewrite. Take a look at the urlrewrite.xml file located in the same folder as web.xml. |
| src/main/resources/spring/applicationContext.xml |
Use the Spring Security namespace to: Set the user service bean expected by SpringSecurity. Enable @RolesAllowed annotations (jsr250) and @Secured annotations on scanned components. |
| src/main/resources/spring/spring-security-http.xml | This is where you grant access or not to your urls depending on user's role. |
| src/main/resources/spring/springmvc-webapp.xml | Enable @RolesAllowed annotations (jsr250) and @Secured annotations on scanned controllers. |
| src/main/webapp/WEB-INF/views/login/index.jsp & accessdenied.jsp | The application's login page and the page displayer to logged in user trying to access an unauthorized resource. |
| <rootpackage>/security/AccountDetailsServiceImpl.java | Implements the UserDetailsService provided by Spring Security. This service is called by Spring Security upon a login attempt. This is the glue between Spring Security and your user's account repository. |
| <rootpackage>/security/SpringSecurityContext.java | Utility class generated by Springfuse. It provides static methods to access the current username and roles. It uses the SecurityContextHolder provided by Spring Security. |
| <rootpackage>/web/controller/login/LoginController.java & LoginForm.java | Convenient login controller so SpringMVC tags can be used from the view. |
'Account' and 'Role' tables convention
The AccountDetailsServiceImpl service is the link between the SpringSecurity's world and your user's credential information. As you expect, this class must know how to access the user's information such as login and password. The generated implementation of this service varies depending on whether you follow or not SpringFuse's conventions.
By convention, during the generation phase, SpringFuse looks for 2 specials tables in your database schema, an 'Account' table and a 'Role' table. The account table is expected to store user's login and password informations while the role table is expected to store user's roles.
The 'Account' and the 'Role' tables do not need to be named Account and Role.
Account Table
SpringFuse assumes that a table is an 'Account' table when it contains at least the following mandatory columns:
| Column name | Is mandatory? | mapped Java type |
|---|---|---|
| "login" OR "username" OR "identifiant" OR "email" OR "emailAddress" OR "mail" | Yes | String |
| "password" OR "pwd" OR "passwd" OR "mot_de_passe" OR "motdepasse" | Yes | String |
| "enabled" OR "is_enabled" OR "isenabled" | No | Boolean |
When the "enabled" column (or one of its variants) is present, it is passed to SpringSecurity along with the username and password. If it is not present, 'true' is passed instead to SpringSecurity.
Role Table
SpringFuse assumes that a table is a 'Role' table when the table has a many-to-many relationship with the found 'Account' table and when the table contains the following mandatory column:
| Column name | Is mandatory? | mapped Java type |
|---|---|---|
| "authority" OR "name_locale" OR "role_name" OR "role" | Yes | String |
By default, the configuration file generated by Springfuse expects the content of the 'authority' column (or one of its variants) to match one of these role names:
- ROLE_USER
- ROLE_ADMIN
This is just a convention coming from Security's official documentation, if it does not suit your needs, you can change it manually in the files that uses these role names:
- src/main/resources/spring/spring-security-http.xml configuration file.
- <rootpackage>/dao/hibernate/HibernateFilterContext.java
- <rootpackage>/web/context/AccountContextSupport.java
- <rootpackage>/service/password/PasswordService.java
- few JSP pages under src/main/webapp/WEB-INF: search for occurences of the <security:authorize> tag...
When Account or Role table convention is not used
No Account table case
If no Account table is found, SpringFuse does as if it had found one named "SF_MOCK_ACCOUNT" and generates a mock Account DAO implementation that returns 2 dummy users (user/user and admin/admin) instead of generating an Hibernate DAO implementation. It is up to you to replace this DAO implementation with your own implementation.
No Role tables case
When no role table is found, the user's roles are retrieved using the generated 'AccountModel'.getRoleNames() method, but instead of relying on the many-to-many relationship with a role table, it returns hard coded role names. Please refer to the (SfMock)AccountModel.java generated file for more details.
Miscellaneous integration
Remember Me
The login form has a special 'remember me' checkbox. It is activated in spring-security-http.xml
Logout URL
The /logout url is intercepted by SpringSecurity filter which logs out the user. It is configured in spring-security-http.xml. Note that this logout.action url is not a SpringMvc action.
Using annotations
All is configured in the generated project so you can use in your code the @RolesAllowed annotation. We do not use it in the generated code except as an example in the <rootpackage>/service/PasswordService.java to indicates the changePassword method can only be invoked by a user having a ROLE_USER role. In other terms, you have to be logged in to be able to change your password using this method.

