Monday, December 27, 2010

Spring Security 3 - MVC: Using a Simple User-Service Tutorial

In this tutorial we will build a simple Spring MVC 3 application and provide security using Spring Security 3. We will provide a simple configuration. Our users will be authenticated based on Spring's built-in in-memory user-service (that's a lot of dashes). If you need to authenticate based on an existing database and provide a custom provider, please read my other tutorial Spring Security 3 - MVC Integration Tutorial (Part 2) instead.

Note: I suggest reading the following tutorial as well which uses the latest Spring Security 3.1
Spring Security 3.1 - Implement UserDetailsService with Spring Data JPA

What is Spring Security?
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications

Spring Security is one of the most mature and widely used Spring projects. Founded in 2003 and actively maintained by SpringSource since, today it is used to secure numerous demanding environments including government agencies, military applications and central banks. It is released under an Apache 2.0 license so you can confidently use it in your projects.

Source: Spring Security
We'll build first the Spring MVC part of our application, then add Spring Security.

Let's declare our primary controller first.

MainController

This controller declares two mappings:
/main/common - any registered user can access this page
/main/admin - only admins can access this page
Each mapping will resolve to a specific JSP page. The common JSP page is accessible by everyone, while the admin page is accessible only by admins. Right now, everyone has access to these pages because we haven't enabled Spring Security yet.

Here are the JSP pages:

commonpage.jsp



adminpage.jsp



We've finished setting-up the primary controller and the associated JSP views. Now, we add the required XML configurations to enable Spring MVC and Spring Security at the same time.

We start by adding the web.xml:

web.xml

Notice the url-patterns for the DelegatingFilterProxy and DispatcherServlet. Spring Security is placed at the root-path
/*
Whereas, Spring MVC is placed at a sub-path
/krams/*

We also referenced two important XML configuration files:
spring-security.xml 
applicationContext.xml

spring-security.xml contains configuration related to Spring Security.

spring-security.xml

The elements are self-documenting. If you're using an IDE, like Eclipse or STS, try pointing your mouse to any of these elements and you will see a short description of the element.

Notice that the bulk of the security configuration is inside the http element. Here's what we observe:

1. We declared the denied page URL in the
access-denied-page="/krams/auth/denied"

2. We provided three URLs with varying permissions. We use Spring Expression Language (SpEL) to specify the role access. For admin only access we specified hasRole('ROLE_ADMIN') and for regular users we use hasRole('ROLE_USER'). To enable SpEL, you need to set use-expressions to true

3. We declared the login URL
login-page="/krams/auth/login"

4. We declared the login failure URL
authentication-failure-url="/krams/auth/login?error=true"

5. We declared the URL where the user will be redirected if he logs out
logout-success-url="/krams/auth/login"

6. We declared the logout URL
logout-url="/krams/auth/logout"

7. We declared a default authentication-manager that references an in-memory user-service


8. We declared an in-memory user-service:

This basically declares two users with corresponding passwords and authorities. This user-service is a good way to prototype and test a Spring Security application quickly.

9. We also declared an Md5 password encoder:

When a user enters his password, it's plain string. The password we have in our database (in this case, an in-memory lists) is Md5 encoded. In order for Spring to match the passwords, it's need to encode the plain string to Md5. Once it has been encoded, then it can compare passwords.

Now we need to create a special controller that handles the login and logout requests.

LoginLogoutController

This controller declares two mappings:
/auth/login - shows the login page
/auth/denied - shows the denied access page
Each mapping will resolve to a specific JSP page.

Here are the JSP pages:

loginpage.jsp



deniedpage.jsp



That's it. We got a working Spring MVC 3 application that's secured by Spring Security. We've managed to build a simple and quick configuration Spring Security configuration.

To access the common page, enter the following URL:
http://localhost:8080/spring-security-simple-user-service/krams/main/common
To access the admin page, enter the following URL:
http://localhost:8080/spring-security-simple-user-service/krams/main/admin
To login, enter the following URL:
http://localhost:8080/spring-security-simple-user-service/krams/auth/login
To logout, enter the following URL:
http://localhost:8080/spring-security-simple-user-service/krams/auth/logout
I suggest you read my other tutorial Spring Security 3 - MVC Integration Tutorial (Part 2) for comparison purposes.

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring3-security-mvc-integration-tutorial/

You can download the project as a Maven build. Look for the spring-security-simple-user-service.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring Security 3 - MVC: Using a Simple User-Service Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring 3 MVC: Using @ModelAttribute in Your JSPs

In this tutorial we will create a simple Spring 3 MVC application that uses JSPs for the presentation layer. We will create a simnple CRUD system using the @ModelAttribute

What is @ModelAttribute
@ModelAttribute has two usage scenarios in controllers. When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.

You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.

Note
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database. Such an attribute can then already be accessed through @ModelAttribute annotated handler method parameters in the chosen handler method, potentially with binding and validation applied to it.

Source: Spring 3 Reference Documentation
The @ModelAttribute is a convenient annotation for exposing your objects to your JSP pages, and returning the object back to your Controllers.

If you're familiar with the classin Spring of doing things, this annotation combines functionalities of a formBackingObject (or commandObject) and SimpleFormController's referenceData. However, as of Spring 3.0, these have been deprecated in favor of annotated controllers (Source: Spring 3 API SimpleFormController)

Let's start by declaring the required Spring configurations.

To enable Spring MVC we need to add it in the web.xml

web.xml

Take note of the URL pattern. When accessing any pages in our MVC application, the host name must be appended with
/krams
In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml


This XML config declares a view resolver. All references to a JSP name in the controllers will map to a corresponding JSP in the /WEB-INF/jsp location.

By convention, we must declare an applicationContext.xml

applicationContext.xml

This XML config declares three beans to activate the Spring 3 MVC programming model.

We're done with the required Spring XML configurations. We now focus on the two usage patterns of the @ModelAttribute annotation.

Pattern 1: Method Level
You can also use @ModelAttribute at the method level to provide reference data for the model (see the populatePetTypes() method in the following example). For this usage the method signature can contain the same types as documented previously for the @RequestMapping annotation.
Source: Spring 3 Reference Documentation
This means we declare a method in our controller and annotate the method with @ModelAttribute.

We will examine this pattern by displaying a list of addresses. First let's declare our controller.

AddressController

The controller has a method named getAllAddresses() that's been annotated with @ModelAttribute. We also provide a model name addresses

The model attribute addresses is referenced in the JSP page.

addressespage.jsp

In this controller we have to mappings:
/address/list1
/address/list2
Both mappings will yield the same result. However the models are retrieved in different ways.

The getAllUsingModelAttribute() method doesn't pass any model but instead relies on the @ModelAttribute for its data

Here's the actual screenshot of the JSP page from /address/list1

The getAllUsingModel() method retrieves the model by manually adding it on the Model. It also adds an extra model data named greetings

Here's the actual screenshot of the JSP page from /address/list2

They both produce the same list of addresses. So what's the difference? I don't see any except for one major difference:
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database.

Source: Spring 3 Reference Documentation
Using the @ModelAttribute automatically prepopulates your list. If you're doing some updates in your controller, you might still get the old list unless you specifically override the list from the @ModelAttribute.

This is better explained when we move to the next usage pattern.

Pattern 2: Method Parameter Level
When you place it on a method parameter, @ModelAttribute maps a model attribute to the specific, annotated method parameter (see the processSubmit() method below). This is how the controller gets a reference to the object holding the data entered in the form.rameters in the chosen handler method, potentially with binding and validation applied to it.

Source: Spring 3 Reference Documentation
This means we have a method with a parameter and we annotate that parameter with a @ModelAttribute. The purpose of this pattern is to pass the data from the JSP page back to your controller. The data is automatically converted to a Java object.

We will examine this pattern by displaying a list of persons that we can edit and update. This example will also showcase some of Spring 3's RESTful annotations.

We begin by defining our main controller.

MainController.

This controller declares two @ModelAttribute at the method level. We already know what that does. Then there's a @ModelAttribute at the method parameter level:

This basically means your JSP page is sending a model attribute named personAttribute. Your controller picks this model attribute and assign it to a Java object Person. In this way you're manipulating an object instead of HTTP request parameters.

In this controller we have three mappings:
/main - retrieve all persons
/main/edit/{id} - (GET) retrieve and edit a person by his id 
/main/edit/{id} - (POST) save a person based on his id
Notice we have two /main/edit/{id}. How does our controller know which one to call? The controller's @RequestMapping doesn't just rely on the mapping value but it also uses the method type. In our case, it's either POST or GET. The GET method is used when we retrieve a page; whereas, the POST method is used when we're submitting a form. For more info, please check the following blog from SpringSource Annotated Web MVC Controllers in Spring 2.5

Also, we're using a special identifier in the mappings. We have declared a {id} in the path, and referenced that as @PathVariable in the method parameter. This is a URI template, one of the RESTful features of Spring 3 MVC.

What is a URI template?
A URI template is a URI-like string, containing one or more variable names. When these variables are substituted for values, the template becomes a URI. For more information, see the proposed RFC.

Source: REST in Spring 3: @MVC
For a thorough description of this subject, please visit the blog from SpringSourceREST in Spring 3: @MVC

Let's examine the associate JSP view for each mappings.

personspage.jsp

This is referenced by the mapping /main. There's nothing special here. This is exactly similar with our Address example earlier.

editpage.jsp

This JSP page is returned by the following controller method:

This method searches a person based on his id. If found, a model attribute is added in the Model. The name of the attribute is personAttribute. This can be any name.

To access the edit page, we need to manually type the following URL in the browser:
http://localhost:8080/spring-jsp-model-attribute/krams/main/edit/2
Just make sure to change the number to match the id that you want to edit.

Here's the Edit page:

When we're done editing the person, we submit the form.

Notice we use POST to submit the data. We also use the same model attribute name. We also pass the id in the action URL.

Once the data is sent, it is picked by the controller and assigned to the saveEdit method.

I advise my readers to read the important comments within this method. To display again the list of persons we can either pass the model manually or rely on the @ModelAttribute on the Method Level. However, there's a problem if you follow the Method Level. It doesn't show the updated list. You have to refresh the browser again to see it. Why?
Note
@ModelAttribute annotated methods are executed before the chosen @RequestMapping annotated handler method. They effectively pre-populate the implicit model with specific attributes, often loaded from a database.

Source: Spring 3 Reference Documentation
Because the list is populated even before it's processed by the method! As a workaround, you must pass the model manually so that you don't need to refresh the browser.

Here's the final JSP page.

Our application is now finished. We've managed to build a simple Spring 3 MVC application that uses JSPs for the presentation layer. We've also discussed the usage patterns of the @ModelAttribute.

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-jsp-model-attribute/

You can download the project as a Maven build. Look for the spring-jsp-model-attribute.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run

If you want to learn more about Spring MVC and Jasper, feel free to read my other tutorials in the Tutorials section.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring 3 MVC: Using @ModelAttribute in Your JSPs ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share