Spring Security is used to secure the access to the generated web application. This tutorial guides you through the various Spring Security integration points in the project that SpringFuse has generated for you.
If you have not generated a project yet, please follow the Getting Started Tutorial or the instructions to reverse your own database.
Here is the list of files that are involved with Spring Security in your generated project:
| pom.xml | Contains the Spring Security's version and the various jar dependencies required by Spring Security. |
| src/main/webapp/WEB-INF/web.xml | Spring Security's Filter is declared and mapped to all *.action urls. The filter's name "springSecurityFilterChain" matches an internal infrastructure bean created by Spring Security. |
| src/main/resources/spring/applicationContext.xml |
Set the user service bean expected by SpringSecurity. Enable @RolesAllowed annotations (jsr250) and @Secured annotations on scanned components. |
| src/main/resources/spring/applicationContext-security-http.xml | SpringSecurity's http configuration. |
| src/main/resources/spring/springmvc-webapp.xml | Enable @RolesAllowed annotations (jsr250) and @Secured annotations on scanned controllers. |
| src/main/webapp/WEB-INF/login/index.jsp & accessdenied.jsp | The application's login page. |
| <root package>/security/AccountServiceDetailsImpl.java | Service called by Spring Security upon a login attempt. |
| <root package>/security/SpringSecurityContext.java | Utility class. |
| <root package>/web/controller/login/LoginController.java & LoginForm.java | Convenient login controller so SpringMVC tags can be used from the view. |
The AccountServiceDetailsImpl 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.
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 |
| "username" OR "login" OR "user_name" OR "identifiant" | 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 is present, it is passed to SpringSecurity along with the username and password. If it is not present, 'true' is passed instead to SpringSecurity.
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 |
The generated configuration expects the content of the 'authority' column to match one of these role names:
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/applicationContext-security-http.xml configuration file.
* <root package>/hibernate/support/HibernateFilterContext.java
* <root package>/web/context/AccountContextSupport.java
* <root package>/service/password/PasswordService.java
* few JSP pages under src/main/webapp/WEB-INF: search for occurences of the <security:authorize> tag...
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.
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 SfMockAccountModel.java generated file for more details.
The login form has a special 'remember me' checkbox. It is activated in applicationContext-security-http.xml
The /logout.action url in intercepted by SpringSecurity filter which logs out the user. It is configured in applicationContext-security-http.xml. Note that this logout.action url is not a SpringMvc action.
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 <root package>/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.