Roo supports configuring Spring Security for your application via security
setup
command. In this recipe, we'll look at the security related configurations added to your application by Roo when you execute the security
setup
command. In the next recipe, Using Spring Security with Apache Directory Server, we'll look at how we can extend the Spring Security configuration to use Apache Directory
Server
for addressing security requirements of a Roo-generated web application and how to incorporate method-level security.
Create a sub-directory ch06-security
inside the C:
oo-cookbook
directory.
Copy the ch06_web_app_security.roo
script into the ch06-security
directory.
Execute the ch06_web_app_security.roo
script, which creates the flightapp-web
Roo project, sets up Hibernate as persistence provider, configures MySQL as the database for the application, creates Flight
, FlightDescription
, and Booking
JPA entities, defines a many-to-one relationship between Flight
and FlightDescription
entities, and a many-to-one relationship between Booking
and Flight
JPA entities. Also, script makes use of controller
all
command to scaffold Spring Web MVC application. If you are using a different database than MySQL or your connection settings are different than what is specified in the script, then modify the script accordingly.
Start the Roo shell from the C:
oo-cookbookch06-security
directory.
To configure Spring Security for your application through the security
setup
command, follow the steps given here:
security setup
command to set up Spring Security for the flightapp-web Spring Web MVC application, as shown here:.. roo> security setup Updated ROOTpom.xml [Added property 'spring-security.version' with value '3.0.5 .RELEASE'] Updated ROOTpom.xml [Added dependencies org.springframework.security:spring-security-core:${spring-security.version}, ...] Created SRC_MAIN_RESOURCESMETA-INFspringapplicationContext-security.xml Created SRC_MAIN_WEBAPPWEB-INFviewslogin.jspx Updated SRC_MAIN_WEBAPPWEB-INFviewsviews.xml Updated SRC_MAIN_WEBAPPWEB-INFweb.xml Updated SRC_MAIN_WEBAPPWEB-INFspringwebmvc-config.xml
perform
eclipse
command to update project's classpath settings:.. roo> perform eclipse
flightapp-web
Eclipse project into Eclipse IDEThe security
setup
command is processed by the Security add-on
of Roo. The security
setup
command is available only after you have installed Spring Web MVC artifacts by executing one of the controller
commands of Roo. This limits the use of the security add-on only to projects that make use of Spring Web MVC.
Security add-on processes the security
setup
command and performs the following actions:
spring-security-version
with value 3.0.5 to the pom.xml
file of the flightapp-web
project, as shown here:<project ...> ... <name>flightapp-web</name> <properties> <roo.version>1.1.2.RELEASE</roo.version> <spring.version>3.0.5.RELEASE</spring.version> <spring-security.version> 3.0.5.RELEASE</spring-security.version> ... </properties> ... </project>
The spring-security-version
property identifies the version of Spring Security framework required by the application. The Spring Security version number property is referenced by the <dependency>
elements in pom.xml
, as shown here:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring-security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring-security.version}</version> </dependency>
As the given configuration shows, defining the version number of Spring Security required by the flightapp-web
application as a property in pom.xml
file can ensure that pom.xml
defines dependencies on JAR files that belong to the same version of Spring Security.
applicationContext-security.xml
in SRC_MAIN_RESOURCES/META-INF/spring
directory. The applicationContext-security.xml
file configures authentication and authorization requirements of the application.DelegatingFilterProxy
servlet filter to the web.xml
file of the flightapp-web
application, as shown here: <filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The DelegatingFilterProxy
servlet filter acts as an entry point into Spring Security's web module, which handles web request security. The name of the filter springSecurityFilterChain
refers to the name of Spring Security's FlightChainProxy
instance configured in the applicationContext-security.xml
file. The DelegatingFilterProxy
filter delegates web request to FlightChainProxy
instance for performing web request security.
login.jspx
in the SRC_MAIN_WEBAPPWEB-INFviews
directory.SRC_MAIN_WEBAPPWEB-INFviewsviews.xml
tiles definitions XML file, as shown here:<definition extends="public" name="login"> <put-attribute name="body" value="/WEB-INF/views/login.jspx"/> </definition>
ParameterizableViewController
(
via view-controller
element of mvc
namespace of Spring) in webmvc-config.xml
file (located in SRC_MAIN_WEBAPPWEB-INFspring
directory) that dispatches request to login.jspx
page, as shown here:<mvc:view-controller path="/login"/>
pom.xml
file of the flightapp-web
project to include dependency on Spring Security JAR files, such as spring-security-core
, spring-security-config
, and so on.Let's now look in detail at the applicationContext-security.xml
file.
The applicationContext-security.xml
file configures Spring Security beans, which are used for authentication and authorization of requests. As we'll see shortly, Roo-generated applicationContext-security.xml
doesn't do much but gives a good starting point to configure your application-specific security.
Authentication mechanism for the application is configured in applicationContext-security.xml
via the <authentication-manager>
element of Spring's security
namespace, as shown here:
<authentication-manager alias="authenticationManager"> <authentication-provider> <password-encoder hash="sha-256"/> <user-service> <user name="admin" password="..." authorities="ROLE_ADMIN"/> <user name="user" password="..." authorities="ROLE_USER"/> </user-service> </authentication-provider> </authentication-manager>
Let's look in detail at each of the elements in the given configuration and how they work together to provide authentication services to the application:
<authentication-manager>
: It registers an instance of Spring Security's AuthenticationManager
implementation that is responsible for providing authentication services. AuthenticationManager
delegate's authentication to the AuthenticationProvider
is configured using the <authentication-provider>
sub-elements.<authentication-provider>
: It registers an instance of Spring Security's AuthenticationProvider
implementation. Spring Security provides a couple of built-in implementations of the AuthenticationProvider
interface to simplify incorporating different authentication mechanisms in the application. For instance, if you are using JA-SIG CAS for authentication, you can use CasAuthenticationProvider
implementation and if you are using an LDAP server for authentication, you can use LdapAuthenticationProvider
, and so on. The AuthenticationProvider
implementation usage is specified using the ref
attribute of the <authentication-provider>
element. If the ref
attribute is not specified (as in the case of Roo-generated applicationContext-security.xml
), DaoAuthenticationProvider
implementation is registered. DaoAuthenticationProvider
makes use of Spring Security's UserDetailsService
to authenticate users. UserDetailsService
loads user details containing username, password, and granted authorities based on the username entered by the application user. DaoAuthenticationProvider
authenticates the user by comparing the password entered by the application user with the user details loaded by UserDetailsService
.<user-service>
: It creates an in-memory UserDetailsService
instance that reads user details from a properties file or from the nested <user>
elements.<user>
: It defines a user of the application. The name
and password
attributes identify the username and password required for authentication.<password-encoder>
: It converts submitted passwords to hashed versions before comparing the submitted password with the one retrieved by UserDetailsService
. The hash
attribute specifies the hashing algorithm to use for encoding password.The following <http>
element shows how web request security is configured in the applicationContext-security.xml
file:
<http auto-config="true" use-expressions="true"> <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/> <logout logout-url="/resources/j_spring_security_logout"/> <intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')"/> <intercept-url pattern="/member/**" access="isAuthenticated()" /> <intercept-url pattern="/resources/**" access="permitAll" /> <intercept-url pattern="/**" access="permitAll" /> </http>
Let's now look in detail at how the elements in the given configuration define web request security:
<http>
: It contains the HTTP security configuration elements. It creates an instance of Spring Security's FilterChainProxy
with bean name as springSecurityFilterChain
. It is important to note that the name of the FilterChainProxy
bean is same as the name of the DelegatingFilterProxy
servlet filter configured in web.xml
file.The auto-config
attribute automatically configures Spring Security beans, which provide form-based login, logout, and HTTP BASIC authentication services.
The use-expression
attribute specifies whether the access
attributes of the <intercept-url>
element (discussed later in this recipe) can accept EL expressions.
<form-login>
: It configures Spring Security's UsernamePasswordAuthenticationFilter
filter bean (a bean that implements the javax.servlet.Filter
interface of Servlet API) and LoginUrlAuthenticationEntryPoint
bean in an application context. The UsernamePasswordAuthenticationFilter
filter bean is used by FilterChainProxy
to perform authentication. UsernamePasswordAuthenticationFilter
uses the username and password in the submitted request to attempt authentication against the configured authentication provider(s). It is important to note that the names of the request parameters that contain the username and password must be j_username
and j_password
, respectively. If you check the Roo-generated login.jspx
file for parameters that flightapp-web
project, you'll find that the names of the username and password fields are j_username
and j_password
, respectively. The LoginUrlAuthenticationEntryPoint
bean starts off the form login authentication using UsernamePasswordAuthenticationFilter
.The login-page
attribute specifies the URL of the login page. The value of this attribute is used by LoginUrlAuthenticationEntryPoint
to render the login page. The value of the attribute is /login
, which means that the <mvc:view-controller
path="/login"/>
configured controller in webmvc-config.xml
is responsible for rendering the login page.
The login-processing-url
attribute specifies the URL to which the login form is submitted. The UsernamePasswordAuthenticationFilter
handles a request submitted to the URL identified by its filterProcessesUrl
property. The value of the login-processing-url
attribute is used to set the filterProcessesUrl
property of UsernamePasswordAuthenticationFilter
. The value of the login-processing-url
attribute is /resources/j_spring_security_check
, which is the same as the value of the action
attribute of the HTML <form>
element in the Roo-generated login.jspx
file of the flightapp-web
project.
The authentication-failure-url
attribute specifies the URL to which the user is redirected if login fails. The value of this attribute /login?login_error=t
means that the <mvc:view-controller
path="/login"/>
configured controller in webmvc-config.xml
will render the login page again. The login_error
parameter in the URL is used by the login.jspx
page to show an authentication failure message on the login page, as shown here:
<logout>
: It configures the LogoutFilter
filter bean that is responsible for processing logout requests. The LogoutFilter
handles request submitted to the URL identified by its filterProcessesUrl
property. The value of logout-url
attribute is used to set the filterProcessesUrl
property of LogoutFilter
. In case of Roo-generated applicationContext-security.xml
, the value of logout-url
is /resources/j_spring_security_logout
. The footer.jspx
file (located in /WEB-INF/views
directory) contains the Logout hyperlink that is displayed if the user is logged in. The Logout hyperlink refers to /resources/j_spring_security_logout
URL, which means that when the user clicks the Logout hyperlink, the request is processed by the LogoutFilter
filter bean.<intercept-url>
: It defines the URL pattern and the corresponding access permissions. The pattern
attribute specifies the URL pattern and the access
attribute specifies the access permissions. As mentioned earlier, the <http>
element's use-expression
attribute is set to true
; therefore, the access
attribute can accept Boolean EL expressions. If the value returned by the expression is true
, then access to the URL pattern, specified by the pattern
attribute, is authorized.The hasRole
, isAuthenticated
, and permitAll
are examples of built-in expressions. The hasRole('ROLE_ADMIN')
returns true
if the role of the authenticated principal is ROLE_ADMIN
. The isAuthenticated()
returns true
if the user is not an anonymous user. The permitAll
expression always returns true
.
The <http>
element registers an implementation Spring Security's AccessDecisionManager
, which makes access decisions regarding web URL access. An incoming web request is matched against the URL patterns specified by the <intercept-url>
elements in the order in which they appear within the <http>
element. If a match is found, it'll be used by AccessDecisionManager
implementation for making access decisions. As incoming web requests are matched against the URL patterns (specified by the <intercept-url>
elements) in the order in which they appear within the <http>
element, more specific URL patterns should be declared before the more general URL patterns.
3.143.235.219