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

Sunday, December 26, 2010

Spring WS 2 and Spring 3 MVC Integration Tutorial

In this tutorial we will integrate Spring WS 2 and Spring 3 MVC. We will develop a Spring WS web service that follows a Contract-First development. We will also take advantage of the latest Spring WS 2.0.0 RC2 features and use marshalling techniques to efficiently manipulate XML requests. We will use Spring 3 MVC to display our list of subscribers. It's highly recommended to read first the Spring WS: A Tutorial Using the Latest 2.0.0 RC2 Build because that's the foundation of this tutorial.

What is Spring Web Services (WS)?
Spring Web Services (Spring-WS) is a product of the Spring community focused on creating document-driven Web services. Spring Web Services aims to facilitate contract-first SOAP service development, allowing for the creation of flexible web services using one of the many ways to manipulate XML payloads. The product is based on Spring itself, which means you can use the Spring concepts such as dependency injection as an integral part of your Web service.

Source: Spring WS Reference 2.0

What is Contract-First development?
When creating Web services, there are two development styles: Contract Last and Contract First. When using a contract-last approach, you start with the Java code, and let the Web service contract (WSDL, see sidebar) be generated from that. When using contract-first, you start with the WSDL contract, and use Java to implement said contract.

Source: Spring WS Reference 2.0
For an in-depth look of Spring WS, I suggest my readers to visit the Spring WS Reference 2.0 and the Spring WS API 2.0.0.RC2

We begin by defining our requirements. We have a magazine business. Our business partner has clients that needs to subscribe with our magazine. To expose this feature, we decided to use a web service. Our contract is that the clients will send the following information:
subscription code
name
email
Our web service will send a reply if the subscription is successful or not. The reply will contain the following elements:
status code
description
Since all web services are ultimately XML message, we need to define the format of our messages. We will create an XSD file. If you're not familiar with XSD, please see the excellent XSD tutorial w3schools.com XML Schema Tutorial.

Here's our XSD document:

subscription.xsd

This XSD is comprised of simple and complex element types. Each simple element has been assigned with restriction. In this way we can filter data even before it comes to our service. It's also a good way to validate XML data. Spring WS will handle the validation based on these restrictions.

When the client sends a request, we receive an XML document. Using Java's object-oriented approach and XML approach is not really convenient when manipulating information. Therefore we will use marshalling techniques to map the XML document with a corresponding Java object.

First let's see the actual XML document that is sent to us by the client:

Take note that this XML format is not arbitrary! The client has to honor the format that we declared in the XSD document.

Let's map this document to a SubscriptionRequest class:

SubscriptionRequest

For every request sent by the client, we send a response. We declare a SubscriptionResponse object:

Our marshaller will automatically convert this class into an XML document. If you look at the XSD file, we have declared a subscriptionResponse element.


This has been declared so that the client who is reading our WSDL will see what kind of response he will receive. Hence, the Contract-First development.

When the client receives a response, this is what he actually gets:

Our class has been automatically converted to XML.

To convert Java objects to XML and vice-versa we use Castor as our marshaller/unmarshaller implementation. For more info about Castor, check the reference guide Castor XML Mapping. There are other marshallers available, such as JAXB and JiBX. Check the Spring WS Reference Guide Chapter 8. Marshalling XML using O/X Mapper for more info.

To use Castor we need to declare a mapping file:

castor-mapping.xml

We're done with our contract. We now start the actual development!

The programming model of Spring WS 2 is similar with the programming model of Spring 3 MVC. Keep that in mind. In Spring MVC, to declare a controller, we mark the name of the class with @Controller and @RequestMapping. For example:

In Spring WS, we have a corresponding controller as well. Actually, it's called an endpoint. To declare an endpoint, we mark it with @Endpoint. For example:

In Spring MVC, to expose a method for a particular request, we add the @RequestMapping annotation and the associated URI template value and the type of method. For example:

In Spring WS, to expose a method for a particular service request, we add the @PayloadRoot annotation and the associated localPart and namespace values. For example:

The method is also annotated with @ResponsePayload, indicating that the return value ( SubscriptionResponse) is used as the payload of the response message. The method takes a SubscriptionRequest as a parameter, annotated with @RequestPayload. This means that the payload of the message is passed on this method as a DOM element. If you have omitted these two annotations, you will encounter a "java.lang.IllegalStateException: No adapter for endpoint".

Let's now declare our SubscriptionEndpoint class:

SubscriptionEndpoint

This endpoint has one method named processSubscription. It takes a SubscriptionRequest and delegates the processing to a SubscriptionService. If the subscription is successful a SUCCESS response is sent. If it failed, a FAILURE response is sent.

Here's the SubscriptionService:

SubscriptionService

We're done with the Spring WS part. We now start the Spring MVC development.

What we're adding here are just basically a single controller and single JSP file to display our subscribers. Here's a screenshot of our subscribers list:

Here's the controller:

MainController

This controller declares a single mapping:
/main/subscribers
This mapping delegates the call to the SubscriptionService. This is the same service that's utilized by Spring WS earlier!

Here's the JSP file:

We're done will all our classes. What's left are the XML configurations. We start by declaring the web.xml file:

web.xml

All request are handled by Spring MVC's DispatcherServlet. In a stand-alone Spring WS, we use the MessageDispatcherServlet instead. But since we're now integrating both, we need a way to resolve our dispatchers hierarchy.
As an alternative to the MessageDispatcherServlet, you can wire up a MessageDispatcher in a standard, Spring-Web MVC DispatcherServlet. By default, the DispatcherServlet can only delegate to Controllers, but we can instruct it to delegate to a MessageDispatcher by adding a WebServiceMessageReceiverHandlerAdapter to the servlet's web application context:

Spring WS 2 Reference 5.3.2. Wiring up Spring-WS in a DispatcherServlet
I suggest to read the Spring WS 2 reference for a thorough description of this integration.

If you examine carefully the servlet element, we've declared an init-param. This is required to dynamically convert WSDLs regardless where you deploy it. There's no need to manually set the URL of your WSDL anymore, though you still can.

In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml

By convention, we must declare an applicationContext.xml as well.

applicationContext.xml

These beans activate Spring's annotation support for Spring 3 MVC. At the bottom portion we import an external configuration file spring-ws.xml. This contains all the Spring WS specific configuration. In a normal Spring project, it's typical to have multiple XML configs. To lessen the XML hell experience, it's advisable we group related configurations in their owned XML file.

Here's spring-ws.xml:

spring-ws.xml

This configuration uses the latest Spring WS 2.0.0 RC2 features (unlike if you're still using 1.5.9).

What's new with Spring WS 2.0.0 RC2?
The most important new feature in this release is the update of the Spring-WS XML namespace, which now contains <sws:annotation-driven/> and <sws:interceptors/> elements (similar to the Spring-MVC namespace), and <sws:static-wsdl/> and <sws:dynamic-wsdl/> for exporting your WSDLs.

Source: SpringSource Forum: Spring Web Services 2.0.0 RC2 released
It's worth mentioning in the spring-ws.xml, we're using a pluggable endpoint adapter
DefaultMethodEndpointAdapter
and a marshalling method processor
MarshallingPayloadMethodProcessor
If you visit some of the popular Spring WS tutorials, they still use the old GenericMarshallingMethodEndpointAdapter. However, this is already deprecated in favor of a pluggable adapter.
Class GenericMarshallingMethodEndpointAdapter

Deprecated. as of Spring Web Services 2.0, in favor of DefaultMethodEndpointAdapter and MarshallingPayloadMethodProcessor.

See Spring WS API 2.0.0 GenericMarshallingMethodEndpointAdapter
That concludes our Spring WS development. We've managed to setup a simple Spring 3 WS application using the latest Spring WS 2.0.0.RC2 build. We've utilized the latest annotation features. We've also leveraged Spring 3 MVC's programming model.

To test the application, you will need to deploy it in a server, like Tomcat. For the client, unless you know how to develop a Web Service client, I advise my readers to use Soap UI for testing. They have a free version at http://soapui.org/. It's also one of the recommended tools at the official Spring Web Services site at http://static.springsource.org/spring-ws/sites/2.0/resources.html.

Here's a sample screenshot using SOAP UI to test the application:

To access the service endpoint, use the following URL:
http://localhost:8080/spring-ws/krams/ws
To access the WSDL, use the following URL (you can use Firefox to check this out):
http://localhost:8080/spring-ws/krams/ws/subscription.wsdl
To access the subscribers page, use the following URL:
http://localhost:8080/spring-ws/krams/main/subscribers
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-ws-2-0-0-rc2-tutorial/

You can download the project as a Maven build. Look for the spring-ws.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 integration with other technologies, 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 WS 2 and Spring 3 MVC Integration Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share