SpringSecurity4,Primefaces5,SpringDataJPA and Hibernate4 CRUD Application(Java Configuration) Using Netbeans8.2 IDE and MySQL Database Server
This simple application is a Create, Retrieve, Update and Delete (CRUD) application operating on an ‘employee’ table in ‘springdatacruddb’ database in MySQL Database Server. It is a SpringSecurity, Spring, SpringDataJPA and Hibernate-annotation based application(Java Configuration).So minimum XML.
Project can also be created using Eclipse.
For Spring Security Primefaces Hibernate java based configuration project please look blog post at below URL
https://raichand-java.blogspot.in/2017/06/springsecurity4primefaces5springdatajpa_16.html
For XML Based Configuration Please look at the blog post at below URL
https://raichand-java.blogspot.in/2016/12/springsecurity4primefaces5springdatajpa.html
For Integrating maven pom.xml of the project is at the end of this post.
This simple application is a Create, Retrieve, Update and Delete (CRUD) application operating on an ‘employee’ table in ‘springdatacruddb’ database in MySQL Database Server. It is a SpringSecurity, Spring, SpringDataJPA and Hibernate-annotation based application(Java Configuration).So minimum XML.
Project can also be created using Eclipse.
For Spring Security Primefaces Hibernate java based configuration project please look blog post at below URL
https://raichand-java.blogspot.in/2017/06/springsecurity4primefaces5springdatajpa_16.html
For XML Based Configuration Please look at the blog post at below URL
https://raichand-java.blogspot.in/2016/12/springsecurity4primefaces5springdatajpa.html
For Integrating maven pom.xml of the project is at the end of this post.
Security
is of critical importance to all web applications. Vulnerable applications are
easy prey for hackers. Spring Security is a Java/Java EE framework that
provides authentication, authorization and other security features for java
language based enterprise applications. It is operating system independent,
works on various kinds of operating system. On 1st September 2016
the latest stable version of spring -Security is 4.1.3.Spring- Security version
4.1.1 is used in this application.
·
Spring Security Features
1. Comprehensive and extensible
support for both Authentication and Authorization.
2. Protection against attacks
like session fixation, clickjacking, cross site request forgery (CSRF), etc.
3. Servlet API integration.
4. Optional integration with
Spring MVC and supports more frameworks.
This
is a web security (Login Logout and Remember me) CRUD application operating on employee,
users and user_roles tables in ‘springdatacruddb’ database in MySQL Database Server.
It is a Hibernate-Annotation
and Spring
Java based application. Different persons with different authorisation
(e.g. user or admin) view different web pages according to authorisation after logging in.
Steps of Authentication mechanism
1.
User submits his credentials to the system; that is, a username and password.
2.
org.springframework.security.authentication.
UsernamePasswordAuthenticationToken
accepts the credentials and passes them
to org.springframework.security.authentication.AuthenticationManager for
validation.
3.
System authenticates the user.
4.
Credential flows as follows: UsernamePasswordAuthenticationTokenà
AuthenticationManager
à Authentication.
5.
Finally a fully loaded authentication instance is returned.
6.
SecurityContextHolder accepts the authentication instance.
7.
The system also checks for authorisation of roles or groups.
8. Finally, the
user is allowed to access the system based on his authorisation(i.e Role).
Most of the above steps occur as default, so not coded.But every component of spring security could be customised according to requirement.
Remember-me
functionality enables a user to keep logged-in.
Basically
remember me functionality does 2 things
1.In Remember-me or persistent-login authentication, Applications remember the identity of user between sessions. In our
application we provide an option, usually checkbox, to the user to select
remember-me and if the user checks it then after successful login, spring
application sends a remember-me browser cookie to the browser in addition to
session cookie.This cookie will be stored at browser side and will remain there for certain period(defined by cookie lifetime).
"rememeber-me"
browser cookie is created with a token based on username,password ( token can
be computed and persisted in database if needed or it can be on the fly computed hash
of user’s password).
2.When the
user tries to access the secured page without any session (session is expired
because of timeout), then RememberMe service will try to autoLogin the user by
retrieving the user details from the remember-me cookie and can verify user
details if needed.User will be automatically logged in, without providing userid/password. Spring performs remember-me functionality by creating token
using authentication details.
.
Software
Used
1.JDK8u25
2.Netbeans
8.2
3.MySQL
5.* Database Server(or XAMPP-For easy MySQL Management)
4.MySQL
Connector 5.*
5.Hibernate
4.3.** and Primefaces 5.0(Bundled with Netbeans)
6.Spring4.3.2
7.Spring
Security 4.1.1
Steps
1.Install
JDK8 or Jdk7 if not installed
2.Install
Netbeans and associated ApacheTomcat Server
3.Install MySQL Database server or XAMPP(For easy
management of MySQL ) .
After
Installing Netbeans click the services tab on the left.Expand Database node.
Expand Drivers node. Right click MySQL(Connector/Jdriver) then connect. Put
springdatacruddb as the database. As shown below. Put password if you have
given password at the time of installation of MySQL database server. For XAMPP no password is required. Then test connection.
If successful click finish button.
Create
user table by running below SQL in ‘springdatacruddb’ database
CREATE
TABLE IF NOT EXISTS `employee` (
`EmpId` int(15) NOT NULL,
`FirstName` varchar(25) NOT NULL,
`LastName` varchar(25) NOT NULL,
`Salary` int(20) NOT NULL,
`Sex` varchar(15) NOT NULL,
`DOB` date NOT NULL,
`Remark` varchar(50) NOT NULL
)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER
TABLE `employee` ADD PRIMARY KEY
(`EmpId`);
INSERT INTO `employee` (`EmpId`, `FirstName`, `LastName`,
`Salary`, `Sex`, `DOB`, `Remark`) VALUES
(1, 'Andrei', 'Agassi', 1000000, 'Male', '1976-06-15', 'Very
Good Tennis Player'),
(2, 'Martina', 'Navratilova', 60000000, 'Female',
'1978-12-15', 'Very Good Tennis Player'),
(3, 'Venus', 'Williams', 7000000, 'Female', '1975-12-21',
'Very Good Tennis Player'),
(4, 'Roger', 'Fedrer', 600000, 'Male', '1987-12-20', 'Very
Good Tennis Player'),
(5, 'Lindsay', 'Devonport', 600000, 'Female', '1974-12-14',
'Very good Tennis Player '),
(6, 'Serena', 'Williams', 600000, 'Female', '1988-12-16',
'Very Good Tennis Player'),
(7, 'Barak', 'Obama', 5463216, 'Male', '1961-12-18',
'Ex-President USA'),
(8, 'Mary', 'Pierce', 8654321, 'Female', '1993-06-14', 'Very
Good Tennis Player'),
(9, 'Rafel', 'Nadal', 754321, 'Male', '1991-04-12', 'Very
Goog Tennis Player'),
(10, 'Sir Donald', 'Bradman', 650000, 'Male', '1942-05-06',
'Very Good Cricket Bowler'),
(11, 'Usin', 'Bolt', 690700, 'Male', '1998-12-16',
'Olympics Gold Medalist in Athletics'),
(12, 'Micheal', 'Phelps', 765000, 'Male', '1992-12-22',
'Olympics Gold Medalist in Swimming.USA
Citizen.'),
(13, 'Andy', 'Moore', 750000, 'Male', '1991-05-09', 'Very
Goog Tennis Player'),
(14, 'Tom', 'Cruise', 7000000, 'Male', '1975-01-15', 'Good
Actor'),
(15, 'Maria', 'Sharpova', 950000, 'Female', '1978-11-21',
'Very good beautiful Tennis Player'),
(16, 'Martina',
'Hingis', 850000, 'Female', '1982-02-18', 'Very Goog Tennis Player'),
(17, 'Vin', 'Diesel', 840000, 'Male', '1985-01-17', 'Very
Good Actor'),
(18, 'Angelina', 'Jolie', 7500000, 'Female', '1987-11-14',
'Very Good Actress'),
(19, 'Brad', 'Pitt', 765000, 'Male', '1979-01-24', 'Very Good
Actor');
CREATE
TABLE IF NOT EXISTS `users` (
`username` varchar(255) NOT NULL,
`password` varchar(255) DEFAULT NULL,
`enabled` tinyint(1) DEFAULT NULL
)
ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER
TABLE `users` ADD PRIMARY KEY
(`username`);
INSERT
INTO `users` (`username`, `password`, `enabled`) VALUES
('admin',
'admin123', 1),
('alex',
'alex123', 1),
('deepak',
'deepak123', 2),
('raichand70',
'jaishriram', 1);
CREATE
TABLE IF NOT EXISTS `user_roles` (
`user_role_id` int(15) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`role` varchar(50) DEFAULT NULL
)
ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
ALTER
TABLE `user_roles` ADD PRIMARY KEY
(`user_role_id`), ADD KEY `FK_USERNAME` (`username`);
ALTER
TABLE `user_roles` MODIFY `user_role_id`
int(15) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5;
ALTER
TABLE `user_roles`ADD CONSTRAINT `FK_USERNAME` FOREIGN KEY (`username`)
REFERENCES `users` (`username`);
Insert
these Records below by executing below insert statement
INSERT
INTO `user_roles` (`user_role_id`, `username`, `role`) VALUES
(1,
'admin', 'ROLE_ADMIN'),
(2,
'alex', 'ROLE_USER'),
(3,
'raichand70', 'ROLE_ADMIN'),
(4,
'deepak', 'ROLE_USER');
JARS required to be added
to Libraries Folder
Right click on the Libraries folderà addJAR/Folder then add below mentioned JAR Files .
1.aopalliance-1.0.jar
2.javax.inject-1.jar
3.commons-logging-1.2.jar
4.mysql-connector-java-bin.jar
5. Jandex-2.0.3
6. spring-aop-4.3.2
7. spring-beans-4.3.2
8. spring-context-4.3.2
9. spring-core-4.3.2
10. spring-tx-4.3.2
11. spring-web-4.3.2
12. spring-expression-4.3.2
13. spring-jdbc-4.3.2
14. spring-orm-4.3.2
15. spring-security-config-4.1.1
16. spring-security-core-4.1.1
17. spring-security-web-4.1.1
18. Spring-data-commons-1.12.5
19. Spring-data-jpa-1.10.5
Creating Project SpringSecurity4SpringDataJPAPrimefaces5Hibernate4RememberMeExample
File-àNew
ProjectàCategories-àChoose JavaWeb--àChoose WebApplicationàClick Next-àGive Project Name SpringSecurityPrimefacesSpringDataCRUDRememberMe_JavaConfigurationà
Click NextàClick
NextàChoose Framework First Hibernate then Java Server Faces--àClick
Component Tab-àChoose Primefacesà Click Finish
In the above figure Database Connection
should be with ‘springdatacruddb’ database.
Download mysql-
connector-java-bin.jar add to libraries folder by right click addJAR/Folderàadd the mysql-java-bin.jar.
Create a folder named View under Web
pages Folder.Delete welcomePrimefaces.xhtml .Create Two Folders named Secured
and UnSecured under View Folder. Create two folders named User and Admin under
Secured Folder.Admin Folder would contain crud.xhtml File. User folder would
contain add.xhtml file. UnSecured Folder would contain one file login.xhtml.
Project Structure
Creating Packages and Classes
Right
click Source Package folder and create seven packages
1.
com.ray.jsfbean.controller-->This would contain JSF Managed Bean Class LoginController.java and EmployeeBean.java
2.
com.ray.security.custom.auth.handleràThis would contain Spring
authorization class file CustomAuthenticationHandler.java
This
Class directs the person logging in after authentication with username and
password to the authorized web page depending on authority like User or Admin.
2.
com.ray.springdatajpa.dao.repositories-àThis would contain
DAO(Data Access Object) Repositories EmployeeRepository.java
and UserRepository.java
3.com.ray.springdatajpa.exceptionàThis would contain one
file EmployeeNotFoundException.java
4.
com.ray.springsecurity.pojos.modelàThis would contain entity
(POJO) class files Employee.java,User.java and UserRole.java. POJO Stands for
Plain Old Java Objects
6.
com.ray.springsecurity.serviceàThis would contain Spring
Service class files CustomUserDetailsService.java ,EmployeeService.java
and EmployeeServiceImpl.Java.
7.
com.ray.webspringsecurity.javaconfig-àThis would contain Java Configuration
Files JPAConfiguration.java
, MyWebSecurityConfiguration.java, SecurityWebApplicationInitializer.java
and WebAppInitializer.java
Following
Files would be created using Netbeans
1. hibernate.cfg,xml File-àAutomatically generated.
(It will be used to create User.java,UserRole .java and Employee.java and then
would be deleted.)
2.
hibernate.reveng.xmlà Reverse Engineering File.
(It will be used to create User.java,UserRole.java and Employee.java and then would be deleted.)
3.Entity(POJO)
File-àEmployee.java and User.java
and UserRole.java(POJO stands for Plain Old Java
Objects)
4. LoginContoller.ja vaà JSF
Managed Bean Login File
5. EmployeeBean.java àJSF
Managed Bean Employee Bean File
6. CustomUserDetailsService.javaà UserDetailsService Implementation File
7. EmployeeService
.java àEmployeeService Interface File
8. EmployeeServiceImpl.javaà EmployeeService Implementation File
9. EmployeeRepository.javaà Employee Repository File
10. UserRepository.javaà User Repository File
11. EmployeeNotFoundException.javaà Exception handling File
12. CustomAuthenticationHandler.javaà
SpringSecurityAuthorisationHandler File
13. login.xhtmlàPerson
writes his/her username and password with remember me facility
14. crud.xhtmlàThis
is displayed if the person logging in is having admin authorization.
15. add.xhtmlàThis
is displayed if the person logging in is having user authorization. This
displays the profile of user.
16.faces-config.xmlàIt
is to be added after creating under WEB-INF folder if not there.
17. web.xml
(Automatically generated)
18. index.xhtmlàIt redirects to login
page.
19. JPAConfiguration.javaàIt
contains database transaction and connection credential
20. MyWebSecurityConfiguration.javaàIt
contains SpringsecurityRememberMe credentials
21. SecurityWebApplicationInitializer.javaàIt
contains springSecurityFilterChain credentials
22. WebAppInitializer.javaàThis
class launches the index.xhtml web page
when web application starts.
Add mysql-
connector-java-bin.jar to libraries if not done.
COPY
AND PASTE CODE OF THE FILE GIVEN BELOW
WHOSE CODE IS NOT GENERATED
1.Hibernate.cfg.xml File(It would be deleted after used for
creating User.java and User_Role entity
class)
As XAMPP is used so there is no
password in the file only username
is given that is root in
Hibernate.cfg.xml File.
Code:-
<?xml
version="1.0" encoding="UTF-8"?>
<!DOCTYPE
hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD
3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property
name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property
name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="hibernate.connection.url">jdbc:mysql://localhost:3306/ springdatacruddb?zeroDateTimeBehavior=convertToNull</property>
<property
name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">
</property>
<property name="hibernate.connection.pool_size">10</property>
<property
name="show_sql">true</property>
<property
name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property
name="hibernate.hbm2ddl.auto">update</property>
<mapping class="com.ray.springsecurity.pojos.model.User"/>
<mapping class="com.ray.pojos.springsecurity.model.UserRole"/>
<mapping class="com.ray.pojos.springsecurity.model.Employee"/>
<mapping class="com.ray.pojos.springsecurity.model.Employee"/>
</session-factory>
</hibernate-configuration>
2. Creating Reverse
Engineering File-àhibernate.reveng.xml(It
would be deleted after used for creating entity classes).
Right Click default package in the Source
Package-ànewàchoose Hibernate Reverse Engineering Wizardàclick
nextàchoose employee,User and UserRole tableàAdd àclick
finish.
CODE:
<?xml version="1.0"
encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering
PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd">
<hibernate-reverse-engineering>
<schema-selection match-catalog=" springdatacruddb "/>
<table-filter match-name="user"/>
<table-filter
match-name="user_role"/>
<table-filter match-name="employee"/>
</hibernate-reverse-engineering>
3. Creating Hibernate Entity
(pojo) File:-Employee.java and User.java and UserRole.java
Important:To create this
file MySQL database springsecurity most be connected through Netbeans.
Right
click com.model package--ànew-àHibernate Mappling Files
and pojos from databaseàDonot select mapping file
& select EJB3.0 Pattern and Domain Code(java) àAlso select JDK5
Language Features tough not displayedàClick Finish
Please Modify both entity
classes as Given Below. Generated code may differ a little.
Employee.java CODE:
package
com.ray.springsecurity.pojos.model;
import
java.util.Date;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.Id;
import
javax.persistence.Table;
import
javax.persistence.Temporal;
import
javax.persistence.TemporalType;
/**
*
* @author Raichand
*/
@Entity
@Table(name="employee"
,catalog="springdatacruddb"
)
public
class Employee implements
java.io.Serializable {
private int empId;
private String firstName;
private String lastName;
private int salary;
private String sex;
private Date dob;
private String remark;
@Id
@Column(name="EmpId", unique=true,
nullable=false)
public int getEmpId() {
return this.empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
@Column(name="FirstName",
nullable=false, length=25)
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
@Column(name="LastName",
nullable=false, length=25)
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name="Salary",
nullable=false)
public int getSalary() {
return this.salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Column(name="Sex",
nullable=false, length=15)
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Temporal(TemporalType.DATE)
@Column(name="DOB",
nullable=false, length=10)
public Date getDob() {
return this.dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
@Column(name="Remark",
nullable=false, length=50)
public String getRemark() {
return this.remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public
void reset() {
this.setEmpId(0);
this.setFirstName("");
this.setLastName("");
this.setSex("");
this.setSalary(0);
this.setDob(null);
this.setRemark("");
}
//This method writes the values of contact
object with System.out.println(employee.toString()) code
@Override
public String toString() {
return "employee"
+ "\n\t Id: " + this.empId
+ "\n\t FirstName: " +
this.firstName
+ "\n\t LastName: " +
this.lastName
+ "\n\t Sex: " + this.sex
+ "\n\t Salary: " +
this.salary
+ "\n\t Date of Birth: " +
this.dob
+ "\n\t Remark: " + this.remark;
}
}
User.java CODE:
package
com.ray.springsecurity.pojos.model;
import
java.io.Serializable;
import
java.util.HashSet;
import
java.util.Set;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.FetchType;
import
javax.persistence.Id;
import
javax.persistence.OneToMany;
import
javax.persistence.Table;
@Entity
@Table(name
= "users", catalog = "springdatacruddb")
public
class User implements Serializable{
private String username;
private String password;
private boolean enabled;
private Set<UserRole> userRole
= new HashSet<UserRole>(0);
@Id
@Column(name = "username",
unique = true,
nullable = false, length
= 45)
public String getUsername() {
return this.username;
}
public void setUsername(String
username) {
this.username =
username;
}
@Column(name = "password",
nullable = false, length
= 60)
public String getPassword() {
return this.password;
}
public void setPassword(String
password) {
this.password =
password;
}
@Column(name = "enabled",
nullable = false)
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean
enabled) {
this.enabled = enabled;
}
@OneToMany(fetch = FetchType.LAZY,
mappedBy = "user")
public Set<UserRole>
getUserRole() {
return this.userRole;
}
public void
setUserRole(Set<UserRole> userRole) {
this.userRole =
userRole;
}
}
UserRole.Java CODE:-
package
com.ray.springsecurity.pojos.model;
import
java.io.Serializable;
import
static javax.persistence.GenerationType.IDENTITY;
import
javax.persistence.Column;
import
javax.persistence.Entity;
import
javax.persistence.FetchType;
import
javax.persistence.GeneratedValue;
import
javax.persistence.Id;
import
javax.persistence.JoinColumn;
import
javax.persistence.ManyToOne;
import
javax.persistence.Table;
import
javax.persistence.UniqueConstraint;
@Entity
@Table(name
= "user_roles", catalog = "springdatacruddb",
uniqueConstraints = @UniqueConstraint(
columnNames = {
"role", "username" }))
public
class UserRole implements Serializable{
private Integer userRoleId;
private User user;
private String role;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name =
"user_role_id",
unique = true, nullable =
false)
public Integer getUserRoleId() {
return this.userRoleId;
}
public void setUserRoleId(Integer
userRoleId) {
this.userRoleId = userRoleId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name =
"username", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
@Column(name = "role",
nullable = false, length = 45)
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
}
4. JSF Managed Bean File LoginController.java
File
Right
click com.controller package--ànew-àJSF Managed BeanàGive class name LoginController-à click finish.
package
com.ray.jsfbean.controller;
import
java.io.IOException;
import
java.io.Serializable;
import
javax.faces.bean.SessionScoped;
import
javax.faces.context.ExternalContext;
import
javax.faces.context.FacesContext;
import
javax.inject.Named;
import
javax.servlet.RequestDispatcher;
import
javax.servlet.ServletException;
import
javax.servlet.ServletRequest;
import
javax.servlet.ServletResponse;
/**
*
* @author Raichand
*/
@Named()
@SessionScoped()
public
class LoginController implements Serializable {
private String username;
private String password;
public void login() throws
ServletException, IOException {
System.out.println("Login
controller password is :-" + password);
ExternalContext context =
FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher =
((ServletRequest) context.getRequest()).getRequestDispatcher("/login");
dispatcher.forward((ServletRequest)
context.getRequest(), (ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
}
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;
}
}
5. JSF Managed Bean File EmployeeBean.java
File
Right
click com.controller package--ànew-àJSF Managed BeanàGive class name EmployeeBean-à click finish.
package com.ray.jsfbean.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.stereotype.Component;
import org.springframework.dao.DataAccessException;
import com.ray.springsecurity.pojos.model.Employee;
import com.ray.springsecurity.service.EmployeeService;
import org.primefaces.context.RequestContext;
import com.ray.springdatajpa.exception.EmployeeNotFoundException;
import javax.faces.context.FacesContext;
/**
*
* @author Raichand
*/
//@Named(value = "employeeBean")
@Component//with it spring can can this class as a bean.@Named also does same thing
@ManagedBean(name="employeeBean")
@SessionScoped
public class EmployeeBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject//@ Autowired or #(ManagedProperty) can also be used
private EmployeeService employeeService;
private List<Employee> employeeList;
private Employee employee = new Employee();
private List<Employee> selectedEmployees;
private Employee selectedEmployee;
/**
* Creates a new instance of EmployeeBean
*/
public EmployeeBean() {
}
public void addEmployee() {
try {
int newId = getEmployeeService().CreateNewEmpId();//Retrieving Id of last Employee in Employee Table and adding 1 to it for next record id
System.out.println(newId);
employee.setEmpId(newId);
getEmployeeService().create(employee);
employee.reset();
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Save ","Employee Information saved successfully.");
RequestContext.getCurrentInstance().showMessageInDialog(message);
} catch (DataAccessException e) {
e.printStackTrace();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "D'oh!", "Message: "));
}
}
public void changeEmployee(Employee employee) {
this.employee= employee;
}
public void updateEmployee()throws Exception{
getEmployeeService().update(employee);
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Update","Employee Information updated successfully .");
RequestContext.getCurrentInstance().showMessageInDialog(message);
this.reset();
}
public void deleteEmployee()throws Exception {
for (Iterator iterator = selectedEmployees.iterator(); iterator.hasNext();) {
Employee employee = (Employee) iterator.next();
getEmployeeService().delete(employee.getEmpId());
}
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Delete","Employee Records deleted successfully");
RequestContext.getCurrentInstance().showMessageInDialog(message);
}
public void reset() {
this.employee.reset();
}
public List<Employee> getEmployeeList() {
employeeList = new ArrayList<Employee>();
employeeList.addAll(getEmployeeService().findAll());
return employeeList;
}
public EmployeeService getEmployeeService() {
return employeeService;
}
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public List<Employee> getSelectedEmployees() {
return selectedEmployees;
}
public void setSelectedEmployees(List<Employee> selectedEmployees) {
this.selectedEmployees = selectedEmployees;
}
public Employee getSelectedEmployee() {
return selectedEmployee;
}
public void setSelectedEmployee(Employee selectedEmployee) {
this.selectedEmployee = selectedEmployee;
}
}
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.stereotype.Component;
import org.springframework.dao.DataAccessException;
import com.ray.springsecurity.pojos.model.Employee;
import com.ray.springsecurity.service.EmployeeService;
import org.primefaces.context.RequestContext;
import com.ray.springdatajpa.exception.EmployeeNotFoundException;
import javax.faces.context.FacesContext;
/**
*
* @author Raichand
*/
//@Named(value = "employeeBean")
@Component//with it spring can can this class as a bean.@Named also does same thing
@ManagedBean(name="employeeBean")
@SessionScoped
public class EmployeeBean implements Serializable {
private static final long serialVersionUID = 1L;
@Inject//@ Autowired or #(ManagedProperty) can also be used
private EmployeeService employeeService;
private List<Employee> employeeList;
private Employee employee = new Employee();
private List<Employee> selectedEmployees;
private Employee selectedEmployee;
/**
* Creates a new instance of EmployeeBean
*/
public EmployeeBean() {
}
public void addEmployee() {
try {
int newId = getEmployeeService().CreateNewEmpId();//Retrieving Id of last Employee in Employee Table and adding 1 to it for next record id
System.out.println(newId);
employee.setEmpId(newId);
getEmployeeService().create(employee);
employee.reset();
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Save ","Employee Information saved successfully.");
RequestContext.getCurrentInstance().showMessageInDialog(message);
} catch (DataAccessException e) {
e.printStackTrace();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "D'oh!", "Message: "));
}
}
public void changeEmployee(Employee employee) {
this.employee= employee;
}
public void updateEmployee()throws Exception{
getEmployeeService().update(employee);
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Update","Employee Information updated successfully .");
RequestContext.getCurrentInstance().showMessageInDialog(message);
this.reset();
}
public void deleteEmployee()throws Exception {
for (Iterator iterator = selectedEmployees.iterator(); iterator.hasNext();) {
Employee employee = (Employee) iterator.next();
getEmployeeService().delete(employee.getEmpId());
}
FacesMessage message= new FacesMessage(FacesMessage.SEVERITY_INFO, "Delete","Employee Records deleted successfully");
RequestContext.getCurrentInstance().showMessageInDialog(message);
}
public void reset() {
this.employee.reset();
}
public List<Employee> getEmployeeList() {
employeeList = new ArrayList<Employee>();
employeeList.addAll(getEmployeeService().findAll());
return employeeList;
}
public EmployeeService getEmployeeService() {
return employeeService;
}
public void setEmployeeService(EmployeeService employeeService) {
this.employeeService = employeeService;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public List<Employee> getSelectedEmployees() {
return selectedEmployees;
}
public void setSelectedEmployees(List<Employee> selectedEmployees) {
this.selectedEmployees = selectedEmployees;
}
public Employee getSelectedEmployee() {
return selectedEmployee;
}
public void setSelectedEmployee(Employee selectedEmployee) {
this.selectedEmployee = selectedEmployee;
}
}
6. CustomUserDetailsService.java
Service File
Right
click com.ray.springsecurity.service package-ànew-àjavaclassàClass name àGive name CustomUserDetailsServiceàClick Finish
CustomUserDetailsService.java CODE:
package
com.ray.springsecurity.service;
import
java.util.ArrayList;
import
java.util.HashSet;
import
java.util.List;
import
java.util.Set;
import
com.ray.springdatajpa.dao.repositories.UserRepository;
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;
import
org.springframework.transaction.annotation.Transactional;
import
javax.persistence.EntityManager;
import
javax.persistence.PersistenceContext;
import com.ray.springsecurity.pojos.model.UserRole;
@Service("CustomUserDetailsService")
@Transactional(readOnly=true)
public
class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository
userRepository ;
@Override
public UserDetails
loadUserByUsername(final String username) throws UsernameNotFoundException {
System.out.println("username
is:-" + username);
com.ray.springsecurity.pojos.model.User
user = userRepository.findByUsername(username);
System.out.println("Password
From Detailservice is:-" + user.getPassword().toString());
System.out.println(user.toString());
if (user==null){throw new
UsernameNotFoundException("No such user: " + username);
}else
if(user.getUserRole().isEmpty()){
throw
new UsernameNotFoundException("User" + username + "has no
authorities");
}
System.out.println("password is:-" +
user.getPassword().toString());
List<GrantedAuthority>
authorities = buildUserAuthority(user.getUserRole());
return
buildUserForAuthentication(user, authorities); }
// Converts
com.ray.springsecurity.pojos.model.User user to
// org.springframework.security.core.userdetails.User
private
User buildUserForAuthentication(com.ray.springsecurity.pojos.model.User user,
List<GrantedAuthority> authorities) {
return
new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true,
true, authorities);
}
private
List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles)
{
Set<GrantedAuthority> setAuths
= new HashSet<GrantedAuthority>();
// Build user's
authorities
for (UserRole userRole :
userRoles) {
setAuths.add(new
SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority>
Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
7.Employee Service
Interface File:-EmployeeService.java
package com.ray.springsecurity.service;
import java.util.List;
import
com.ray.springsecurity.pojos.model.Employee;
import
com.ray.springdatajpa.exception.EmployeeNotFoundException;
/**
*
*
@author Raichand
*/
public interface EmployeeService {
public Employee create(Employee employee);
public
void delete(int empid) throws EmployeeNotFoundException;
public List<Employee> findAll();
public Employee update(Employee employee) throws
EmployeeNotFoundException;
public Employee findById(int empid);
public int CreateNewEmpId();
}
8.Employee Service
Implementation File:-EmployeeServiceImpl.java
package com.ray.springsecurity.service;
import java.util.List;
import javax.annotation.Resource;
import
org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import
com.ray.springsecurity.pojos.model.Employee;
import
com.ray.springsecurity.service.EmployeeService;
import
com.ray.springdatajpa.dao.repositories.EmployeeRepository;
import
com.ray.springdatajpa.exception.EmployeeNotFoundException;
/**
*
*
@author Raichand
*/
@Service
public class EmployeeServiceImpl implements
EmployeeService {
@Resource
private EmployeeRepository employeeRepository;
@Override
@Transactional
public Employee create(Employee employee) {
Employee createdEmployee = employee;
return employeeRepository.save(createdEmployee);
}
@Override
@Transactional
public int CreateNewEmpId() {
int maxEmpId = employeeRepository.getMaxEmpId();
return maxEmpId+1;
}
@Override
@Transactional
public Employee findById(int empid) {
return employeeRepository.findOne(empid);
}
@Override
@Transactional(rollbackFor=EmployeeNotFoundException.class)
public void delete(int empid) throws EmployeeNotFoundException {
Employee deletedEmployee = employeeRepository.findOne(empid);
if (deletedEmployee == null)
throw new EmployeeNotFoundException("Employee Not Found");
employeeRepository.delete(deletedEmployee);
}
@Override
@Transactional
public List<Employee> findAll() {
return employeeRepository.findAll();
}
@Override
@Transactional(rollbackFor=EmployeeNotFoundException.class)
public Employee update(Employee employee) throws
EmployeeNotFoundException {
Employee updatedEmployee =
employeeRepository.findOne(employee.getEmpId());
if (updatedEmployee == null)
throw new EmployeeNotFoundException("Employee not
Found");
updatedEmployee.setFirstName(employee.getFirstName());
updatedEmployee.setLastName(employee.getLastName());
updatedEmployee.setSalary(employee.getSalary());
updatedEmployee.setSex(employee.getSex());
updatedEmployee.setDob(employee.getDob());
updatedEmployee.setRemark(employee.getRemark());
return updatedEmployee;
}
}
9.
EmployeeRepository.javaà Employee Repository File
package
com.ray.springdatajpa.dao.repositories;
import
org.springframework.data.jpa.repository.JpaRepository;
import
org.springframework.data.jpa.repository.Query;
import
com.ray.springsecurity.pojos.model.Employee;
/**
*
* @author Raichand
*/
public
interface EmployeeRepository extends JpaRepository<Employee,Integer> {
@Query("SELECT max(e.empId) FROM Employee
e")//Retrieving Maximum Id of Employee Record
int getMaxEmpId();
}
10.
UserRepository.javaà User Repository File
package
com.ray.springdatajpa.dao.repositories;
import
com.ray.springsecurity.pojos.model.User;
import
org.springframework.data.jpa.repository.JpaRepository;
/**
*
* @author Raichand
*/
public
interface UserRepository extends JpaRepository<User,Integer>{
User findByUsername(String
username);
}
11.
EmployeeNotFoundException.javaà Exception handling File
package
com.ray.springdatajpa.exception;
/**
*
* @author Raichand
*/
public
class EmployeeNotFoundException extends Exception{
public EmployeeNotFoundException(String
message){
super(message);
}
}
12.CustomAuthenticationHandler.java Class File
Right
click com.ray.security.custom.auth.handler package-ànew-àjavaclassàClass name àGive name CustomAuthenticationHandleràClick Finish
CustomAuthenticationHandler.java
CODE:
package
com.ray.security.custom.auth.handler;
import
java.io.IOException;
import
java.util.Set;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
org.springframework.security.core.Authentication;
import
org.springframework.security.core.authority.AuthorityUtils;
import
static org.springframework.security.crypto.keygen.KeyGenerators.string;
import
org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
/**
*
* @author Raichand
*/
/*
* This Class Redirects to authorised page
according to role of the person logging in.
*/
public
class CustomAuthenticationHandler extends SimpleUrlAuthenticationSuccessHandler
{
@Override
public void
onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse
response,
Authentication
authentication) throws ServletException, IOException {
String userTargetUrl =
"/View/Secured/User/add.xhtml";
String adminTargetUrl =
"/View/Secured/Admin/crud.xhtml";
Set<String> roles =
AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if
(roles.contains("ROLE_ADMIN")) {
getRedirectStrategy().sendRedirect(request, response, adminTargetUrl);
} else if
(roles.contains("ROLE_USER")) {
getRedirectStrategy().sendRedirect(request, response, userTargetUrl);
} else {
super.onAuthenticationSuccess(request,
response, authentication);
}
}
}
13. login.xhtml code
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.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:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Login</title>
</h:head>
<body>
<center><h2>Login</h2></center>
<c:if test="${'fail' eq
param.auth}">
<div style="color:red">
Login Failed!!!<br/>
Reason : Bad Credentials!Please Try Again.
</div>
</c:if>
<center><h:form prependId="false"
id="form">
<p:panelGrid columns="2" style="border-bottom-width:
0px;">
<h:outputText
value="UserName:"/>
<p:inputText
value="#{loginController.username}" id="username"
required="true" requiredMessage="UserName is required"/>
<h:outputText
value="Password:"/>
<p:password
value="#{loginController.password}" id="password"
required="true" requiredMessage="Password is
required"/>
</p:panelGrid>
<p:spacer height="20px" width="10px"> </p:spacer><p:row ><p:selectBooleanCheckbox label="Remember Me"
id="remember-me" >Remember Me
</p:selectBooleanCheckbox>
<h:outputText value="
" /> </p:row><br></br>
<p:row>
<p:commandButton action="#{loginController.login()}"
value="Login" ajax="false"/> </p:row>
</h:form>
</center>
</body>
</html>
14. crud.xhtml code
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.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:jr="http://jasperreportjsf.sf.net/tld/jasperreports-jsf-1_2.tld"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Employee
Manager</title>
</h:head>
<h:body>
<h:form>
<p:outputLabel value="Welcome Admin
"></p:outputLabel>
<p:outputLabel value="#{loginController.username}"></p:outputLabel>
<h:outputLink
value="#{request.contextPath}/logout">logout</h:outputLink>
</h:form>
<p:spacer
height="1px"></p:spacer>
<center><h2>Employee
Manager</h2></center>
<p:dialog
id="employeeDetail1" widgetVar="$employeeDetail1"
header="Add
Employee"
hideEffect="explode" appendTo="@(body)"
resizable="false"
draggable="false"
closeOnEscape="true">
<h:form>
<p:panelGrid
columns="2">
<h:outputLabel
for="employeefirstname" value="Employee FirstName: *" />
<p:inputText
id="employeefirstname"
value="#{employeeBBean.employee.firstName}"
label="Employee FirstName"
placeholder="Employee FirstName" />
<h:outputLabel
for="employeelastname" value="Employee LastName:"/>
<p:inputText id="employeelastname"
label="Employee LastName"
value="#{employeeBBean.employee.lastName}" placeholder="Employee
LirstName"/>
<h:outputLabel
for="sex" value="Choose Sex"/>
<p:selectOneMenu
id="sex" label="Choose Sex"
value="#{employeeBBean.employee.sex}" effect="fold">
<f:selectItem
itemLabel="Select One" itemValue="" />
<f:selectItem
itemLabel="Male" itemValue="Male"/>
<f:selectItem
itemLabel="Female" itemValue="Female"/>
</p:selectOneMenu>
<p:outputLabel
for="dob" value="Employee Date of Birth"/>
<p:calendar
id="dob" value="#{employeeBBean.employee.dob}"
label="DatePosted:"
required="true"
pattern="dd/MM/yyyy" effect="slideDown"
requiredMessage="Please Enter Date of Birth!"
navigator="true"
showButtonPanel="true" yearRange="c-60:c+60"
placeholder="Date of Birth" />
<h:outputLabel
for="employeesalary" value="Employee Salary:"/>
<p:inputText id="employeesalary"
label="Employee Salary"
value="#{employeeBBean.employee.salary}" placeholder="Employee
Salary"/>
<p:outputLabel
for="remark" value="Remark"/>
<p:inputTextarea
id="remark" label="Remark"
value="#{employeeBBean.employee.remark}"
placeholder="Remark"/>
<p:commandButton
value="add"
process="@form" id="AddButtonId" ajax="true"
icon="ui-icon-plus"
update=":form1:employeeTable"
actionListener="#{employeeBBean.addEmployee()}"
oncomplete="updateTable(),PF('$employeeDetail1').hide()" />
<p:commandButton
id="cancelAddButtonId"
value="Cancel"
onclick="handleComplete(xhr, status, args)"/>
</p:panelGrid>
</h:form>
</p:dialog>
<h:outputScript
id="handleCompleteScript" target="body">
/*
<![CDATA[ */
function
handleComplete(xhr, status, args) {
if(args
&& args.validName) {
$userDetail1.hide();
}
}
/*
]]> */
</h:outputScript>
<p:dialog
id="employeeDetail2" widgetVar="$employeeDetail2"
header="Edit
Employee"
hideEffect="explode" appendTo="@(body)"
resizable="false"
draggable="false"
closeOnEscape="true">
<h:form>
<p:panelGrid
columns="2">
<h:outputLabel
for="employeefirstname" value="Employee FirstName: *" />
<p:inputText
id="employeefirstname"
value="#{employeeBBean.employee.firstName}"
label="Employee FirstName"
placeholder="Employee FirstName" />
<h:outputLabel
for="employeelastname" value="Employee LastName:"/>
<p:inputText id="employeelastname"
label="Employee LastName"
value="#{employeeBBean.employee.lastName}" placeholder="Employee
LirstName"/>
<h:outputLabel
for="sex" value="Choose Sex"/>
<p:selectOneMenu
id="sex" label="Choose Sex"
value="#{employeeBBean.employee.sex}" effect="fold">
<f:selectItem
itemLabel="Select One" itemValue="" />
<f:selectItem
itemLabel="Male" itemValue="Male"/>
<f:selectItem
itemLabel="Female" itemValue="Female"/>
</p:selectOneMenu>
<p:outputLabel
for="dob" value="Employee Date of Birth"/>
<p:calendar
id="dob" value="#{employeeBBean.employee.dob}"
label="DatePosted:"
required="true"
pattern="dd/MM/yyyy" effect="slideDown"
requiredMessage="Please Enter Date of Birth!"
navigator="true"
showButtonPanel="true" yearRange="c-60:c+60"
placeholder="Date of Birth" />
<h:outputLabel for="employeesalary"
value="Employee Salary:"/>
<p:inputText id="employeesalary"
label="Employee Salary"
value="#{employeeBBean.employee.salary}" placeholder="Employee
Salary"/>
<p:outputLabel
for="remark" value="Remark"/>
<p:inputTextarea
id="remark" label="Remark"
value="#{employeeBBean.employee.remark}"
placeholder="Remark"/>
<p:commandButton
value="Update" process="@form"
id="EditButtonId" ajax="true" icon="ui-icon-disk"
update=":form1:employeeTable"
actionListener="#{employeeBBean.updateEmployee()}"
oncomplete="updateTable(),PF('$employeeDetail2').hide()"
/>
<p:commandButton
id="cancelEditButtonId"
value="Cancel"
onclick="handleComplete(xhr, status, args)"/>
</p:panelGrid>
</h:form>
</p:dialog>
<h:outputScript>
</h:outputScript>
<h:outputScript
id="handleCompleteScript" target="body">
/*
<![CDATA[ */
function
handleComplete(xhr, status, args) {
if(args
&& args.validName) {
$userDetail2.hide();
}
}
/*
]]> */
</h:outputScript>
<h:form id="form1">
<center><h3>Employees</h3></center>
<p:toolbar>
<p:toolbarGroup
align="left">
<p:commandButton
icon="ui-icon-plusthick" type="button" id="addEmployeeBtn" value="Add
Employee"
update=":employeeDetail1" ajax="true"
onclick="PF('$employeeDetail1').show()"/>
<p:commandButton
value="Delete" icon="ui-icon-trash" type="button"
onclick="PF('confirmDialog').show()" />
</p:toolbarGroup>
</p:toolbar>
<p:confirmDialog message="Are you
sure you want to delete this record?Record once deleted can not be
retrieved."
header="Deleting"
severity="alert" widgetVar="confirmDialog">
<p:commandButton value="Yes Sure"
update=":form1:employeeTable"
action="#{employeeBBean.deleteEmployee()}"
oncomplete="PF('confirmDialog').hide()"/>
<p:commandButton value="Not Yet"
onclick="PF('confirmDialog').hide();" type="button" />
</p:confirmDialog>
<p:remoteCommand
name="updateTable" update="employeeTable" />
<p:dataTable
value="#{employeeBBean.employeeList}" var="employee"
editable="true" rowKey="#{employee.empId}" selection="#{employeeBBean.selectedEmployees}"
paginator="true" rows="5" id="employeeTable">
<p:column
selectionMode="multiple" headerText="Select"
style="width:6%" />
<p:column
headerText="EmployeeId" style="text-align: left;">
<h:outputText
value="#{employee.empId}"/>
</p:column>
<p:column
filterBy="#{employee.firstName}"
filterOptions=""
filterMatchMode="startsWith" headerText="First
Name">
<h:outputText
value="#{employee.firstName}"/>
</p:column>
<p:column
headerText="Last Name">
<h:outputText
value="#{employee.lastName}"/>
</p:column>
<p:column
headerText="Sex">
<h:outputText
value="#{employee.sex}"/>
</p:column>
<p:column
headerText="Salary">
<h:outputText
value="#{employee.salary}"/>
</p:column>
<p:column
headerText="Date of Birth" >
<h:outputText
value="#{employee.dob}">
<f:convertDateTime
type="date" pattern="dd-MMM-yyyy"/>
</h:outputText>
</p:column>
<p:column
headerText="Remark">
<h:outputText
value="#{employee.remark}"/>
</p:column>
<p:column
headerText="Edit" style="text-align: center">
<p:commandButton
icon="ui-icon-pencil" id="editEmployeeBtn"
value="Edit" ajax="true"
actionListener="#{employeeBBean.changeEmployee(employee)}"
update=":employeeDetail2"
oncomplete="PF('$employeeDetail2').show()"/>
</p:column>
<p:rowExpansion>
<h:outputText
value="#{employee.remark}" styleClass="rowExpansion"/>
</p:rowExpansion>
</p:dataTable>
</h:form>
</h:body>
</html>
15.add.xhtml Code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD
HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.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:p="http://primefaces.org/ui">
<h:head>
<title>Welcome
to Employee Manager</title>
</h:head>
<h:body>
<h:form>
<p:outputLabel value="Welcome User
"></p:outputLabel>
<p:outputLabel
value="#{loginController.username}"></p:outputLabel>
<h:outputLink
value="#{request.contextPath}/logout">logout</h:outputLink>
</h:form>
<p:spacer height="1px"></p:spacer>
<p:messages></p:messages>
<h:form
id="form1">
<table>
<tr>
<td><h:outputLabel
for="firstname" value="FirstName : " /></td>
<td><p:inputText
id="firstname"
value="#{employeeBBean.employee.firstName}">
<f:validateLength
minimum="2" />
<p:ajax
event="blur" update="firstnameMsg" />
</p:inputText>
<p:message id="firstnameMsg" for="firstname"
display="icon" /></td>
</tr>
<tr>
<td><h:outputLabel
for="lastname" value="LastName : " /></td>
<td><p:inputText
id="lastname"
value="#{employeeBBean.employee.lastName}">
<f:validateLength
minimum="2" />
<p:ajax
event="blur" update="lastnameMsg" />
</p:inputText>
<p:message id="lastnameMsg" for="firstname"
display="icon" /></td>
</tr>
<tr>
<td><h:outputLabel
for="sex" value="Choose Sex : " /></td>
<td><p:selectOneMenu label="Sex:"
value="#{employeeBBean.employee.sex}" id="sex">
<f:selectItem itemLabel="Select One" itemValue=""
/>
<f:selectItem
itemLabel="Male" itemValue="Male"/>
<f:selectItem itemLabel="Female"
itemValue="Female"/>
<f:validateLength minimum="2"/>
<p:ajax
event="blur" update="sexMsg" />
</p:selectOneMenu>
<p:message id="sexMsg" for="sex"
display="icon" />
</td>
</tr>
<tr>
<td><h:outputLabel
for="salary" value="Salary: " /></td>
<td><p:inputText
id="salary"
value="#{employeeBBean.employee.salary}">
<f:validateLength
minimum="2" />
<p:ajax
event="blur" update="salaryMsg" />
</p:inputText>
<p:message id="salaryMsg" for="salary"
display="icon" /></td>
</tr>
<tr>
<td><h:outputLabel
for="dob" value="Date of Birth : " /></td>
<td><p>
<p:calendar id="dop"
value="#{employeeBBean.employee.dob}" label="DatePosted:"
required="true"
pattern="dd/MMM/yyyy" effect="slideDown"
requiredMessage="Please Enter Date of Birth!"
navigator="true"
showButtonPanel="true" yearRange="c-60:c+60" />
</p></td>
</tr>
<tr>
<td><h:outputLabel
for="remark" value="Remark : " /></td>
<td><p:inputTextarea
id="remark"
value="#{employeeBBean.employee.remark}">
<f:validateLength
minimum="2" />
<p:ajax
event="blur" update="remarkMsg" />
</p:inputTextarea>
<p:message id="remarkMsg" for="remark"
display="icon" /></td>
</tr>
<tr>
<td><p:commandButton
icon="ui-icon-plusthick" id="addEmployeeBtn"
value="AddEmployee" type="submit" ajax="true"
update=":form1:employeetable"
actionListener="#{employeeBBean.addEmployee()}"
/></td>
<td><p:commandButton
id="reset" value="Reset"
actionListener="#{employeeBBean.reset()}"
ajax="false" /></td>
</tr>
</table>
<center><h3>Employees</h3></center>
<p:dataTable
id="employeetable" var="employee"
paginator="true" rows="5"
value="#{employeeBBean.employeeList}"
style="width:
100%">
<p:column headerText="Id">
<h:outputText
value="#{employee.empId}"/>
</p:column>
<p:column
headerText="First Name">
<h:outputText
value="#{employee.firstName}"/>
</p:column>
<p:column
headerText="Last Name">
<h:outputText
value="#{employee.lastName}"/>
</p:column>
<p:column
headerText="Sex">
<h:outputText
value="#{employee.sex}"/>
</p:column>
<p:column
headerText="Salary">
<h:outputText
value="#{employee.salary}"/>
</p:column>
<p:column
headerText="Date of Birth" >
<h:outputText
value="#{employee.dob}">
<f:convertDateTime
type="date" pattern="dd-MMM-yyyy"/>
</h:outputText>
</p:column>
<p:column
headerText="Remark">
<h:outputText
value="#{employee.remark}"/>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html>
16.
faces-config.xml
It
is created using notepad and below provided code is added to .save as
faces-config.xml.Then copy it and paste to WEB-INF Folder.
CODE:-
<?xml
version="1.0" encoding="UTF-8"?>
<faces-config
version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<!--
JSF and Spring are integrated -->
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
</faces-config>
17. web.xml (Automatically
generated and modified later)
<?xml version="1.0"
encoding="UTF-8"?>
<web-app version="3.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<display-name>Employee Management</display-name>
<!--
JSF Servlet is defined to container -->
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces
Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
Mapping with servlet and url for the http requests. -->
<!-- Map these files with JSF -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<!--
Welcome Page -->
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
18.index.xhtmlàIt is launched first and redirects to login page
<?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>
<head>
<meta http-equiv="refresh"
content="1;URL=View/UnSecured/login.xhtml"></meta>
</head>
<body>
<p>Redirecting Page.Redirecting To Login Page</p>
</body>
</html>
19. JPAConfiguration.javaàIt contains database transaction and connection credential
package
com.ray.webspringsecurity.javaconfig;
import
org.springframework.beans.factory.annotation.Autowired;
import
java.util.Properties;
import
org.springframework.jdbc.datasource.DriverManagerDataSource;
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
import
org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import
org.springframework.orm.jpa.JpaTransactionManager;
import
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import
org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import
org.springframework.transaction.PlatformTransactionManager;
import
org.springframework.transaction.annotation.EnableTransactionManagement;
import
javax.sql.DataSource;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
/**
*
* @author Raichand
*/
@EnableTransactionManagement
@EnableJpaRepositories("com.ray.springdatajpa.dao.repositories")
@Configuration
public
class JPAConfiguration {
@Bean
@Autowired
public
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean
emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan("com.ray.springsecurity.pojos.model");
HibernateJpaVendorAdapter
jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(false);
emf.setJpaVendorAdapter(jpaVendorAdapter);
Properties
jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect",
"org.hibernate.dialect.MySQL5Dialect");
jpaProperties.put("hibernate.hbm2ddl.auto","validate");
jpaProperties.put("hibernate.show_sql","true");
emf.setJpaProperties(jpaProperties);
emf.afterPropertiesSet();
return
emf;
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource
dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/springdatacruddb");
dataSource.setUsername("root");
dataSource.setPassword("");
return
dataSource;
}
@Bean
public
PlatformTransactionManager transactionManager() {
return
new JpaTransactionManager(entityManagerFactory().getObject());
}
}
20.
MyWebSecurityConfiguration.javaàIt
contains SpringsecurityRememberMe credentials
package
com.ray.webspringsecurity.javaconfig;
import
org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.context.annotation.Configuration;
import
org.springframework.context.annotation.Bean;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity;
import
com.ray.security.custom.auth.handler.CustomAuthenticationHandler;
import
org.springframework.security.core.userdetails.UserDetailsService;
import
org.springframework.context.annotation.ComponentScan;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import
org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import
org.springframework.transaction.annotation.EnableTransactionManagement;
import
org.springframework.data.jpa.repository.config.EnableJpaRepositories;
/**
*
* @author Raichand
*/
@EnableWebSecurity
@EnableTransactionManagement
@EnableJpaRepositories("com.ray.springdatajpa.dao.repositories")
@ComponentScan("com.ray.*,com.ray.springsecurity.service.CustomUserDetailsService")
@Configuration
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter{
@Autowired
UserDetailsService
userDetailsService;
@Override
protected void
configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/View/UnSecured/**").permitAll()
.antMatchers("/View/UnSecured/login.xhtml").permitAll()
.antMatchers("/View/Secured/Admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/View/Secured/User/**").access("hasRole('ROLE_USER')")
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/View/UnSecured/login.xhtml")
.failureUrl("/View/UnSecured/login.xhtml?auth=fail")//login
configuration
.usernameParameter("username")
.passwordParameter("password")
.successHandler(customAuthenticationHandler())
.permitAll()
//remember me
configuration
.and().rememberMe()
.useSecureCookie(true)
.useSecureCookie(true)
.key("rem-me-key")//It specifies the key to identify token
.rememberMeParameter("remember-me_input")//id of remember me field
in login form & Primefaces adds '_input' suffix to remember-me parameter
from Login Form
.tokenValiditySeconds(86400)//Specifies the time in seconds after which
token expires.key to identify token keep for one day
.alwaysRemember(false)
.and().logout()
//logout configuration
.logoutSuccessUrl("/index.xhtml")
.invalidateHttpSession(true).deleteCookies("JSESSIONID")
.permitAll()
.and().csrf().disable();
//Permissions here
}
/*
Meaning
of important terminology in above method
authorizedRequests():
It allows restricted access.HTTP requests are authorized before being served.
antMatcher():It
matches the URL with given pattern.
Access():It
checks USER has provoided role.
formLogin():Enables
form based authentication.
loginPage():It
specifies the custom login page URL.
LoginProcessingURL():It
specifies the URL using which username and password is validated
usernameParameter():It
specifies the field name to enter user name which is used by spring security to
validate.If not specified then default is username.
passwordParameter
():It specifies the field name to enter password which is used by spring
security to validate.If not specified then default is password.
defaultSuccessUrl
():It specifies the default URL which is
used by spring security after successful authentication.
logout():It
supports the login functionality in spring security application.
logoutUrl():If
defines the URL for logout.If CSRF protection is enabled,logout request must be
POST.
logoutSuccessUrl
():It specifies the URL which is used by spring security after
successful logout.
configureGlobal
():It configures AuthenticationManager.
*/
/*
Use above USERDETAILSERVICE for Authentication */
@Override
protected
void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new
PlaintextPasswordEncoder());
//auth.authenticationProvider()
can be used in place of userDetailsService above
}
@Bean
public CustomAuthenticationHandler
customAuthenticationHandler(){
return new CustomAuthenticationHandler();
}
}
21. SecurityWebApplicationInitializer.javaàIt
contains springSecurityFilterChain credentials
package
com.ray.webspringsecurity.javaconfig;
import
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
*
* @author Raichand
*/
public
class SecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer{
}
/**
* Above Specified initializer class registers
the springSecurityFilter with application war.
* It is equivalent to below code in XML
Configuration in web.xml
* <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>
**/
22. WebAppInitializer.javaàThis
class launches the index.xhtml web page
when web application starts.
package
com.ray.webspringsecurity.javaconfig;
import
org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
*
* @author Raichand
*/
public
class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[]
getServletConfigClasses(){
return null;
}
@Override
protected String[] getServletMappings(){
return new String[]{"/"};
}
@Override
protected Class<?>[]
getRootConfigClasses(){
return new
Class[]{MyWebSecurityConfiguration.class};
}
}
Login.xhtml page
When user tries to log in with wrong
username or password below page is displayed.
User alex is logging in
add.xhtml
is displayed after user alex has logged
Admin
raichand70 is logging in
pom.xml
Edit
Employee
Employee
Delete
Filtering
First Name Starting with ‘S’
<?xml
version="1.0" encoding="UTF-8"?>
<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.raywebsites</groupId>
<artifactId>PrimefacesSpringsecurityMavenCRUD</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>PrimefacesSpringsecurityMavenCRUD</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--Javax inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!--Java Annotation Indexer -->
<dependency>
<groupId>org.jboss</groupId>
<artifactId>jandex</artifactId>
<version>2.0.3.Final</version>
</dependency>
<!-- aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!--Spring Framework-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!--spring-data-commons -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.13.1.RELEASE</version>
</dependency>
<!-- Spring Data JPA dependencies
-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.0.RELEASE</version>
</dependency>
<!-- aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<!-- querydsl-apt -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.1.4</version>
</dependency>
<!-- Spring Security Libraries
-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.1.3.RELEASE
</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
<version>4.1.3.RELEASE
</version>
</dependency>
<!-- aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<!--Web Dependencies-->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>1.2.2</version>
</dependency>
<!--Java Server Faces-->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.2.7</version>
</dependency>
<!--Primefaces-->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.0</version>
</dependency>
<!--Hibernate-->
<!-- hibernate-entitymanager
-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.10.Final</version>
</dependency>
<!--hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.10.Final</version>
</dependency>
<!-- Database dependencies -->
<!-- MySql Connector -->
<dependency>
<groupId> mysql
</groupId>
<artifactId>
mysql-connector-java </artifactId>
<version> 5.1.35
</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<url>http://repository.primefaces.org/</url>
<id>PrimeFaces-maven-lib</id>
<layout>default</layout>
<name>Repository for library
PrimeFaces-maven-lib</name>
</repository>
</repositories>
</project>
---------------------------------------------------------------------------------------------------
Files of the Project can be downloaded by below URL
https://www.dropbox.com/s/204is6k2mgnqhkq/SpringSecurityPrimefacesCRUD-Java-Configuration.rar?dl=0
---------------------------------------------------------------------------------------------------
Files of the Project can be downloaded by below URL
https://www.dropbox.com/s/204is6k2mgnqhkq/SpringSecurityPrimefacesCRUD-Java-Configuration.rar?dl=0