Project Gitee
address
Blog address
Project requirements
Human resource management system positioning
- The realized human resource management system serves shareholders, employees and interns.
- By realizing the functions of each module, the company's personnel joining, internal transfer and resignation personnel change are carried out through a systematic method, and auxiliary management is provided for these personnel movements.
- To ensure that the right people in the right positions can complete all tasks efficiently and effectively.
User rights and authentication
- The function of this module is to register users and assign permissions, connect the database and shiro to realize user security, and realize user permission grouping combined with thymeleaf shiro.
- JS designs the password length of login to judge whether the user name format is correct.
- After successful login, jump to the home page, or select registration. After successful registration, jump to login.
- Users with different permissions can view different pages and have different operation permissions.
Department management
- In the front end, you need to draw a tree view. When you click a node, all employees under its corresponding department will be displayed.
- Here, the tree view is drawn through the fuel ux Library of the template.
- Get the json string from the back end in the front end as the data source for drawing the tree view, convert it into js object with its parse function in js, and define the callback function during rendering.
- When clicking a node, call a jumptoDepartment function to automatically jump to the corresponding department personnel display page according to the clicked node.
- In the back end, a tree is established to represent the subordinate relationship between departments. A List is used in each node to store the information of sub departments, and its corresponding functions are provided to the front end.
Salary management
- Employee information statistics:
Including basic salary, Department, cumulative overtime hours per month, monthly attendance and leave, etc; And realize the query function, employee information addition function, deletion function, paging function, fuzzy query function and paging query function. - Salary details:
Calculate the employee's bonus, impose a fine and tax amount, and finally settle the salary; And realize the query function, delete function, paging function, fuzzy query function and paging query function.
Attendance management
- The function of this module is to view the attendance status of employees
- The attendance status of employees is divided into: 1: attendance, 2: leave, 3: business trip, 4: overtime, 5: compensatory leave, 6: shift adjustment, 7: shutdown.
- While displaying the status, the page also displays the employee's ID, name, start and end time of the status, and adds comments.
- Add the modification function at the end of each employee table row. Click Modify to jump to the modification page to modify the employee's attendance status, time and comments.
- In addition, the filtering function is added to view employees in this status by selecting attendance status.
Personnel handling
- This module implements the transfer management module, including employee enrollment, employment confirmation, job transfer, salary adjustment, resignation, reinstatement and other businesses.
Publish deploy to server
- The project is finally packaged (jar) and published to the server.
Project design
Login registration
Department management
Salary management
Attendance management
Personnel handling
Database design
Userall
name | type | length | decimal point | Not null | |
---|
user | varchar | 255 | 0 | 1 | key |
password | varchar | 255 | 0 | 1 | |
salt | varchar | 255 | 0 | 0 | |
UserPer (user rights)
name | type | length | decimal point | Not null | |
---|
user | varchar | 255 | 0 | 1 | key |
perms | varchar | 255 | 0 | 0 | |
department
name | type | length | decimal point | Not null | |
---|
department | varchar | 255 | 0 | 1 | |
d_id | int | 255 | 0 | 1 | key |
parid | int | 255 | 0 | 0 | |
Employees (all employees)
name | type | length | decimal point | Not null | |
---|
id | int | 11 | 0 | 1 | key |
name | varchar | 255 | 0 | 1 | |
age | int | 11 | 0 | 1 | |
sex | varchar | 2 | 0 | 1 | |
phone | varchar | 255 | 0 | 0 | |
email | varchar | 255 | 0 | 0 | |
dName | varchar | 255 | 0 | 1 | |
pName | varchar | 255 | 0 | 1 | |
gName | varchar | 255 | 0 | 1 | |
flag | bit | 1 | 0 | 1 | |
gangwei (post)
name | type | length | decimal point | Not null | |
---|
name | varchar | 255 | 0 | 0 | |
g_id | int | 255 | 0 | 1 | key |
kaoqin (attendance)
name | type | length | decimal point | Not null | |
---|
id | int | 11 | 0 | 1 | key |
name | varchar | 255 | 0 | 0 | |
type | int | 11 | 0 | 1 | |
start | date | 0 | 0 | 0 | |
end | date | 0 | 0 | 1 | |
remark | varchar | 255 | 0 | 0 | |
position
name | type | length | decimal point | Not null | |
---|
position | varchar | 255 | 0 | 1 | |
p_id | int | 255 | 0 | 1 | key |
level | int | 255 | 0 | 0 | |
Salary (salary)
name | type | length | decimal point | Not null | |
---|
time | varchar | 255 | 0 | 0 | |
gid | int | 11 | 0 | 1 | key |
pid | int | 11 | 0 | 1 | |
username | varchar | 255 | 0 | 0 | |
basicSalary | int | 11 | 0 | 1 | |
dname | varchar | 255 | 0 | 0 | |
workovertime | int | 11 | 0 | 1 | |
checkaccout | int | 11 | 0 | 1 | |
Project core code
detailed design
Login and registration
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String indexPage(String username, String password, Map<String, Object> map, HttpSession session, HttpServletRequest request, Model model) {
/**
* Write the operation of authentication using shiro
*/
//1. Get Subject
Subject subject = SecurityUtils.getSubject();
//2. Encapsulate user data
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
//3. Execute login method
subject.login(token);
model.addAttribute("username", username);
session.setAttribute("username", username);
return "index";
} catch (UnknownAccountException e) {
//Login failed, wrong user name
model.addAttribute("msg", "User name does not exist!");
return "login";
} catch (IncorrectCredentialsException e) {
//Login failed, password error
model.addAttribute("msg", "Wrong user name or password!");
return "login";
}
}
@RequestMapping(value = "/login")
public String regPageToLogin(String username, String password, Map<String, Object> map, HttpSession session, Model model) {
Userall userall = new Userall(username, password);
if (username == null || password == null) {
return "reg";
}
if (password.length() < 4 || password.length() > 10) {
return "reg";
}
Userall userall1 = userCheckServiceImpl.selectByKeyName(username);
if (userall1 != null) {
map.put("error", "repeat of user name");
return "reg";
}
try {
Integer id = Integer.parseInt(username);
boolean flag = userCheckServiceImpl.insert(username, password);
if (flag) {
//Set user permissions
String role = employServiceImpl.getRole(Integer.parseInt(username));
userCheckServiceImpl.insertUserPer(username, role);
return "login";
} else {
Userall usercheck = userCheckServiceImpl.selectByNameAndPassword(username, password);
if (usercheck == null) {
return "reg";
} else {
return "login";
}
}
} catch (Exception e) {
map.put("error", "The user name does not conform to the number format");
return "reg";
}
}
/**
* Execute authentication logic
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("Perform certification: Authentiction");
//Assume the user name and password of the database
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
Userall user = userCheckService.selectByKeyName(token.getUsername());
String DBPassword = user.getPassword();
String Salt = user.getSalt();
System.out.println(Salt);
return new SimpleAuthenticationInfo(user,DBPassword, ByteSource.Util.bytes(Salt),"");
}
@Override
public boolean insert(String username, String password) {
String Salt = new SecureRandomNumberGenerator().nextBytes().toHex();
//encryption
SimpleHash simpleHash = new SimpleHash("md5",password,Salt,1);
String NewPassword = simpleHash.toString();
//System.out.println(password);
userallMapper.insert(username,NewPassword,Salt);
return true;
}
<div class="container">
<form class="form-signin" action="/index" id = "signForm">
<div class="form-signin-heading text-center">
<h1 class="sign-title">Sign in</h1>
<img src="../static/images/login-top.png" alt=""/>
</div>
<div class="login-wrap">
<input type="text" class="form-control" placeholder="User ID" autofocus name="username" id = "username" required="required">
<input type="password" class="form-control" placeholder="Password" name="password" id = "password" required="required"><p class="message">Please enter 4~10 Bit cipher</p>
<script>
var password = document.querySelector('.form-control');
var message = document.querySelector('.message');
password.onblur = function() {
if (this.value.length < 4 || this.value.length > 10) {
message.innerHTML = 'Password length error, expected 4~10 position';
message.className = 'message wrong';
} else {
message.innerHTML = 'The password length is correct';
message.className = 'message right';
}
}
</script>
<button class="btn btn-lg btn-login btn-block" type="submit" onclick="mycheck()" >
<i class="fa fa-check"></i>
</button>
<div class="registration">
<a class="" href="/reg">
register
</a>
</div>
</div>
</form>
</div>
<div class="login-wrap">
<input type="text" autofocus="" placeholder="Enter number, intern please enter 0" class="form-control" name="username" required="required" id="username">
<input type="password" autofocus="" placeholder="password" class="form-control" name="password" required="required" id="password"><p class="message">Please enter 4~10 Bit cipher</p>
<p th:text="${error}" color="red"></p>
<script>
var password = document.querySelector('.form-control');
var message = document.querySelector('.message');
password.onblur = function() {
if (this.value.length < 4 || this.value.length > 10) {
message.innerHTML = 'Password length error, expected 4~10 position';
message.className = 'message wrong';
} else {
message.innerHTML = 'The password length is correct';
message.className = 'message right';
}
}
</script>
<button type="submit" class="btn btn-lg btn-login btn-block" onclick="mycheck()">
<i class="fa fa-check"></i>
</button>
<div class="registration">
Already Registered.
<a href="login.html" class="">
Login
</a>
</div>
</div>
Department management
Controller layer
Service layer
@Service
public class departmentTree {
private Department department;
private List<departmentTree> children;
departmentTree() {
}
departmentTree(DepartmentMapper departmentMapper, int id) {
department = departmentMapper.getById(id);
department.setdId(id);
children = new ArrayList<departmentTree>();
for (int childrenId : departmentMapper.geIdtByParId(id)) {
children.add(new departmentTree(departmentMapper, childrenId));
}
}
// Get all employees under this node
ArrayList<Employees> getAllEmployee(EmployeesMapper employeesMapper) {
ArrayList<Employees> ans = employeesMapper.getBydName(department.getDepartment());
for (departmentTree tmp : children) {
ans.addAll(tmp.getAllEmployee(employeesMapper));
}
return ans;
}
Department getDepartment() {
return department;
}
public List<departmentTree> getChildren() {
return children;
}
}
@Service
public class departmentTool implements departmantToolService {
@Autowired
DepartmentMapper departmentMapper;
@Autowired
EmployeesMapper employeesMapper;
private String getJSONByNode(departmentTree node) {
JSONObject JSON = new JSONObject();
// Gets all values under the node
String ch = null;
for (departmentTree son : node.getChildren()) {
if (ch == null)
ch = getJSONByNode(son);
else
ch = ch + "," + getJSONByNode(son);
}
return "{" + "\"name\": \"" + node.getDepartment().getDepartment()
+ "\" ,\"type\": \"" + (node.getChildren().size() != 0 ? "folder" : "item")
+ "\" ,\"id\": " + node.getDepartment().getdId()
+ " ,\"children\": " + "[" + (ch == null ? "" : ch) + "]"
+ "}";
}
// Get root node
@Override
public departmentTree getRoot() {
return new departmentTree(departmentMapper, 0);
}
// Get JSON
@Override
public String getJSON() {
// JSONObject JSON = new JSONObject();
return "[" + getJSONByNode(new departmentTree(departmentMapper, 0)) + "]";
}
// Find all employees in a department according to their id
@Override
public ArrayList<Employees> getEmployeeById(int id) {
return (new departmentTree(departmentMapper, id)).getAllEmployee(employeesMapper);
}
}
Mapper layer
@Mapper
public interface DepartmentMapper {
int deleteByPrimaryKey(Integer dId);
int insert(Department record);
int insertSelective(Department record);
Department selectByPrimaryKey(Integer dId);
int updateByPrimaryKeySelective(Department record);
int updateByPrimaryKey(Department record);
@Select("select * from department where d_id = #{id} ")
Department getById(int id);
@Select("select d_id from department where parid = #{id} ")
List<Integer> geIdtByParId(int id); // Find the IDs of all child nodes through the parent node
@Select("select * from department")
List<Department> getAll();
}
@Mapper
public interface EmployeesMapper {
int deleteByPrimaryKey(Integer id);
int insert(Employees record);
int insertSelective(Employees record);
Employees selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Employees record);
int updateByPrimaryKey(Employees record);
@Select("select * from employees")
List<Employees> getAll();
@Select("select * from employees where dName = #{dName} ")
ArrayList<Employees> getBydName(String dName);
}
Front end HTML & JS
var DMPTree = function () {
return {
//main function to initiate the module
init: function () {
var DataSourceTree = function (options) {
this._data = options.data;
this._delay = options.delay;
};
DataSourceTree.prototype = {
data: function (options, callback) {
var nodes;
if($.isEmptyObject(options)) {
nodes = this._data;
}
else {
if(options.children == null || options.children == undefined) {
nodes = {};
}
else {
nodes = options.children;
}
}
setTimeout(function () {
callback({ data: nodes });
}, this._delay)
}
};
var treeDataSourceDynamicStr = $("#dataTreeSrc").val();
var treeDataSourceDynamic = JSON.parse(treeDataSourceDynamicStr);
var deparmentTreeSrc = new DataSourceTree({
data: treeDataSourceDynamic,
delay: 400
});
$('#DepartmentTree').tree({
dataSource: deparmentTreeSrc,
loadingHTML: '<img src="../static/images/input-spinner.gif"/>'
});
}
};
}();
Front end management jump function:
<script>
function jumpToDepartment() {
var dmpid = ($('#DepartmentTree').tree('selectedItems')[0]).id;
window.location.href = "/index/department/" + dmpid;
}
</script>
HTML Receive backend incoming json character string:
<input type="hidden" id="dataTreeSrc" th:value="${treeDataSrc}">
Salary management
Controller layer
@RequestMapping("/index/salary_search")
public String salary_select(Model model,String username,
@RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum,
@RequestParam(defaultValue="5",value="pageSize")Integer pageSize){
if(pageNum==null || pageNum<=0){
pageNum = 1;
}
if(pageSize == null){
pageSize = 1;
}
PageHelper.startPage(pageNum,pageSize);
try {
List<Salary> users=salaryServiceImpl.findUserByName(username);
PageInfo<Salary> pageInfo = new PageInfo<Salary>(users,pageSize);
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("salary",users);
model.addAttribute("username",username);
}finally {
}
return "salary_search";
@GetMapping("/index/salary_delete/{id}")
public String salary_delete(@PathVariable Integer id){
salaryServiceImpl.salary_delete(id);
return "redirect:/index/salary";
}
@RequestMapping("/index/salary_insert")
public String insertPage(){
return "salary_insert";
}
@RequestMapping("/index/salaryBack")
public String insert(Salary salary) {
salaryServiceImpl.add(salary);
return "redirect:/index/salary_control";
}
Service layer
List<Salary> getSalary();
int salary_delete(Integer id);
List<Salary> findUserByName(String username);
void add(Salary salary);
int update(Salary salary);
Mapper layer
@Select("select * from salary")
List<Salary> getSalary();
@Select("select * from kaoqin")
List<Salary> getKaqqinInformation();
/*
delete user
*/
@Delete("delete from salary\n" +
" where gid = #{gid,jdbcType=INTEGER}")
int salary_delete(Integer gid);
/*
Query user information
*/
@Select("select * from salary where username like CONCAT('%',#{name},'%')")
List<Salary> findUserByName(String username);
@Insert("insert into salary (`time`, pid, username, \n" +
" basicSalary, dname, workovertime, \n" +
" checkaccount)\n" +
" values (#{time,jdbcType=VARCHAR}, #{pid,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, \n" +
" #{basicsalary,jdbcType=INTEGER}, #{dname,jdbcType=VARCHAR}, #{workovertime,jdbcType=INTEGER}, \n" +
" #{checkaccount,jdbcType=INTEGER})")
void add(Salary user);
Attendance management
Controller layer
@RequestMapping("/index/employee_table2")
public String KaoqinList(Model model,
@RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum,
@RequestParam(defaultValue="10",value="pageSize")Integer pageSize){
//For the sake of the preciseness of the procedure, judge whether it is not empty:
//Set default current page
if(pageNum==null || pageNum<=0){
pageNum = 1;
}
//Sets the default number of data displayed per page
if(pageSize == null){
pageSize = 1;
}
// System.out.println("current page is:" + pageNum + "display number is:" + PageSize ");
//1. Introduce the paging plug-in. pageNum is the page number, pageSize is the number of items displayed on each page, and the default total number of queries is count
PageHelper.startPage(pageNum,pageSize);
//2. The following query is a paging query - it must be followed Other subsequent queries will not be paged unless PageHelper is called again startPage
List<Kaoqin> kaoqins = kaoqinServiceImpl.kaoqinList();
//3. Use PageInfo to wrap the query results. 5 is the number of continuously displayed items, and the result list type is page < E >
PageInfo<Kaoqin> pageInfo = new PageInfo<Kaoqin>(kaoqins,pageSize);
//4. Use model to send parameters back to the front end
model.addAttribute("pageInfo",pageInfo);
model.addAttribute("kaoqins",kaoqins);
return "kaoqin_table";
}
//Find by attendance type
@RequestMapping("/find")
public String find(Integer type, Model model){
List<Kaoqin> kaoqins = kaoqinServiceImpl.findKaoqin(type);
model.addAttribute("kaoqins",kaoqins);
System.out.println(type);
return "kaoqin_table";
}
//Update attendance content according to id
@GetMapping("/update/{id}")
public String update(Model model, @PathVariable int id){
Kaoqin kaoqin = kaoqinServiceImpl.findKaoqinById(id);
model.addAttribute("kaoqin",kaoqin);
return "updateKaoqin";
}
//Update attendance
@PostMapping("/update")
public String updateKaoqin(Kaoqin kaoqin){
kaoqinServiceImpl.updateKaoqin(kaoqin);
return "redirect:/index/employee_table2";
}
Service layer
@Autowired
KaoqinMapper kaoqinMapper;
@Override
public List<Kaoqin> kaoqinList(){
return kaoqinMapper.kaoqinList();
}
@Override
public List<Kaoqin> findKaoqin(Integer type){
return kaoqinMapper.findKaoqin(type);
}
@Override
public Kaoqin findKaoqinById(int id){
return kaoqinMapper.findKaoqinById(id);
}
@Override
public int updateKaoqin(Kaoqin kaoqin){
return kaoqinMapper.updateKaoqin(kaoqin);
}
List<Kaoqin> kaoqinList();
List<Kaoqin> findKaoqin(Integer type);
Kaoqin findKaoqinById(int id);
int updateKaoqin(Kaoqin kaoqin);
Mapper layer
@Select("select * from kaoqin")
List<Kaoqin> kaoqinList();
@Select("select * from kaoqin where type = #{type}")
List<Kaoqin> findKaoqin(Integer type);
@Select("select * from kaoqin where id = #{id}")
Kaoqin findKaoqinById(int id);
@Update("update kaoqin set type = #{type}, start = #{start}, end = #{end}, remark = #{remark} where id = #{id}")
int updateKaoqin(Kaoqin kaoqin);
Personnel handling
Controller layer
public String employeeListPage(Model model, @RequestParam(defaultValue = "1") Integer pageNum) {
PageHelper.startPage(pageNum, 5);
List<Employees> list = employServiceImpl.getAll();
PageInfo<Employees> pageInfo = new PageInfo<Employees>(list);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("employee", list);
return "employee_table";
}
@RequestMapping(value = "/index/addEmployee")
public String addStus(String name,int age,String sex,
String dname,String pname,String gname,boolean flag,int id,String email,String phone,
@RequestParam(defaultValue = "1") Integer pageNum,
Model model) {
Employees employees = new Employees(name,age,sex,dname,pname,gname,email,phone,id,flag);
try {
employServiceImpl.addEmployees(employees);
}catch (Exception e){
return "addStu";
}
return "index";
}
@RequestMapping(value = "/index/delEmployee")
public String delEmployee(String name,int age,String sex,
String dname,String pname,String gname,boolean flag,int id,String email,String phone) {
Employees employees = new Employees(name,age,sex,dname,pname,gname,email,phone,id,flag);
employServiceImpl.delEmployees(employees);
return "delSuccess";
}
Sevice layer
EmployeesMapper employeesMapper;
@Override
public void addEmployees(Employees employees) {
employeesMapper.save(employees);
}
@Override
public void delEmployees(Employees employees) {
employeesMapper.delete(employees);
}
@Override
public List<Employees> getAll() {
return employeesMapper.getAll();
}
Mapper layer
@Select("select * from employees")
List<Employees> getAll();
@Delete("DELETE from employees where name = #{name} and age = #{age} and sex = #{sex} and id = #{id} ")
void delete(Employees employee);
@Insert("INSERT INTO employees VALUES(#{id},#{name},#{age},#{sex},#{phone},#{email},#{dname},#{pname},#{gname},#{flag})")
void save(Employees employee);
User rights grouping
shiroConfiguration
@Configuration
public class ShiroConfiguration {
/**
* LifecycleBeanPostProcessor,This is a subclass of DestructionAwareBeanPostProcessor,
* Responsible for org apache. shiro. util. Initializable type bean's life cycle, initialization and destruction.
* It is mainly a subclass of the AuthorizingRealm class and the EhCacheManager class.
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* HashedCredentialsMatcher,This class is used to encode passwords,
* Prevent the password from being saved in the database. Of course, when logging in for authentication,
* This class is also responsible for encoding the password entered in the form.
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");
return hashedCredentialsMatcher;
}
/**
* ShiroRealm,This is a user-defined authentication class, which inherits from authoringrealm,
* Responsible for user authentication and authority processing, you can refer to the implementation of JdbcRealm.
*/
@Bean(name = "shiroRealm")
@DependsOn("lifecycleBeanPostProcessor")
public ShiroRealm shiroRealm() {
ShiroRealm realm = new ShiroRealm();
realm.setCredentialsMatcher(hashedCredentialsMatcher());
return realm;
}
/**
* SecurityManager,Permission management, which combines login, logout, permission and session processing, is an important class.
* //
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
return securityManager;
}
/**
* ShiroFilterFactoryBean,It is a factorybean to generate ShiroFilter.
* It mainly maintains three data items: securityManager, filters and filterChainDefinitionManager.
*/
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
Map<String, Filter> filters = new LinkedHashMap<String, Filter>();
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/login");
shiroFilterFactoryBean.setFilters(filters);
Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();
//Sign in
// Add shiro's built-in filter
/**
* anon: Access without authentication
* authc: Must be authenticated to access
* user: You must have the remember me function to use
* perms: You must have permission on a resource to access it
* role: Only with the permission of a role can you access
*/
filterChainDefinitionManager.put("/login","anon");
filterChainDefinitionManager.put("/logout", "anon");
filterChainDefinitionManager.put("/index","anon");
filterChainDefinitionManager.put("/index/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);
shiroFilterFactoryBean.setLoginUrl("/");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
return shiroFilterFactoryBean;
}
/**
* DefaultAdvisorAutoProxyCreator,Spring The Advisor decides which class methods to AOP proxy.
*/
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
/**
* AuthorizationAttributeSourceAdvisor,shiro Advisor class implemented in,
* AOP alliance annotations authoring method interceptor is used internally to intercept methods annotated below.
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();
aASA.setSecurityManager(securityManager());
return aASA;
}
/**
* Configure shiroDialect for thymeleaf and
* @return
*/
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
}
shiroRealm
public class ShiroRealm extends AuthorizingRealm {
@Autowired
userCheckServiceImpl userCheckService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("Execution authorization: Authorization");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
Userall userall = (Userall)subject.getPrincipal();
String role = userCheckService.getUserPer(userall.getUser());
System.out.println(role);
info.addStringPermission(role);
return info;
}
/**
* Execute authentication logic
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("Perform certification: Authentiction");
//Assume the user name and password of the database
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
Userall user = userCheckService.selectByKeyName(token.getUsername());
String DBPassword = user.getPassword();
String Salt = user.getSalt();
System.out.println(Salt);
return new SimpleAuthenticationInfo(user,DBPassword, ByteSource.Util.bytes(Salt),"");
}
}
thymeleaf+shiro
<li class="menu-list nav-active" shiro:hasAnyPermissions="boss,deputy,fudeputy,staff">
<a href="#"> < I class =" Fa FA th list "> < / I > < span > personnel archiving < / span ></a>
<ul class="sub-menu-list">
<li class="active"><a href="/index/employee_table">Personnel filing</a></li>
<li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
<a href="/index/addStu">Employee induction</a>
</li>
<li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
<a href="/index/delStu">Employee turnover</a>
</li>
</ul>
</li>
Project deployment
Deployment URL