Spring Boot UserDetails返回null

时间:2017-09-19 15:37:45

标签: spring-boot spring-security

我使用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"/> &nbsp; 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方法,并且人员为空。

请帮助,我真的卡住了。提前谢谢。

0 个答案:

没有答案