MapStruct

MapStruct is a serious alternative for Dozer bean mapping project. It’s a code generator which simplifies the implementation of mappings between Java bean types based on a convention over configuration approach.

MapStruct solves some traditional mapping issues like a lack of performance, difficult mapping code debugging and late errors détection (usually in code execution).

This posts presents how to use MapStruct by dealing with bean mapping case.

Maven configuration

MapStruct is an annotation processor which is plugged into the Java compiler. That why we need to configure maven processor plugin to parse the mapping annotations and generate code.

    <dependencies>
      <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
      </dependency>
      <!-- other project dependencies -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.bsc.maven</groupId>
                <artifactId>maven-processor-plugin</artifactId>
                <version>2.2.4</version>
                <configuration>
                    <defaultOutputDirectory>
                        ${project.build.directory}/generated-sources
                    </defaultOutputDirectory>
                    <processors>
                        <processor>org.mapstruct.ap.MappingProcessor</processor>
                    </processors>
                </configuration>
                <executions>
                    <execution>
                        <id>process</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

Source classes

The source code bellow, presents the source class and its dependencies.

public class User {

    private String fullName;
    private Address address;
    private List<Authority> authorities;

    // Add getters and setters
}


public class Address {

    private String street;
    private String city;
    private String state;
    private String zipCode;

    @Override
    public String toString() {
        return street + ", " + city + ", " + state + ", " + zipCode;
    }
    
    // Add getters and setters
}

public class Authority {
    private String code;
    private String value;
    
    // Add getters and setters
}

Destination classes

The destination class has a String type address and a set of string for authorities values.

The mapper have to do three actions:

  1. Copy name field value.
  2. Convert Address object to String.
  3. Convert List to Set.

public class UserDto {

    private String name;
    private String address;
    private Set<String> authorities;

    // Add getters and setters
}

Mapping code

@Mapper
public abstract class UserMapping {
    public static UserMapping INSTANCE = Mappers.getMapper(UserMapping.class);

    @Mappings({
         @Mapping(source="fullName", target="name"),
         @Mapping(target="address", expression="java(user.getAddress().toString())")
    })
    public abstract UserDto userToDto (User user);

    @IterableMapping(elementTargetType = String.class)
    protected abstract Set<String> mapListToSet(List<Authority> value);

    protected String mapAuthorityToString(Authority authority) {
        return authority.getValue();
    }
}

Generated mapping code

Mapping code will be gerated in the generate-sources phase when executing Maven install goal.

If there is no mapping specification error, you can check mapping code under project-folder/target/generated-sources folder.

@Generated(value = "org.mapstruct.ap.MappingProcessor",  date = "today",
    comments = "version: 1.0.0.CR2, compiler: javac, 
    environment: Java 1.7.0 (Sun Microsystems Inc.)"
)
public class UserMappingImpl extends UserMapping {

    @Override
    public UserDto userToDto(User user) {
        if ( user == null ) {
            return null;
        }

        UserDto userDto = new UserDto();
        userDto.setName( user.getFullName() );
        userDto.setAuthorities( mapListToSet( user.getAuthorities() ) );
        userDto.setAddress( user.getAddress().toString());
        return userDto;
    }

    @Override
    protected Set<String> mapListToSet(List<Authority> value) {
        if ( value == null ) {
            return null;
        }
        Set<String> set_ = new HashSet<String>();
        for ( Authority authority : value ) {
            set_.add( mapAuthorityToString( authority ) );
        }
        return set_;
    }
}

Test beans mapping

public class MappingTest {
    @Test
    public void testMapping() {
        Address address = new Address( "street", "city", "state", "zipCode");
        User user = new User("name", address, Arrays.asList(new Authority("1", "admin"), new Authority("2", "user")));

        UserDto userDto = UserMapping.INSTANCE.userToDto(user);

        Assert.assertEquals("name", userDto.getName());
        Assert.assertEquals("street, city, state, zipCode", userDto.getAddress());
        Assert.assertTrue(userDto.getAuthorities().containsAll(Arrays.asList("admin", "user")));
    }

}

In this posts, we dealt with some MapStruct features like collections mapping and expressions. It has other mapping features that can fit your mapping needs like Decorators, Enum type mapping and customized mappings with Before/After mapping methods.

At the moment when I’m writing this article, Mapstruct is in RC2 version. I think soon we will have a release which is mature enough to be considered for production use.

Advertisements

Spring Integration

Today’s business applications rarely live in isolation. That’s why we have often in applications development to implement a communication module to make the new application exchanging data with the existent information system. To implement those data flow we can use many technologies (JMS, SOA, Apache commons IO …). Managing all those components in a project can be tricky and not easily maintainable.

   

Photo credit: Michelangelo

Spring Integration provides an extension of the Spring programming model to support the well-known Enterprise Integration Patterns. It enables lightweight messaging within Spring-based applications and supports integration with external systems via declarative adapters.

The first part of this article presents some basic background to start using Spring Integration. The second part deals with a project sample.

1- Spring Integration Basics

Spring Integration adds essentially three components to the core Spring Framework: messages, message channels, and endpoints.

1.2-Spring Integration components

In this part we will present some basic components used in this article sample.

Message: is a data structure that will have payload and the header. The payload can be a file, String, JMS message … The header is a key-value map that contains some properties that will be used by the framework or user values.

Channel: it represents the “pipe” of a pipes-and-filters architecture. Producers send Messages to a channel, and consumers receive Messages from a channel.

Inbound Channel: it does some mapping between the Message and whatever object or resource is received-from the other system (File, HTTP Request, JMS Message, etc).

Outbound Channel: it does the same thing like the inbound Channel but in the other side. It map message to send to other system.

Service Activator: it’s a generic endpoint for connecting a service instance to the messaging system. The input Message Channel must be configured, and if the service method to be invoked is capable of returning a value, an output Message Channel may also be provided.

Transformer: is used to create a Message-transforming endpoint. It requires a “ref”. The “ref” may either point to an Object that contains the @Transformer annotation on a single method or it may be combined with an explicit method name value provided via the “method” attribute.[2]

Splitter: is a component whose role is to partition a message in several parts, and send the resulting messages to be processed independently.

To get more details about those components and to discover others components you can read the Spring integration reference manual in this link : http://static.springsource.org/spring-integration/reference/htmlsingle/

1.2- Spring integration component specification

To specify components, you can use the basic xml language or annotations.

This source code presents the transformer declaration by sing the XML language.

<integration:transformer input-channel="channel1" output-channel="channel2">
	<bean class="com.mycompany.integration.FileTransformer" />
</integration:transformer>


The same thing could be done by using Spring integration annotation.
First add to your spring application context the declaration of the package where your annotated classes are defined.

	<integration:annotation-config/>
	<context:component-scan base-package="com.mycompany.integration"/>

Next you add the annotation to your transformer class.

@Component
public class FileTransformer {	
	
	@Transformer(inputChannel="channel1", outputChannel="channel2")
	public NewMessageFormat transform(OldMessageFormat omf) throws IOException{
		//Your transformation implementation here
		return newMessageFormat;
	}
}

I recommend the xml specification because it could be used by STS to display integration graph. This graphic representation is helpful for reading and verifying the integration flow.

1.3- Create Spring integration project

The simplest way to create a Spring Integration project is to create a basic Spring project and to add Spring Integration dependencies to the pom file.

<dependency>
	<groupId>org.springframework.integration</groupId>
	<artifactId>spring-integration-core</artifactId>
	<version>${spring.integration.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.integration</groupId>
	<artifactId>spring-integration-file</artifactId>
	<version>${spring.integration.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.integration</groupId>
	<artifactId>spring-integration-jdbc</artifactId>
	<version>${spring.integration.version}</version>
</dependency>

1.4- Spring Tools Suite (STS)

You can develop your spring integration application with your favorite IDE without any extra feature. But I think it is too much easier if it will be done with STS. You can download STS from this link http://www.springsource.com/developer/sts or to install the STS plugin for eclipse form this link http://marketplace.eclipse.org/content/springsource-tool-suite.

2- Spring integration sample

In this sample, we suggest to implement data integration between two systems. The first one produces data into flat file and the second system receives a data into a database.

You can import the project sample from google code SVN link: http://project4example4.googlecode.com/svn/trunk/

The application needs to detect the new file in a folder, log the name of the detected file, read text file and integrate its content into the database.

Bellow we present the source formatted flat text file content and the destination persistent classe.

id tax name adresse city state zip phone
5 2 name5 adresse5 Paris Paris 75001 0606060606
6 2 name6 adresse6 Paris Paris 75001 0606060606
7 2 name7 adresse7 Paris Paris 75001 0606060606
8 2 name8 adresse8 Paris Paris 75001 0606060606
9 2 name9 adresse9 Paris Paris 75001 0606060606
Source file format Persistent class

The picture bellow presents Spring integration graph used to implement the solution.

The file inbound channel inspect every 5 second the input folder. If a new file is present a message with a payload of type file will be created and sent to the service activator.
The service activator in this sample will just log the file name and deliver the message to the channel1.
The Transformer gets the Message from channel1, parse it, create a list of Customers and send the new message content to channel2.
The splitter gets the message, read the payload content and split the message to massages with a payload of type Customer.
The JDBC outbound channel gets the payload and uses payload attribute to execute the query.

The code source bellow presents the xml code of the spring integration graph. You can edit your Spring integration flow with both modes graphic and XML code mode. If you change XML code, the graph will be updated and if you use the graphic mode the changes done to the graph will affect the source code.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:integration="http://www.springframework.org/schema/integration"
  xmlns:file="http://www.springframework.org/schema/integration/file"
  xmlns:jdbc="http://www.springframework.org/schema/integration/jdbc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/file
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/jdbc
http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd">

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

	<file:inbound-channel-adapter id="filesIn"
		directory="${customer.file.input.path}">
		<integration:poller id="poller" fixed-delay="5000"/>
	</file:inbound-channel-adapter>

	<integration:service-activator	input-channel="filesIn" ref="handler" output-channel="channel1" />

	<bean id="handler" class="com.mycompany.integration.Handler" />
	
	<integration:channel id="channel1" />
	
	<integration:transformer input-channel="channel1" output-channel="channel2">
		<bean class="com.mycompany.integration.FileTransformer" />
	</integration:transformer>

	
	<integration:channel id="channel2" />

	<integration:splitter expression="payload" input-channel="channel2"  output-channel="dbChannel"/>	
	
	<integration:channel id="dbChannel" />

	<jdbc:outbound-channel-adapter
		query="insert into customer (customer_id, tax_id, name, adresse, city, state, zip, phone) values
		(:payload.customerId, :payload.taxId, :payload.name, :payload.adresse, :payload.city, :payload.state, :payload.city, :payload.phone)"
		channel="dbChannel" data-source="dataSource" />

</beans>

To test the application, you can run the jUnit test “testIntegrateCustomer”.

@Test
	public void testIntegrateCustomer() throws Exception {
		
		Collection<Customer> listCustomers = iCustomerDao.getAll();
		Assert.assertEquals(3, listCustomers.size());
		logger.info("customers number : {}", listCustomers.size());
		
		logger.info("wait .... ");
		Thread.sleep(2000);
		
		URL customerFileUrl = this.getClass().getResource("/input/customer.txt");
		File customerFile = new File(customerFileUrl.toURI());
		Assert.assertTrue(customerFile.exists());
		
		
		FileUtils.copyFileToDirectory(customerFile, new File(inputDirectoryPath));
		logger.info("test file {} copied to {}", customerFile.getName(), inputDirectoryPath);
		
		Thread.sleep(4000);
		
		
		listCustomers = iCustomerDao.getAll();
		logger.info("new customers number : {}", listCustomers.size());
		Assert.assertEquals(8, listCustomers.size());
		
	}


Spring Integration is a smart solution for application data integration. It provides support for the standard patterns typically used in enterprise integration. Spring Integration adds lightweight messaging and support for integrating with external systems and services using an adapter framework. Adapters enable a higher-level abstraction for communication with external systems and for Spring’s support for data and remote access as well as scheduling.

Reference

[1] http://www.eaipatterns.com/
[2] http://static.springsource.org/spring-integration/reference/htmlsingle/
[3] Dr. Mark Lui, Mario Gray, Andy H. Chan, and Josh Long, Pro. Spring Integration. Apress.

Web design with 960 grid system

Sometimes we lose a lot of time solving some web design problems like unstable components positions or page structure. Often web pages change with screen width, content and web browser.

Some CSS frameworks like BluePrint and 960 Grid System cut down development time. They give a web developer a solid foundation to build UI with an easy-to-use grid and other features.

   

Photo credit: HannyB

This article presents 960 Grid System and suggests to integrate it in a dynamic web project (JEE JSF web project).

How 960 grid system works?

960 grid System framework propose two ways to manage the web page area. The first one use the central part of the web page with a fixe width. The second way use fluid width to define the exploited area of the page.

960 grid System framework uses the css class name to manage DIV position and the inner component position into the web page.

A row is defined by the container which is a div used to specify how many total columns exist, either 12 or 16.

If a grid unit contains grid children, the child need to a class which will indicate a number of columns it will take (grid_X). If you want to insert empty space before or after a grid unit, use class prefix_P or suffix_S.

container_12

pref grid_10 prefix_2 suffix_1 suf


The picture above explains how to use 960 grid CSS to manage Div positions. The content of the grid will be in the green area.

After we have a look to basic use case of the 960 grid framework, we will try to integrate it in a web application to manage screen components position.

960 grid in JEE project

Usually, the first step in UI design we define the page template. The picture bellow presents a template that we suggest to use for a project sample.

template
header
menu
content
footer
960px

960 grid system gives us the possibility to choose the way to place the different part of the application user interface into a grid system. We made a choice to use fixed width of 960px with 12 grids.

To use 960 grid system in your template page you need to add 960.css to the CSS folder of the web project and reference it.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
	xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link href="#{request.contextPath}/css/default.css"  rel="stylesheet" type="text/css"/>
<link href="#{request.contextPath}/css/960.css"  rel="stylesheet" type="text/css"/>
<title>Sample Template</title>
</head>
<body >

<div id="wrap">
	<div id="header" class="container_12">
		<ui:include src="/pages/template/header.xhtml" />
	</div>
	<div id="main" class="container_12">
		<div id="menu" class="grid_2 " >
			<ui:include src="/pages/template/menu.xhtml" />
		</div>
		<div id="content" class="grid_6  prefix_2 suffix_2">
			<ui:insert name="body" />
		</div>
	</div>

</div>
<div id="footer" class="container_12" >
		<ui:include src="/pages/template/footer.xhtml" />
</div>

</body>
</html>

The picture bellow presents the application interface after we applied the 960 grid system.

Secure your web application with Spring Security

Spring Security is great framework to secure web application. It’s easy to configure and it doesn’t need to make special changes or deploy libraries to your Servlet or EJB container.

Spring security keeps your application objects free of security code, unless you specifically choose to interact with the security context.

   

Photo credit: V.Áron

This article explains how to secure a JEE application with Spring Security by a sample project. This project is implemented with JSF, Spring (version 3.0) and Hibernate.

The source code of the project is available on github here.

Basic configuration

In this part we will add dependencies and basic configuration to integrate Spring security to the web application.

  • Add Spring Security dependencies to the maven pom.xml file.
     <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.web</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.config</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.taglibs</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
    

– Update web.xml file.
Inside web.xml, insert the following block of code. It should be inserted right after the /context-param end-tag.

<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>

– Add applicationContext-security.xml file
This file contains the basic Spring Security config. There is no user access control for any path. Users are defined in the Spring application context file.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
 
 <http use-expressions="true">
        <intercept-url pattern="/**" filters="none" />
        <form-login />
        <logout />
    </http>

	<authentication-manager>
	    <authentication-provider>
	      <user-service>
	        <user name="user1" password="password1" authorities="ROLE_USER, ROLE_ADMIN" />
	        <user name="user2" password="password2" authorities="ROLE_USER" />
	      </user-service>
	    </authentication-provider>
  </authentication-manager>
</beans>

After the basic configuration is done, you should have your web application running and you should access all pages.

Security Configuration

1 – Authentication

Authentication is the process of determining whether someone or something is, in fact, who or what it is declared to be. [2]

Spring security supports LDAP, database, XML and Properties file to authenticate users. In this article, we use database authentication. The database schema is created by hibernate and it is populated by DbUnit framework.

We create two persistent classes to save users and their authorities.


– Create a login.xhtml page as shown in the code bellow

<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jstl/core" 
>
<head></head>
<body>

<c:if test="${param.state=='failure'}">
		<c:set var="username" value="#{sessionScope.SPRING_SECURITY_LAST_USERNAME}"/>
		<div class="ERROR">
			Your login attempt was not successful, try again.<br />
			Reason: #{sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
		</div>
</c:if>
	<form  action="#{request.contextPath}/j_spring_security_check" method="post">
		<h:panelGrid columns="2" title="Customer">
			<f:facet name="header"> 
				<h:outputText value="Login form" />
			</f:facet>
			<h:outputText value="User:" />
			<h:inputText id="j_username" value="#{username}"  />
			<h:outputText value="Password:" />
			<h:inputSecret id="j_password" />
			<f:facet name="footer"> 
				<h:commandButton  value="Login" type="submit"  />
			</f:facet>
		</h:panelGrid>
	</form>
</body>
</html>

To add JDBC Spring security some changes nead to be done to the applicationContext-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<http use-expressions="true" access-denied-page="/pages/static/accessDenied.jsf">
		<intercept-url pattern="/login.jsf" filters="none"/>
		<intercept-url pattern="/pages/**" access="isAuthenticated()" />
		<form-login login-page="/login.jsf" default-target-url="/pages/static/welcome.jsf" authentication-failure-url="/login.jsf?state=failure"/>
		<logout logout-success-url="/login.jsf?state=logout"  />
	</http>

	<authentication-manager alias="authenticationManager">
		<authentication-provider>
			<password-encoder hash="md5" />
			<jdbc-user-service data-source-ref="dataSource"
				users-by-username-query="SELECT U.login AS username, U.password as password, U.enabled as enabled FROM user U where U.login=?"
				authorities-by-username-query="SELECT U.login as username, A.authority_name as authority FROM user U, authority A WHERE U.user_id=A.user_id and U.login=?"
				role-prefix="ROLE_" />
		</authentication-provider>
	</authentication-manager>

</beans:beans>

To maximize password security we made a choice to use md5 password encoding.

2 – Authorization

Authorization is the function of specifying access rights to resources, which is related to information security and computer security in general and to access control in particular. More formally, “to authorize” is to define access policy. [1]

With spring security we can manage pages, screen components and methods execution rights policies.

– Path access control

Then implement access rules for URLs by adding <intercept-url> children directly under the <http> element.

	
	<http use-expressions="true" access-denied-page="/pages/static/accessDenied.jsf">
		<intercept-url pattern="/login.jsf" filters="none" />
		<intercept-url pattern="/pages/static/**" access="isAuthenticated()" />
		<intercept-url pattern="/pages/customer/**" access="hasAnyRole('ROLE_ADMIN','ROLE_CUSTOMER')" />
		<intercept-url pattern="/pages/order/**" access="hasAnyRole('ROLE_ADMIN','ROLE_ORDER')" />
		<intercept-url pattern="/pages/admin/**" access="hasRole('ROLE_ADMIN')" />
		<form-login login-page="/login.jsf" default-target-url="/pages/static/welcome.jsf"
			authentication-failure-url="/login.jsf?state=failure" />
		<logout logout-success-url="/login.jsf?state=logout" />
	</http>

-Taglib Spring Security

Sometimes, it is better to hide some unauthorized links rather than letting them available and showing the access denied page when they are requested.

Spring Security has its own taglib which provides basic support for accessing security information and applying security constraints in JSPs. [3]

To use Spring security taglib in JSP pages, you need to add the taglib declaration to your project as shown in the source code bellow:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<sec:authorize ifAllGranted="ROLE_USER">
  Utilisateur : <sec:authentication property="principal.username"/>
</sec:authorize>

To use Spring security Taglib in a facelets pages is a little bit more complicated.

  • We need to add XML namespaces declaration for Spring security taglib into facelet page as highlighted in this source code.
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:rich="http://richfaces.org/rich"
    xmlns:sec="http://www.springframework.org/security/tags">
  • Create springsecurity.taglib.xml file into the WEB-INF file and a param declaration to reference this file in the web.xml file.
	<context-param>
		<param-name>facelets.LIBRARIES</param-name>
		<param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
	</context-param>

This is the source code of springsecurity.taglib.xml I used in this prototype project. But this file has to be changed if you are using JSF 2.0. For more detail, read the spring documentation in this link.

<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
	<namespace>http://www.springframework.org/security/tags</namespace>
	<tag>
		<tag-name>authorize</tag-name>
		<handler-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagHandler</handler-class>
	</tag>
	<function>
		<function-name>areAllGranted</function-name>
		<function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areAllGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>areAnyGranted</function-name>
		<function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areAnyGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>areNotGranted</function-name>
		<function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areNotGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>isAllowed</function-name>
		<function-class>org.springframework.faces.security.Jsf12FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean isAllowed(java.lang.String, java.lang.String)</function-signature>
	</function>
</facelet-taglib>

  • Add this dependency to the pom.xml file
		<dependency>
			<groupId>org.springframework.webflow</groupId>
			<artifactId>spring-faces</artifactId>
			<version>2.2.1.RELEASE</version>
		</dependency>

Usually, the admin menu panel is visible only for users having the admin role. To implement this behavior, the panel source code is nested into the spring security authorize tag.

<sec:authorize access="hasAnyRole('ROLE_ADMIN')" >
	<rich:panelMenuGroup label="Admin">
		<rich:panelMenuItem >
				 <h:outputLink value="../admin/admin.jsf" >Users</h:outputLink>
		</rich:panelMenuItem> 
	</rich:panelMenuGroup>
</sec:authorize>

-Method authorization

Spring security allows method execution authorization management. It provides annotations which can contain expression attributes which are applied before and after the method invocation. To enable support for them, the attribute global-method-security has to be assigned the value enabled:

<global-method-security pre-post-annotations="enabled"/>

The source code above is added to application-context-security.xml file.

In this example we made a choice to allow only users having ROLE_CUSTOMER role to add customers.

import com.mycompany.dao.ICustomerDao;
import com.mycompany.entity.Customer;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.security.access.prepost.PreAuthorize;

public class CustomerDao extends HibernateDaoSupport implements ICustomerDao{

    @PreAuthorize("hasRole('ROLE_CUSTOMER')")
    public void save(Customer customer) {
        getHibernateTemplate().save(customer);
    }

// Other methods ....

}

To test Spring method execution authorization, we created a user “orderManager” which doesn’t have the role ROLE_CUSTOMER. When this user tries to save a customer, the application display the caught error message “Access is denied”.

Application example (Access is denied message)


Spring Security is a powerful framework to secure JEE applications. It has many other features to manage authentication and access-control services for java/JEE applications. I had used Spring Security since the project had a name Acegi. I think that the framewok has made a lot of progress and I recommend it for Securing web applications.

Reference:
[1] en.wikipedia.org
[2] searchsecurity.techtarget.com
[3] www.springsource.org