我使用spring boot和security创建一个简单的登录页面。 但是在创建用户之后,当我尝试登录时,我看到实体" staff"是null因此产生错误无效登录。
SecurityConfig.java
package com.ridzuan.service.StaffServiceImpl;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ridzuan.dao.RoleDao;
import com.ridzuan.dao.StaffDao;
import com.ridzuan.domain.Staff;
import com.ridzuan.domain.security.StaffRole;
import com.ridzuan.service.StaffService;
@Service
public class StaffServiceImpl implements StaffService{
private static final Logger LOG = LoggerFactory.getLogger(StaffService.class);
@Autowired
private StaffDao staffDao;
@Autowired
private RoleDao roleDao;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public void save(Staff staff) {
staffDao.save(staff);
}
public Staff findByNric(String nric) {
return staffDao.findByNric(nric);
}
public boolean checkStaffExists(String nric) {
if (findByNric(nric) != null) return true;
else return false;
}
@Transactional
public Staff createStaff(Staff staff, Set<StaffRole> staffRoles) {
Staff localStaff = staffDao.findByNric(staff.getNric());
if(localStaff != null) {
LOG.info("Staff with nric {} already exist.", staff.getNric());
}else {
String encryptedPassword = passwordEncoder.encode(staff.getPassword());
staff.setPassword(encryptedPassword);
for(StaffRole sr : staffRoles) {
roleDao.save(sr.getRole());
}
staff.getStaffRoles().addAll(staffRoles);
localStaff = staffDao.save(staff);
}
return localStaff;
}
}
HomeController.java
package com.ridzuan.controller;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.ridzuan.dao.RoleDao;
import com.ridzuan.domain.Staff;
import com.ridzuan.domain.security.StaffRole;
import com.ridzuan.service.StaffService;
@Controller
public class HomeController {
@Autowired
public StaffService staffService;
@Autowired
private RoleDao roleDao;
@RequestMapping("/")
public String home() {
return "redirect:/index";
}
@RequestMapping("/index")
public String index() {
return "index";
}
@RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(Model model) {
Staff staff = new Staff();
model.addAttribute("staff", staff);
return "register";
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerPost(@ModelAttribute("staff") Staff staff, Model model) {
if(staffService.checkStaffExists(staff.getNric())) {
model.addAttribute("staffExists", true);
return "register";
}else {
Set <StaffRole> staffRoles = new HashSet<>();
staffRoles.add(new StaffRole(staff, roleDao.findByName("ROLE_STAFF")));
staffService.createStaff(staff, staffRoles);
return "redirect:/";
}
}
}
RoleDao.java
package com.ridzuan.dao;
import org.springframework.data.repository.CrudRepository;
import com.ridzuan.domain.security.Role;
public interface RoleDao extends CrudRepository<Role, Integer>{
Role findByName(String name);
}
StaffDao.java
package com.ridzuan.dao;
import org.springframework.data.repository.CrudRepository;
import com.ridzuan.domain.Staff;
public interface StaffDao extends CrudRepository<Staff, Long>{
Staff findByNric(String nric);
}
Authority.java
package com.ridzuan.domain.security;
import org.springframework.security.core.GrantedAuthority;
/**
* Created by z00382545 on 10/20/16.
*/
public class Authority implements GrantedAuthority{
private final String authority;
public Authority(String authority) {
this.authority = authority;
}
@Override
public String getAuthority() {
return authority;
}
}
Role.java
package com.ridzuan.domain.security;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/**
* Created by z00382545 on 10/20/16.
*/
@Entity
public class Role {
@Id
// @GeneratedValue(strategy = GenerationType.AUTO)
private int roleId;
private String name;
@OneToMany(mappedBy = "role", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<StaffRole> staffRoles = new HashSet<>();
public Role() {
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<StaffRole> getStaffRoles() {
return staffRoles;
}
public void setStaffRoles(Set<StaffRole> staffRoles) {
this.staffRoles = staffRoles;
}
}
StaffRole.java
package com.ridzuan.domain.security;
import com.ridzuan.domain.Staff;
import javax.persistence.*;
/**
* Created by z00382545 on 10/20/16.
*/
@Entity
@Table(name="staff_role")
public class StaffRole {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long staffRoleId;
public StaffRole(Staff staff, Role role) {
this.staff = staff;
this.role = role;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "userId")
private Staff staff;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "roleId")
private Role role;
public StaffRole() {}
public long getStaffRoleId() {
return staffRoleId;
}
public void setStaffRoleId(long staffRoleId) {
this.staffRoleId = staffRoleId;
}
public Staff getStaff() {
return staff;
}
public void setStaff(Staff staff) {
this.staff = staff;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
Off.java
package com.ridzuan.domain;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Off {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long idOff;
private Date startDate;
private Date endDate;
private String remarks;
private boolean isApproved;
@ManyToOne
@JoinColumn(name = "userId")
private Staff staff;
public long getIdOff() {
return idOff;
}
public void setId(long idOff) {
this.idOff = idOff;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public boolean isApproved() {
return isApproved;
}
public void setApproved(boolean isApproved) {
this.isApproved = isApproved;
}
@Override
public String toString() {
return "Leave [idOff=" + idOff + ", startDate=" + startDate + ", endDate=" + endDate + ", remarks=" + remarks
+ ", isApproved=" + isApproved + "]";
}
}
Staff.java
package com.ridzuan.domain;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ridzuan.domain.security.Authority;
import com.ridzuan.domain.security.StaffRole;
@Entity
public class Staff implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "userId", nullable = false, updatable = false)
private long userId;
private String nric;
private int phone;
private String password;
private boolean isActive = true;
@OneToMany(mappedBy = "staff", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JsonIgnore
private List<Off> offList;
@OneToMany(mappedBy = "staff", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonIgnore
private Set<StaffRole> staffRoles = new HashSet<>();
public Set<StaffRole> getStaffRoles() {
return staffRoles;
}
public void setStaffRoles(Set<StaffRole> staffRoles) {
this.staffRoles = staffRoles;
}
public String getNric() {
return nric;
}
public void setNric(String nric) {
this.nric = nric;
}
public long getUserId() {
return userId;
}
public List<Off> getOffList() {
return offList;
}
public void setOffList(List<Off> offList) {
this.offList = offList;
}
public void setUserId(long userId) {
this.userId = userId;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
this.phone = phone;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean isActive) {
this.isActive = isActive;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
staffRoles.forEach(sr -> authorities.add(new Authority(sr.getRole().getName())));
return authorities;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return false;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return null;
}
}
StaffSecurityService.java
package com.ridzuan.service.StaffServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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 com.ridzuan.dao.StaffDao;
import com.ridzuan.domain.Staff;
@Service
public class StaffSecurityService implements UserDetailsService {
private static final Logger LOG = LoggerFactory.getLogger(StaffSecurityService.class);
@Autowired
private StaffDao staffDao;
@Override
public UserDetails loadUserByUsername(String nric) throws UsernameNotFoundException {
Staff staff = staffDao.findByNric(nric);
LOG.info("NRIC {}, nric");
if(null == staff) {
LOG.warn("NRIC {} not found", nric);
throw new UsernameNotFoundException("NRIC: " + nric + " not found!");
}
return staff;
}
}
StaffServiceImpl.java
package com.ridzuan.service.StaffServiceImpl;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ridzuan.dao.RoleDao;
import com.ridzuan.dao.StaffDao;
import com.ridzuan.domain.Staff;
import com.ridzuan.domain.security.StaffRole;
import com.ridzuan.service.StaffService;
@Service
public class StaffServiceImpl implements StaffService{
private static final Logger LOG = LoggerFactory.getLogger(StaffService.class);
@Autowired
private StaffDao staffDao;
@Autowired
private RoleDao roleDao;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public void save(Staff staff) {
staffDao.save(staff);
}
public Staff findByNric(String nric) {
return staffDao.findByNric(nric);
}
public boolean checkStaffExists(String nric) {
if (findByNric(nric) != null) return true;
else return false;
}
@Transactional
public Staff createStaff(Staff staff, Set<StaffRole> staffRoles) {
Staff localStaff = staffDao.findByNric(staff.getNric());
if(localStaff != null) {
LOG.info("Staff with nric {} already exist.", staff.getNric());
}else {
String encryptedPassword = passwordEncoder.encode(staff.getPassword());
staff.setPassword(encryptedPassword);
for(StaffRole sr : staffRoles) {
roleDao.save(sr.getRole());
}
staff.getStaffRoles().addAll(staffRoles);
localStaff = staffDao.save(staff);
}
return localStaff;
}
}
StaffService.java
package com.ridzuan.service;
import java.util.Set;
import com.ridzuan.domain.Staff;
import com.ridzuan.domain.security.StaffRole;
public interface StaffService {
void save(Staff staff);
Staff findByNric(String nric);
boolean checkStaffExists(String nric);
Staff createStaff(Staff staff, Set<StaffRole> staffRole);
}
的index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head th:replace="common/header :: common-header"/>
<body>
<!-- Login Section -->
<div class="container">
<div class="row ">
<div class="main-center ">
<div class="bg-danger" th:if="${param.error}">
Invalid username and password.
</div>
<div class="bg-danger" th:if="${param.logout}">
You have been logged out.
</div>
<form class="form-signin" th:action="@{/index}" method="post">
<h2 class="form-signin-heading">Please sign in</h2>
<div class="form-group">
<label for="nric" class="sr-only">NRIC</label>
<input type="text" roleId="nric" class="form-control" placeholder="NRIC" name="nric"
id="nric"
required="required" autofocus="autofocus"/>
</div>
<div class="form-group">
<label for="password" class="sr-only">Password</label>
<input type="password" roleId="inputPassword" class="form-control" placeholder="Password"
id="password"
name="password" required="required"/>
</div>
<div class="form-group">
<input type="checkbox" name="remember-me" id="remember-me"/> Remember me
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
<hr />
</div>
</div>
</div>
<div th:replace="common/header :: body-bottom-scripts"/>
我在StaffSecurityService.java中插入一个日志。控制台打印出来
Hibernate: select staff0_.user_id as user_id1_2_, staff0_.is_active as is_activ2_2_, staff0_.nric as nric3_2_, staff0_.password as password4_2_, staff0_.phone as phone5_2_ from staff staff0_ where staff0_.nric=?
2017-09-19 23:54:11.377 INFO 30313 --- [nio-8080-exec-7] c.r.s.S.StaffSecurityService : NRIC {}, nric
2017-09-19 23:54:11.377 WARN 30313 --- [nio-8080-exec-7] c.r.s.S.StaffSecurityService : NRIC not found
我在StaffSecurityService.java中插入了一个断点loadUserByUsername方法,并且人员为空。
请帮助,我真的卡住了。提前谢谢。