RSS

Spring Security with JSF

07 Mar

Listing 1 – pom.xml
This file has dependences for the whole web project. It sits under project directory


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.movirtu.security</groupId>
    <artifactId>spring-security</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <name>spring-security</name>
    <url>http://maven.apache.org</url>

    <properties>
        <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <jsf-api.version>2.1.6</jsf-api.version>
        <primefaces.version>3.0.1</primefaces.version>
        <primefaces-themes.version>1.0.2</primefaces-themes.version>

        <spring.core.version>3.1.0.RELEASE</spring.core.version>
        <spring.security.core.version>3.1.0.RELEASE</spring.security.core.version>
        <spring.data.jpa.version>1.0.1.RELEASE</spring.data.jpa.version>
        <mysql.connector.version>5.1.16</mysql.connector.version>
        <hibernate.entitymanager.version>3.6.3.Final</hibernate.entitymanager.version>
        <hibernate.jpa-api.version>2.0-cr-1</hibernate.jpa-api.version>
        <c3p0.version>0.9.1.2</c3p0.version>
        <aspectj.version>1.6.12.RELEASE</aspectj.version>

        <querydsl.version>2.2.5</querydsl.version>
        <slf4j.version>1.6.1</slf4j.version>
        <log4j.version>1.2.14</log4j.version>

        <javax.servlet-api.version>2.5</javax.servlet-api.version>
        <javax.jstl-taglibs.version>1.1.2</javax.jstl-taglibs.version>

  	<!-- Testing -->
        <mockito.version>1.8.5</mockito.version>
        <junit.version>4.8.2</junit.version>

  	<!-- Plugins -->
        <maven.copy.plugin.version>0.2.3</maven.copy.plugin.version>
        <maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
        <maven.apt.plugin.version>1.0</maven.apt.plugin.version>
    </properties>

    <dependencies>

        <!--JSF API-->
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>2.1.6</version>
        </dependency>

        <!--Prime Faces-->
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>3.0</version>
<!--            <version>${primefaces.version}</version>-->
        </dependency>
        <dependency><!-- optional theme (see also web.xml to enable it) -->
            <groupId>org.primefaces.themes</groupId>
            <artifactId>redmond</artifactId>
            <version>${primefaces-themes.version}</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces.themes</groupId>
            <artifactId>bluesky</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.primefaces.themes</groupId>
            <artifactId>blitzer</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>snaq.db.dbpool</groupId>
            <artifactId>DBPool</artifactId>
            <version>5.0</version>
        </dependency>

  <!-- Spring Core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.core.version}</version>
        </dependency>

	<!-- A seamless aspect-oriented extension to the Java programming language -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>

	<!-- Cglib is a powerful, high performance and quality Code Generation Library,
	It is used to extend JAVA classes and implements interfaces at runtime.  -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>2.2</version>
        </dependency>

	<!-- The JavaServer Pages Standard Tag Library (JSTL) encapsulates, as simple tags, core
	functionality common to many JSP applications. -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${javax.jstl-taglibs.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>${javax.jstl-taglibs.version}</version>
        </dependency>

	<!-- Logger -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

	<!-- The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction
	for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end
	user to plug in the desired logging framework at deployment time. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

	<!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.security.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>${spring.security.core.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring.security.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring.security.core.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-crypto</artifactId>
            <version>${spring.security.core.version}</version>
        </dependency>

    <!-- Spring Data JPA -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring.data.jpa.version}</version>
        </dependency>

	<!-- Database pooling -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0.version}</version>
        </dependency>

	<!--  MySQL Connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>

	<!-- Hibernate and JPA -->
        <dependency>
            <groupId>org.hibernate.java-persistence</groupId>
            <artifactId>jpa-api</artifactId>
            <version>${hibernate.jpa-api.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.entitymanager.version}</version>
        </dependency>

	<!-- QueryDSL -->
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-core</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mysema.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
        </dependency>

	<!-- Javax Servlet. This needs to be included for runtime only! -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${javax.servlet-api.version}</version>
            <scope>provided</scope>
        </dependency>

    <!-- Testing dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.core.version}</version>
            <scope>test</scope>
        </dependency>

        <!--Spring Security Taglib-->
        <dependency>
            <groupId>org.springframework.webflow</groupId>
            <artifactId>org.springframework.faces</artifactId>
            <version>2.3.0.RELEASE</version>

        </dependency>

    </dependencies>

    <build>
        <finalName>spring-security</finalName>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>maven-apt-plugin</artifactId>
                <version>${maven.apt.plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.goldin.plugins</groupId>
                <artifactId>maven-copy-plugin</artifactId>
                <version>${maven.copy.plugin.version}</version>
                <executions>
                    <execution>
                        <id>create-archive</id>
					<!-- Select compile phase so that resources are copied first before being packaged! -->
                        <phase>compile</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <resources>
                                <resource>
                                    <targetPath>${project.build.outputDirectory}/META-INF</targetPath>
                                    <directory>${project.basedir}/src/main/java/META-INF</directory>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

    </build>

    <repositories>

  	<!-- For main Spring releases -->
        <repository>
            <id>org.springframework.maven.release</id>
            <name>Spring Maven Release Repository</name>
            <url>http://maven.springframework.org/release</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>

	<!-- For testing against latest Spring snapshots -->
        <repository>
            <id>org.springframework.maven.snapshot</id>
            <name>Spring Maven Snapshot Repository</name>
            <url>http://maven.springframework.org/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>

	<!-- For developing against latest Spring milestones -->
        <repository>
            <id>org.springframework.maven.milestone</id>
            <name>Spring Maven Milestone Repository</name>
            <url>http://maven.springframework.org/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>

        <repository>
            <id>jboss</id>
            <name>JBoss repository</name>
            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
        </repository>

        <repository>
            <id>prime-repo</id>
            <name>Prime Technology Maven Repository</name>
            <url>http://repository.primefaces.org</url>
            <layout>default</layout>
        </repository>

        <repository>
            <id>org.springframework.security.taglibs.facelets</id>
            <url>http://spring-security-facelets-taglib.googlecode.com/svn/repo/</url>
        </repository>

        <repository>
            <id>springsource-releases</id>
            <name>SpringSource Release Proxy</name>
            <url>https://oss.sonatype.org/content/repositories/springsource-releases</url>
        </repository>
        <!--Spring Security Taglib Repositories-->
        <repository>
            <id>com.springsource.repository.bundles.release</id>
            <name>SpringSource Enterprise Bundle Repository - SpringSource Releases</name>
            <url>http://repository.springsource.com/maven/bundles/release</url>
        </repository>

        <repository>
            <id>com.springsource.repository.bundles.external</id>
            <name>SpringSource Enterprise Bundle Repository - External Releases</name>
            <url>http://repository.springsource.com/maven/bundles/external</url>
        </repository>

    </repositories>

    <pluginRepositories>

	<!-- Repo for maven-copy-plugin -->
        <pluginRepository>
            <id>evgeny-goldin.org</id>
            <name>Evgeny Goldin Repository</name>
            <url>http://evgeny-goldin.org/artifactory/repo/</url>
        </pluginRepository>

    </pluginRepositories>
</project>

Listing 2 – applicationContext.xml
This file sits under WEB-INF on web application.

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.1.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
          http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:property-placeholder properties-ref="deployProperties" />

	<!-- Activates various annotations to be detected in bean classes -->
    <context:annotation-config />

	<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.
	 For example @Controller and @Service. Make sure to set the correct base-package -->
    <context:component-scan base-package="com.mycompany.security" />

	<!-- Configures the annotation-driven Spring MVC Controller programming model.
	Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
    <mvc:annotation-driven />

    <mvc:resources mapping="/resources/**" location="/resources/" />

 	<!-- Imports logging configuration -->
    <import resource="trace.xml"/>

	<!-- Imports datasource configuration -->
    <import resource="data-jpa.xml"/>

    <bean id="deployProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
        p:location="/WEB-INF/database.properties" />
</beans>

Listing 3 – data-jpa.xml
This file is used for JPAprovided by spring which facilitates traditional JPA, it sits under WEB-INF

<?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:p="http://www.springframework.org/schema/p"
       	xmlns:tx="http://www.springframework.org/schema/tx"
       	xmlns:context="http://www.springframework.org/schema/context"
       	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       	xmlns:util="http://www.springframework.org/schema/util"
       	xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-3.1.xsd


http://www.springframework.org/schema/tx


http://www.springframework.org/schema/tx/spring-tx-3.1.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-3.1.xsd


http://www.springframework.org/schema/jdbc


http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd


http://www.springframework.org/schema/data/jpa


http://www.springframework.org/schema/data/jpa/spring-jpa.xsd


http://www.springframework.org/schema/util


http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <context:property-placeholder properties-ref="deployProperties" />

    <tx:annotation-driven transaction-manager="transactionManager" />

	<!-- Activate Spring Data JPA repository support -->
    <jpa:repositories base-package="com.mycompany.security.repository" />

	<!-- Declare a datasource that has pooling capabilities-->
    <bean id="jpaDataSource" class="snaq.db.DBPoolDataSource"
		p:driverClassName="${app.jdbc.driverClassName}"
		p:url="${app.jdbc.url}"
		p:user="${app.jdbc.username}"
		p:password="${app.jdbc.password}"
		p:maxPool="10"
		p:maxSize="30"
		p:minPool="5" />

 	<!-- Declare a JPA entityManagerFactory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
		p:persistenceXmlLocation="classpath*:META-INF/persistence.xml"
		p:persistenceUnitName="hibernatePersistenceUnit"
		p:dataSource-ref="jpaDataSource"
		p:jpaVendorAdapter-ref="hibernateVendor"/>

	<!-- Specify our ORM vendor -->
    <bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
	            p:showSql="false"/>

	<!-- Declare a transaction manager-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
		p:entityManagerFactory-ref="entityManagerFactory"/>

</beans>

Listing 4 – spring-security.xml
This file holds security settings, it sits under WEB-INF.

<?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"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd


http://www.springframework.org/schema/security


http://www.springframework.org/schema/security/spring-security-3.1.xsd


http://www.springframework.org/schema/util


http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <http pattern="/resources" security="none" />
    <http pattern="/login.htm*" security="none"/>
    <http>

        <intercept-url pattern='/admin/**' access='ROLE_ADMIN' />
        <intercept-url pattern='/user/**' access='ROLE_USER' />
        <form-login login-page='/login.html' default-target-url='/home.html'
            always-use-default-target='true' />
        <access-denied-handler error-page="/denied.html"/>
        <logout invalidate-session="true"
			logout-success-url="/logout.html"
			logout-url="/logout.html"/>
    </http>

    <authentication-manager  alias="authenticationManager">
        <authentication-provider user-service-ref="userDetailsService">
            <password-encoder hash="plaintext"/>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

Listing 5 – trace.xml
This file is just for logging purposes and nothing much. It intercepts methods and then log when the method is called.

<?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:p="http://www.springframework.org/schema/p"
       	xmlns:aop="http://www.springframework.org/schema/aop"
       	xsi:schemaLocation="

http://www.springframework.org/schema/beans


http://www.springframework.org/schema/beans/spring-beans-3.1.xsd


http://www.springframework.org/schema/aop


http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

	<!-- For parsing classes with @Aspect annotation -->
	<aop:aspectj-autoproxy/>

	<bean id="customizableTraceInterceptor" class="com.mycompany.aop.TraceInterceptor"
		p:enterMessage="Entering $[targetClassShortName].$[methodName]($[arguments])"
		p:exitMessage="Leaving $[targetClassShortName].$[methodName](): $[returnValue]"/>

	<aop:config>
	  <aop:advisor advice-ref="customizableTraceInterceptor" pointcut="execution(public * com.mycompany.service..*(..))"/>
	  <aop:advisor advice-ref="customizableTraceInterceptor" pointcut="execution(public * com.mycompany.controller..*(..))"/>
	</aop:config>

</beans>

Listing 6 – web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name>spring-security</display-name>

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

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
		/WEB-INF/spring-security.xml
		/WEB-INF/applicationContext.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Change to "Production" when you are ready to deploy -->
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Production</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/spring-security-taglib.xml</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <!--Blusky theme for PrimeFaces -->
    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>bluesky</param-value>
    </context-param>

    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Listing 7 – database.properties

app.jdbc.driverClassName=com.mysql.jdbc.Driver
app.jdbc.url=jdbc\:mysql\://localhost/spring_security
app.jdbc.username=usr
app.jdbc.password=pwd

Listing 8 – TraceInterceptor.java
To intercept and log methods being called.

package com.mycompany.aop;

import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.log4j.Logger;
import org.springframework.aop.interceptor.CustomizableTraceInterceptor;

/**
 * Extends {@link CustomizableTraceInterceptor} to provide custom logging levels
 */
public class TraceInterceptor extends CustomizableTraceInterceptor {

	private static final long serialVersionUID = 287162721460370957L;
	protected static Logger logger4J = Logger.getLogger("aop");

	@Override
	protected void writeToLog(Log logger, String message, Throwable ex) {
		if (ex != null) {
			logger4J.debug(message, ex);
		} else {
			logger4J.debug(message);
		}
	}

	@Override
	protected boolean isInterceptorEnabled(MethodInvocation invocation, Log logger) {
		return true;
	}
}

Listing 9 – /admin/admin.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Hello from Admin Page
    </h:body>
</html>

Listing 10 – /user/user.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Hello from User page
    </h:body>
</html>

Listing 11 – /denied.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Denied Access
    </h:body>
</html>

Listing 12 – /home.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:sec="http://www.springframework.org/security/tags">

    <h:body>
        <h1>Welcome to MXshare Web Security</h1>
        <f:view>
            <h:form>
                <table border="0" width="70%" cellspacing="10" cellpadding="5">
                    <tbody>
                        <tr>
                            <td>
                                <a href="/user/user.html">
                                    <h:outputText value="User" rendered="#{sec:areAnyGranted('ROLE_USER')}"/>
                                </a>
                            </td>
                            <td>
                                <a href="/user/user.html">
                                    <h:outputText value="Admin1" rendered="#{sec:areAnyGranted('ROLE_ADMIN')}"/>
                                </a>
                            </td>
                            <td>
                                <a href="/user/user.html">
                                    <h:outputText value="Admin2" rendered="#{sec:isAllowed('/admin')}"/>
                                </a>
                            </td>
                            <td>Everyone one allowed</td>
                        </tr>
                    </tbody>
                </table>
            </h:form>
        </f:view>
    </h:body>
</html>

Listing 13 – /index.jsp

<jsp:forward page="login.html"></jsp:forward>

Listing 14 – /login.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>MXShare - Login</title>
        <h:outputStylesheet library="css" name="login.css"  />
    </h:head>
    <h:body>
        <center style="width: 40%;">
            <form action="j_spring_security_check" method="POST">
        <label for="username">User Name:</label>
        <input id="username" name="j_username" type="text"/>
        <label for="password">Password:</label>
        <input id="password" name="j_password" type="password"/>
        <input type="submit" value="Log In"/>
      </form>
        </center>
    </h:body>
</html>

Listing 15 – Role.java

package com.mycompany.domain;

import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

/**
 *
 * @author mlungisi
 */
@Entity(name = "role")
public class Role {

    @Id
    private Long id;
    @ManyToMany(mappedBy="roles")
    private List<User> users;
    private String name;

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return the user
     */
    public List<User> getUsers() {
        return users;
    }

    /**
     * @param user the user to set
     */
    public void setUsers(List<User> users) {
        this.users = users;
    }

    /**
     * @return the role
     */
    public String getName() {
        return name;
    }

    /**
     * @param role the role to set
     */
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Role other = (Role) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }
//Note that using users on toString() causes LazyLoadingException
    @Override
    public String toString() {
        return "Role{" + "id=" + id  + ", name=" + name + '}';
    }
}

Listing 16 – User.java

package com.mycompany.domain;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.UniqueConstraint;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 *
 * @author mlungisi
 */
@Entity(name = "user")
public class User implements Serializable, UserDetails{
    private static final long serialVersionUID = 1L;
    @Id
    private String username;
    private String firstName;
    private String lastName;
    private String password;
    private boolean active;
    @Column(name="account_non_expired")
    private boolean accountNonExpired;
    private boolean enabled;
    @Column(name="credentials_non_expired")
    private boolean credentialsNonExpired;
    @Column(name="account_non_locked")
    private boolean accountNonLocked;
    @ManyToMany(fetch= FetchType.EAGER)
    @JoinTable(name="user_role",
            joinColumns={@JoinColumn(name="username", referencedColumnName="username")},
            inverseJoinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
            uniqueConstraints=@UniqueConstraint(columnNames={"username", "role_id"})
            )
    private List<Role> roles;

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        return null;
    }

    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }

    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }

    /**
     * @param lastName the lastName to set
     */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /**
     * @return the username
     */
    @Override
    public String getUsername() {
        return username;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the password
     */
    @Override
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the active
     */
    public boolean isActive() {
        return active;
    }

    /**
     * @return the accountNonExpired
     */
    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    /**
     * @param accountNonExpired the accountNonExpired to set
     */
    public void setAccountNonExpired(boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }

    /**
     * @return the enabled
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * @return the credentialsNonExpired
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    /**
     * @param credentialsNonExpired the credentialsNonExpired to set
     */
    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }

    /**
     * @return the accountNonLocked
     */
    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    /**
     * @param accountNonLocked the accountNonLocked to set
     */
    public void setAccountNonLocked(boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }

    /**
     * @param active the active to set
     */
    public void setActive(boolean active) {
        this.active = active;
    }

    /**
     * @return the role
     */
    public List<Role> getRoles() {
        return roles;
    }

    /**
     * @param role the role to set
     */
    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final User other = (User) obj;
        if (this.username != other.username && (this.username == null || !this.username.equals(other.username))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 89 * hash + (this.username != null ? this.username.hashCode() : 0);
        return hash;
    }
//Note that using roles on toString() causes LazyLoadingException
    @Override
    public String toString() {
        return "User{" + "firstName=" + firstName + ", lastName=" + lastName + ", username=" + username + ", password=" + password + ", active=" + active + ", accountNonExpired=" + accountNonExpired + ", enabled=" + enabled + ", credentialsNonExpired=" + credentialsNonExpired + ", accountNonLocked=" + accountNonLocked+ '}';
    }
}

Listing 17 – UserRepository.java

package com.mycompany.repository;

import com.mycompany.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

	User findByUsername(String username);
}

Listing 18 – RoleRepository.java

package com.mycompany.repository;

import com.mycompany.domain.Role;
import org.springframework.data.jpa.repository.JpaRepository;

public interface RoleRepository extends JpaRepository<Role, Long>{
    List<Role> findByUsersUsername(String username);
}

Listing 19 – UserDetailsServiceImpl.java

package com.mycompany.service;

import com.mycompany.security.domain.Role;
import com.mycompany.security.repository.RoleRepository;
import com.mycompany.security.repository.UserRepository;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 *
 * @author mlungisi
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    private static Logger logger = Logger.getLogger(UserDetailsServiceImpl.class);

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    /**
     * Returns a populated {@link UserDetails} object.
     * The username is first retrieved from the database and then mapped to
     * a {@link UserDetails} object.
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        try {
            logger.debug("Entering loadUserByUsername...");
            System.out.println("Entering loadUserByUsername...");
            logger.debug("Finding user by username: " + username);
            System.out.println("Finding user by username: " + username);
            com.mycompany.security.domain.User domainUser = userRepository.findByUsername(username);
            logger.debug("Found user: " + domainUser);
            System.out.println("Found user: " + domainUser);
            return new User(
                    domainUser.getUsername(),
                    domainUser.getPassword().toLowerCase(),
                    domainUser.isEnabled(),
                    domainUser.isAccountNonExpired(),
                    domainUser.isCredentialsNonExpired(),
                    domainUser.isAccountNonLocked(),
                    getAuthorities(domainUser));

        } catch (Exception e) {
            System.out.println(e);
            logger.debug(e.getMessage(), e);
            throw new RuntimeException("Username not found", e);
        }
    }

    private Collection<GrantedAuthority> getAuthorities(com.mycompany.security.domain.User domainUser) {
        logger.debug("Entering getAuthorities...");
        System.out.println("Entering getAuthorities...");
        logger.debug("Finding roles by user: " + domainUser);
        System.out.println("Finding roles by user: " + domainUser);
        List<GrantedAuthority> result = new ArrayList<GrantedAuthority>();
        List<Role> roles = roleRepository.findByUsersUsername(domainUser.getUsername());
        System.out.println("getAuthorities: roles = " + roles);
        for(Role role : roles) {
            //result.add(new GrantedAuthorityImpl(role.getName()));
            result.add(new SimpleGrantedAuthority(role.getName()));
        }
        return result;
    }
}

Listing 20 – AuthenticationService.java

package com.mycompany.security.service.impl;

import com.mycompany.security.domain.Role;
import com.mycompany.security.domain.User;
import com.mycompany.security.repository.RoleRepository;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

/**
 *
 * @author mlungisi
 */
@Service
public class AuthenticationService {
    private static Logger logger = Logger.getLogger(AuthenticationService.class);
    @Autowired
    @Qualifier("authenticationManager")
    private AuthenticationManager authenticationManager;
    @Autowired
    private RoleRepository roleRepository;

    public boolean login(String username, String password) {
        try{
            logger.debug("Entering AuthenticationService.login...(" + username + ", " + password + ")");
            System.out.println("Entering AuthenticationService.login...(" + username + ", " + password + ")");
            logger.debug("AuthenticationService - username: " + username + " and password: " + password);
            System.out.println("AuthenticationService - username: " + username + " and password: " + password);
            logger.debug("Finding token...");

            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password, getAuthorities(username));
            logger.debug("Founding token authentication...");
            Authentication authentication = authenticationManager.authenticate(token);
            logger.debug("Finding authentication: " + authentication);
            System.out.println("AuthenticationService - Finding authentication: " + authentication);
            if(authentication.isAuthenticated()) {
                SecurityContextHolder.getContext().setAuthentication(authentication);
                return true;
            }
        } catch(AuthenticationException e) {
            System.out.println(e);
            logger.debug(e.getMessage(), e);
            return false;
        }
        return false;
    }

    private Collection<GrantedAuthority> getAuthorities(String username) {
        logger.debug("Entering getAuthorities...");
        System.out.println("Entering getAuthorities...");
        logger.debug("Finding roles by user: " + username);
        System.out.println("Finding roles by user: " + username);
        List<GrantedAuthority> result = new ArrayList<GrantedAuthority>();
        List<Role> roles = roleRepository.findByUsersUsername(username);
        System.out.println("getAuthorities: roles = " + roles);
        for(Role role : roles) {
            //result.add(new GrantedAuthorityImpl(role.getName()));
            result.add(new SimpleGrantedAuthority(role.getName()));
        }
        return result;
    }

    public void logout(){
        logger.debug("Logging out...");
        SecurityContextHolder.getContext().setAuthentication(null);
        invalidateSession();
        logger.debug("logged out");
    }

    public User getLoggedInUser() {
        return (User)SecurityContextHolder.getContext().getAuthentication();
    }

    private void invalidateSession() {
        FacesContext fc = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) fc.getExternalContext().getSession(false);
        session.invalidate();
    }
}

Listing 21 – JSFUtils.java


package com.mycompany.security.utils;

import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author mlungisi
 */
public class JSFUtils {
    /**
   * Returns the current HTTP session.
   */
  public static HttpSession getHttpSession() {
    FacesContext facescontext = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession) facescontext.getExternalContext().getSession(true);
    return session;
  }

  /**
   * Returns the current servlet response object instance.
   */
  public static HttpServletResponse getHttpServletResponse() {
    FacesContext facescontext = FacesContext.getCurrentInstance();
    HttpServletResponse response=(HttpServletResponse)facescontext.getExternalContext().getResponse();
    return response;
  }

  /**
   * Returns the current servlet request object instance.
   */
  public static HttpServletRequest getHttpServletRequest() {
    FacesContext facescontext = FacesContext.getCurrentInstance();
    HttpServletRequest request=(HttpServletRequest)facescontext.getExternalContext().getRequest();
    return request;
  }

  /**
   * Returns the servlet context.
   */
  public static ServletContext getServletContext() {
    ServletContext context = getHttpSession().getServletContext();
    return context;
  }

  /**
   * Creates or returns the backing bean.
   *
   * @param name The name of the bean.
   * @return The backing bean.
   */
  public static Object getBackingBean(String name) {
    Object bean = getHttpSession().getAttribute(name);
    if (bean == null) {
      FacesContext facescontext = FacesContext.getCurrentInstance();
      bean = facescontext.getApplication().createValueBinding("#{"+name+"}").getValue(facescontext); //$NON-NLS-1$ //$NON-NLS-2$
    }
    return bean;
  }
  /**
   * Adds a SEVERE message.
   *
   * @param message The message.
   */
  public static void addErrorMessage(String message) {
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message);
    FacesContext context = FacesContext.getCurrentInstance();
      context.addMessage(null, facesMsg);
  }
  /**
   * Adds an INFO message.
   *
   * @param message The message.
   */
  public static void addInfoMessage(String message) {
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, message, message);
    FacesContext context = FacesContext.getCurrentInstance();
      context.addMessage(null, facesMsg);
  }
  /**
   * Adds a WARNING message.
   *
   * @param message The message.
   */
  public static void addWarningMessage(String message) {
    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN, message, message);
    FacesContext context = FacesContext.getCurrentInstance();
      context.addMessage(null, facesMsg);
  }

  /**
   * Removes all current messages held by the JSF framework.
   */
  @SuppressWarnings("unchecked") //$NON-NLS-1$
  public static void resetMessages() {
    FacesContext context = FacesContext.getCurrentInstance();
      Iterator iter = context.getMessages();
      while (iter.hasNext()) {
        iter.next();
        iter.remove();
    }
  }

  public static String redirectPage(String pageWithExtention) {
      FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null, pageWithExtention);
      return FacesContext.getCurrentInstance().getApplication().getNavigationHandler().toString();
  }

  public static String redirectPage(String pageWithExtention, String params) {
      FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(FacesContext.getCurrentInstance(), null, pageWithExtention + "?" + params);
      return FacesContext.getCurrentInstance().getApplication().getNavigationHandler().toString();
  }
}

Listing 22 – UserBean.java

package com.mycompany.security.bean;

import com.mycompany.security.repository.RoleRepository;
import com.mycompany.security.repository.UserRepository;
import com.mycompany.security.service.impl.AuthenticationService;
import com.mycompany.security.utils.JSFUtils;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import org.apache.log4j.Logger;

/**
 *
 * @author mlungisi
 */
@ManagedBean
@SessionScoped
public class UserBean {

    private static final Logger logger = Logger.getLogger(UserBean.class);

    private String username;
    private String pin;
    private String name;
    private String surname;

    @ManagedProperty(name="userRepository", value="#{userRepository}")
    private UserRepository userRepository;
    @ManagedProperty(value="#{roleRepository}")
    private RoleRepository roleRepository;
    @ManagedProperty(value="#{authenticationService}")
    private AuthenticationService authenticationService;

    /**
     * @return the username
     */
    public String getUsername() {
        return username;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the pin
     */
    public String getPin() {
        return pin;
    }

    /**
     * @param pin the pin to set
     */
    public void setPin(String pin) {
        this.pin = pin;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the surname
     */
    public String getSurname() {
        return surname;
    }

    /**
     * @param surname the surname to set
     */
    public void setSurname(String surname) {
        this.surname = surname;
    }

    /**
     * @return the userRepository
     */
    public UserRepository getUserRepository() {
        return userRepository;
    }

    /**
     * @param userRepository the userRepository to set
     */
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * @return the roleRepository
     */
    public RoleRepository getRoleRepository() {
        return roleRepository;
    }

    /**
     * @param roleRepository the roleRepository to set
     */
    public void setRoleRepository(RoleRepository roleRepository) {
        this.roleRepository = roleRepository;
    }

    /**
     * @return the authenticationService
     */
    public AuthenticationService getAuthenticationService() {
        return authenticationService;
    }

    /**
     * @param authenticationService the authenticationService to set
     */
    public void setAuthenticationService(AuthenticationService authenticationService) {
        this.authenticationService = authenticationService;
    }

    public String login(){
//        try {
//            FacesContext.getCurrentInstance().getExternalContext().redirect("j_spring_security_check?j_username=" + username + "&j_password=" + pin);
//        } catch (IOException ex) {
//            java.util.logging.Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
//        }
        logger.debug("entering login...");
        System.out.println("Entering login...");
        logger.debug("userbean = " + this);
        boolean success = authenticationService.login(surname, pin);
        if (!success) {
            JSFUtils.addErrorMessage("Username or password incorrect");
            return "login";
        }
        return "home";
    }

    public String logout(){
        authenticationService.logout();
        return "login";
    }

    @Override
    public String toString() {
        return "UserBean{" + "username=" + username + ", pin=" + pin + ", name=" + name + ", surname=" + surname + '}';
    }

}

Listing 23 – persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="hibernatePersistenceUnit" transaction-type="RESOURCE_LOCAL">
    <class>com.mycompany.security.domain.Role</class>
    <class>com.mycompany.security.domain.User</class>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
      <property name="javax.persistence.jdbc.url" value="jdbc\:mysql\://localhost/spring_security"/>
      <property name="javax.persistence.jdbc.password" value=""/>
      <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="javax.persistence.jdbc.user" value="root"/>
    </properties>
    <mapping-file>META-INF/orm.xml</mapping-file>
  </persistence-unit>
</persistence>

The following pages are spring related and not JSF.
Listing 24 – menu.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ page import="org.springframework.security.core.context.SecurityContextHolder" %>

<c:url value="/" var="homeUrl"/>
<c:url value="user" var="userUrl"/>
<c:url value="admin" var="adminUrl"/>
<c:url value="logout" var="logoutUrl"/>

<div class="menu">
	<ul>
		<li><a href="${homeUrl}">Home</a></li>
		<li><a href="${userUrl}">User</a></li>

		<sec:authorize access="hasRole('ROLE_ADMIN')">
		<li><a href="${adminUrl}">Admin</a></li>
		</sec:authorize>

		<li><a href="${logoutUrl}">Logout</a></li>
	</ul>
</div>

Listing 25 – login.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>

<html>
<head>
	<link rel="stylesheet" type="text/css" media="screen" href="resources/css/style.css"/>
	<title>Login</title>
</head>

<body>
	<form class="login-form" action="j_spring_security_check" method="post" >
		<fieldset>
			<legend>Login Here</legend>

			<p>
			<label for="j_username">Username</label>:
			<input id="j_username" name="j_username" size="20" maxlength="50" type="text"/>
			</p>

			<p>
			<label for="j_password">Password</label>:
			<input id="j_password" name="j_password" size="20" maxlength="50" type="password"/>
			</p>

			<p><input type="submit" value="Login"/></p>
		</fieldset>
	</form>
	<p class="message">${message}</p>
</body>
</html>

Listing 26 – spring-security-taglib.xml

<?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.FaceletsAuthorizeTagHandler</handler-class>
	</tag>
	<function>
		<function-name>areAllGranted</function-name>
		<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areAllGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>areAnyGranted</function-name>
		<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areAnyGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>areNotGranted</function-name>
		<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean areNotGranted(java.lang.String)</function-signature>
	</function>
	<function>
		<function-name>isAllowed</function-name>
		<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
		<function-signature>boolean isAllowed(java.lang.String, java.lang.String)</function-signature>
	</function>
</facelet-taglib>
About these ads
 
7 Comments

Posted by on March 7, 2012 in Spring Security

 

7 responses to “Spring Security with JSF

  1. HB

    August 7, 2012 at 6:55 pm

    Thank you for the details in your example. The part that I am not following is the custom authentication manager. Shouldn’t that be left to spring security? Thanks again!

     
  2. mlusincuba

    August 8, 2012 at 1:47 am

    Hi HB,
    First of all jsp pages do not need to be spring specific but can be used as pure jsf pages. The other thing is that spring-security-taglib does not work very well, so you can use some other mechanism to filter the pages to be displayed based on loggen in user.

    To clarify custom authentication manager, we used alias “authenticationManager” on spring-security.xml so that we can always refer to the tag “authentication-manager” as “authenticationManager”. This uses user defined authentication for user details, which is using plaintext but you must use something like md5 encryption method instead.

    Listing 20, uses this alias in question on lines:
    31: @Qualifier(“authenticationManager”)
    32: private AuthenticationManager authenticationManager;

    Line 47 on listing 20, does the actual authentication as shown below.
    47: Authentication authentication = authenticationManager.authenticate(token);

    To answer your last question, This is actually spring security. Looking at same listing 20 you find the import “14: import org.springframework.security.authentication.AuthenticationManager;”; which is spring.

     
  3. ozgun

    August 22, 2012 at 11:35 am

    where is the source codes? can we download? thanx

     
    • mlusincuba

      August 22, 2012 at 11:44 am

      Do you mean you don’t see source code here or you don’t see the complete working project?

       
      • Gaston

        October 17, 2012 at 1:51 pm

        Text for xml files (or anything non-*.java) shows garbled on both Chrome and FFx. It’d be awesome if you could upload the source to Github or Google code. (Great tutorial btw)

        Many thanks!

         
      • mlusincuba

        October 17, 2012 at 2:07 pm

        Well something must have happened to create the issue. I will look at it and also put the source code to google code.

         
      • Gaston

        October 17, 2012 at 2:46 pm

        Much appreciated :D

         

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 27 other followers

%d bloggers like this: