Spring Security Authentication With JSF (Java Server Faces)
Spring Security Authentication With JSF (Java Server Faces)
Authentication with
JSF (Java Server Faces)
(Using Maven Project in
Eclipse IDE)
<artifactId>javax.faces</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.20</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument-tomcat</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/test/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
<excludes>
<exclude>**/*local.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src\main\resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.vm</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>src\main\webapp\WEBINF</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<server>devserver</server>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src\main\webapp\WEB-INF\web.xml</webXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
This should automatically start downloading maven jar files related to the
pom.xml entries. If not, then
1) right click on project from project explorer
2) select Run As -> Maven Install
<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>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.faces</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filterclass>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/security-context.xml</param-value>
</context-param>
<listener>
<listenerclass>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="*" />
<http disable-url-rewriting="true">
<form-login login-page="/login" default-target-url="/index"
authentication-failure-url="/login" usernameparameter="username"
password-parameter="password" />
<custom-filter after="CONCURRENT_SESSION_FILTER"
ref="concurrencyFilter" />
<session-management
session-authentication-strategy-ref="sas" />
<headers />
</http>
<beans:bean id="UserDetailsManager" class="security.UserDetailsManager" />
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/sessionExpired" />
</beans:bean>
<beans:bean id="myAuthFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthentic
ationFilter">
<beans:property name="sessionAuthenticationStrategy"
ref="sas" />
<beans:property name="authenticationManager"
ref="authenticationManager" />
</beans:bean>
<beans:bean id="sas"
class="org.springframework.security.web.authentication.session.CompositeSessionA
uthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean
class="org.springframework.security.web.authentication.session.ConcurrentSession
ControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1"
/>
<beans:property name="exceptionIfMaximumExceeded"
value="true" />
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.SessionFixationPr
otectionStrategy">
</beans:bean>
<beans:bean
class="org.springframework.security.web.authentication.session.RegisterSessionAu
thenticationStrategy">
<beans:constructor-arg ref="sessionRegistry" />
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<!-- Select users and user_roles from database -->
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="UserDetailsManager">
<password-encoder hash="plaintext">
</password-encoder>
</authentication-provider>
</authentication-manager>
</beans:beans>
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd">
<managed-bean>
<managed-bean-name>baseUIController</managed-bean-name>
<managed-bean-class>ui.BaseUIController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>dbConnectionController</managed-bean-name>
<managed-bean-class>database.DbConnectionController</managed-beanclass>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>loginUIController</managed-bean-name>
<managed-bean-class>ui.LoginUIController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>authenticationService</property-name>
<value>#{authenticationService}</value>
</managed-property>
</managed-bean>
<navigation-rule>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/login.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>index</from-outcome>
<to-view-id>/index.xhtml</to-view-id>
<redirect />
</navigation-case>
</navigation-rule>
<application>
<elresolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
BaseUIController.java
You can store all common methods/procedures which all controller classes will access under this
class. Controller classes will inherit this class.
package ui;
import java.io.Serializable;
import
import
import
import
javax.faces.application.FacesMessage;
javax.faces.application.FacesMessage.Severity;
javax.faces.context.FacesContext;
javax.faces.context.ExternalContext;
return getActiveLink();
}
public void addFacesMessage(Severity sev, String msg) {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(sev, msg, ""));
}
public String getUserNameParam() {
if (FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().containsKey("USER_NAME_PARAM")) {
this.userNameParam = (String)
FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap()
.get("USER_NAME_PARAM");
}
return userNameParam;
}
public boolean isLoggedInUser() {
ExternalContext extCtxt = FacesContext.getCurrentInstance()
.getExternalContext();
String remoteUser = extCtxt.getRemoteUser();
if (remoteUser != null) {
return true;
}
else return false;
}
/**
* @param userNameParam the userNameParam to set
*/
public void setUserNameParam(String userNameParam) {
this.userNameParam = userNameParam;
}
}
LoginUIController.java
This java class with authenticate user through spring security using the entered username and
password combination.
package ui;
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import security.AuthenticationService;
@Controller
public class LoginUIController extends BaseUIController {
private static final long serialVersionUID = 1L;
private String userName;
private String password;
private String message;
@Autowired
private AuthenticationService authenticationService;
public String login() {
boolean success = authenticationService.login(userName, password);
if (success) {
StringBuilder userNameBuilder = new StringBuilder();
userNameBuilder.append(userName);
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap()
.put("USER_NAME_PARAM",
userNameBuilder.toString());
return "index";
} else {
this.message = "Wrong Username or Password Entered. Please
LOGIN again.";
return "login";
}
}
public String logout() {
authenticationService.logout();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
.clear();
this.userName = null;
this.password = null;
this.message = null;
FacesContext.getCurrentInstance().getExternalContext()
.invalidateSession();
}
return "login";
DbConnectionController.java
It is always advisable to create a seperate controller class for storing database connection details. In
entire project, only this file should have hard coded database connection details so that in case of
changing the connection details, only one file needs to be modified.
package database;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class DbConnectionController {
Connection conn;
Statement stmt;
DriverManager driverManager;
public DbConnectionController() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/DB_NAME", "DB_USER",
"DB_PWD");
stmt = conn.createStatement();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public Statement getStmt() {
return stmt;
}
public void setStmt(Statement stmt) {
this.stmt = stmt;
}
public DriverManager getDriverManager() {
return driverManager;
}
public void setDriverManager(DriverManager driverManager) {
this.driverManager = driverManager;
}
}
@Override
public void logout() {
SecurityContextHolder.getContext().setAuthentication(null);
}
LoginUser.java
package security;
import
import
import
import
java.sql.ResultSet;
java.sql.SQLException;
org.springframework.stereotype.Repository;
database.DbConnectionController;
@Repository
public class LoginUser {
DbConnectionController dbConnectionController;
ResultSet resultSet;
public UserEntity getUser(String userName) throws ClassNotFoundException {
UserEntity user = new UserEntity();
dbConnectionController = new DbConnectionController();
String query = "SELECT * FROM LOGIN WHERE USERNAME = '" + userName
+ "'";
try {
resultSet =
dbConnectionController.getStmt().executeQuery(query);
if (resultSet.next()) {
user.setUsername(resultSet.getString(1));
user.setPassword(resultSet.getString(2));
user.setSuperUser(resultSet.getString(3));
user.setFullname(resultSet.getString(4));
user.setDepartment(resultSet.getString(5));
}
dbConnectionController.getConn().close();
dbConnectionController.setConn(null);
dbConnectionController.setStmt(null);
this.dbConnectionController = null;
} catch (SQLException e) {
e.printStackTrace();
return null;
return user;
}
/**
* @return the dbConnectionController
*/
public DbConnectionController getDbConnectionController() {
return dbConnectionController;
}
/**
* @param dbConnectionController
*
the dbConnectionController to set
*/
public void setDbConnectionController(
DbConnectionController dbConnectionController) {
this.dbConnectionController = dbConnectionController;
}
/**
* @return the resultSet
*/
public ResultSet getResultSet() {
return resultSet;
}
/**
* @param resultSet
*
the resultSet to set
*/
public void setResultSet(ResultSet resultSet) {
this.resultSet = resultSet;
}
UserEntity.java
package security;
public class UserEntity {
private String username;
private String password;
private String superUser;
private String fullname;
private String Department;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
UserDetailsManager.java
package security;
import
import
import
import
import
import
import
org.springframework.security.core.userdetails.User;
org.springframework.security.core.userdetails.UsernameNotFoundException;
org.springframework.stereotype.Service;
org.springframework.security.core.userdetails.UserDetails;
org.springframework.security.core.userdetails.UserDetailsService;
org.springframework.transaction.annotation.Transactional;
org.springframework.security.core.authority.AuthorityUtils;
@Service
public class UserDetailsManager implements UserDetailsService {
@Override
@Transactional
public UserDetails loadUserByUsername(final String userName)
throws UsernameNotFoundException {
boolean
boolean
boolean
boolean
enabled = true;
accountNonExpired = true;
credentialsNonExpired = true;
accountNonLocked = true;
userEntity = loginUser.getUser(userName);
} catch (Exception e) {
e.printStackTrace();
}
login.xhtml
<!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"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:body>
<h:form>
<div align="center">
<fieldset style="width: 300px;">
<br />
<h:outputText value="Username: " />
<h:inputText id="username"
value="#{loginUIController.userName}" />
<br /> <br />
<h:outputText value="Password: " />
<h:inputSecret id="password"
value="#{loginUIController.password}" />
<br /> <br />
<h:commandButton value="Submit"
action="#{loginUIController.login()}" />
<br /> <br />
<h:outputText value="#{loginUIController.message}"
style="color:red" />
</fieldset>
</div>
</h:form>
</h:body>
</html>
index.xhtml
<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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:body>
<h:form>
<h:outputText>Login Successful</h:outputText>
</h:form>
</h:body>