JavaWeb-SpringSecurity在数据库中查询登录用户

 

 

  系列博文html

  项目已上传至guthub  传送门java

  JavaWeb-SpringSecurity初认识  传送门mysql

  JavaWeb-SpringSecurity在数据库中查询登录用户  传送门git

  JavaWeb-SpringSecurity自定义登录页面  传送门github

  JavaWeb-SpringSecurity实现需求-判断请求是否以html结尾  传送门web

  JavaWeb-SpringSecurity自定义登录配置  传送门spring

  JavaWeb-SpringSecurity图片验证ImageCode  传送门sql

  JavaWeb-SpringSecurity记住我功能  传送门数据库

  JavaWeb-SpringSecurity使用短信验证码登录  传送门安全

 

 

  在MySQL数据库中建立springsecurity数据库

  

 

 

   (id、username、password都是根据User.java映射过来的)

 

  在application.properties中编写配置文件

#datasource
spring.datasource.url=jdbc:mysql:///springsecurity?serverTimezone=UTC&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.dricer-class-name=com.mysql.jdbc.Driver #jpa #打印出数据库语句
spring.jpa.show-sql=true
#更新数据库表
spring.jpa.hibernate.ddl-auto=update

 

  建立domain实体层User.java和repository存储层接口UserRepository.java  

  书写用户User.java实体

//用户是否没有失效
 @Transient private boolean accountNonExpried; //用户是否冻结
 @Transient private boolean accountNonLocked; //证实是否过时
 @Transient private boolean credentialsNonExpired; //判断是否删除
 @Transient private boolean enabled; @Transient //添加 @Transient 注解能够不将 Set<GrantedAuthority>映射到数据库表上
    private Set<GrantedAuthority> authorities; //给hibernatre用的构造方法
    protected User() { } public User(Long id,String username,String password) { this.id = id; this.username = username; this.password = password; } //给SpringSecurity用的构造方法
    public User(String username,String password, Collection<? extends GrantedAuthority> authorities) { this(username,password,true,true,true,true,authorities); } public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) { if (((username == null) || "".equals(username)) || (password == null)) { throw new IllegalArgumentException( "Cannot pass null or empty values to constructor"); } this.username = username; this.password = password; this.enabled = enabled; this.accountNonExpried = accountNonExpired; this.credentialsNonExpired = credentialsNonExpired; this.accountNonLocked = accountNonLocked; this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); } private static SortedSet<GrantedAuthority> sortAuthorities( Collection<? extends GrantedAuthority> authorities) { Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection"); // Ensure array iteration order is predictable (as per // UserDetails.getAuthorities() contract and SEC-717)
        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<>( new AuthorityComparator()); for (GrantedAuthority grantedAuthority : authorities) { Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements"); sortedAuthorities.add(grantedAuthority); } return sortedAuthorities; } private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; public int compare(GrantedAuthority g1, GrantedAuthority g2) { // Neither should ever be null as each entry is checked before adding it to // the set. // If the authority is null, it is a custom authority and should precede // others.
    if (g2.getAuthority() == null) { return -1; } if (g1.getAuthority() == null) { return 1; } return g1.getAuthority().compareTo(g2.getAuthority()); } }

 

package com.Gary.GaryRESTful.domain; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Transient; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.util.Assert; @Entity public class User implements UserDetails{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; //用户是否没有失效
 @Transient private boolean accountNonExpried; //用户是否冻结
 @Transient private boolean accountNonLocked; //证实是否过时
 @Transient private boolean credentialsNonExpired; //判断是否删除
 @Transient private boolean enabled; @Transient //添加 @Transient 注解能够不将 Set<GrantedAuthority>映射到数据库表上
    private Set<GrantedAuthority> authorities; //给hibernatre用的构造方法
    protected User() { } public User(Long id,String username,String password) { this.id = id; this.username = username; this.password = password; } //给SpringSecurity用的构造方法
    public User(String username,String password, Collection<? extends GrantedAuthority> authorities) { this(username,password,true,true,true,true,authorities); } public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) { if (((username == null) || "".equals(username)) || (password == null)) { throw new IllegalArgumentException( "Cannot pass null or empty values to constructor"); } this.username = username; this.password = password; this.enabled = enabled; this.accountNonExpried = accountNonExpired; this.credentialsNonExpired = credentialsNonExpired; this.accountNonLocked = accountNonLocked; this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); } private static SortedSet<GrantedAuthority> sortAuthorities( Collection<? extends GrantedAuthority> authorities) { Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection"); // Ensure array iteration order is predictable (as per // UserDetails.getAuthorities() contract and SEC-717)
        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<>( new AuthorityComparator()); for (GrantedAuthority grantedAuthority : authorities) { Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements"); sortedAuthorities.add(grantedAuthority); } return sortedAuthorities; } private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; public int compare(GrantedAuthority g1, GrantedAuthority g2) { // Neither should ever be null as each entry is checked before adding it to // the set. // If the authority is null, it is a custom authority and should precede // others.
    if (g2.getAuthority() == null) { return -1; } if (g1.getAuthority() == null) { return 1; } return g1.getAuthority().compareTo(g2.getAuthority()); } } public Long getId() { return id; } public void setId(Long id) { this.id = id; } 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; } //用户权限
 @Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub
        return authorities; } //用户是否没有失效
 @Override public boolean isAccountNonExpired() { // TODO Auto-generated method stub
        return accountNonExpried; } //用户是否被冻结
 @Override public boolean isAccountNonLocked() { // TODO Auto-generated method stub
        return accountNonLocked; } //用户是否证实权限过时
 @Override public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub
        return credentialsNonExpired; } //判断用户是否删除
 @Override public boolean isEnabled() { // TODO Auto-generated method stub
        return enabled; } }
User.java

 

  完善User.java实体

public User(Long id,String username,String password) { this.id = id; this.username = username; this.password = password; } //给SpringSecurity用的构造方法
    public User(String username,String password, Collection<? extends GrantedAuthority> authorities) { this(username,password,true,true,true,true,authorities); } public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) { if (((username == null) || "".equals(username)) || (password == null)) { throw new IllegalArgumentException( "Cannot pass null or empty values to constructor"); } this.username = username; this.password = password; this.enabled = enabled; this.accountNonExpried = accountNonExpired; this.credentialsNonExpired = credentialsNonExpired; this.accountNonLocked = accountNonLocked; this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); } private static SortedSet<GrantedAuthority> sortAuthorities( Collection<? extends GrantedAuthority> authorities) { Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection"); // Ensure array iteration order is predictable (as per // UserDetails.getAuthorities() contract and SEC-717)
        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<>( new AuthorityComparator()); for (GrantedAuthority grantedAuthority : authorities) { Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements"); sortedAuthorities.add(grantedAuthority); } return sortedAuthorities; } private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; public int compare(GrantedAuthority g1, GrantedAuthority g2) { // Neither should ever be null as each entry is checked before adding it to // the set. // If the authority is null, it is a custom authority and should precede // others.
    if (g2.getAuthority() == null) { return -1; } if (g1.getAuthority() == null) { return 1; } return g1.getAuthority().compareTo(g2.getAuthority()); } }

 

package com.Gary.GaryRESTful.domain; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.util.Assert; @Entity public class User implements UserDetails{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String username; private String password; //用户是否没有失效
    private boolean accountNonExpried; //用户是否冻结
    private boolean accountNonLocked; //证实是否过时
    private boolean credentialsNonExpired; //判断是否删除
    private boolean enabled; private Set<GrantedAuthority> authorities; //给hibernatre用的构造方法
    protected User() { } public User(Long id,String username,String password) { this.id = id; this.username = username; this.password = password; } //给SpringSecurity用的构造方法
    public User(String username,String password, Collection<? extends GrantedAuthority> authorities) { this(username,password,true,true,true,true,authorities); } public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) { if (((username == null) || "".equals(username)) || (password == null)) { throw new IllegalArgumentException( "Cannot pass null or empty values to constructor"); } this.username = username; this.password = password; this.enabled = enabled; this.accountNonExpried = accountNonExpired; this.credentialsNonExpired = credentialsNonExpired; this.accountNonLocked = accountNonLocked; this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); } private static SortedSet<GrantedAuthority> sortAuthorities( Collection<? extends GrantedAuthority> authorities) { Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection"); // Ensure array iteration order is predictable (as per // UserDetails.getAuthorities() contract and SEC-717)
        SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<>( new AuthorityComparator()); for (GrantedAuthority grantedAuthority : authorities) { Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements"); sortedAuthorities.add(grantedAuthority); } return sortedAuthorities; } private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable { private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; public int compare(GrantedAuthority g1, GrantedAuthority g2) { // Neither should ever be null as each entry is checked before adding it to // the set. // If the authority is null, it is a custom authority and should precede // others.
    if (g2.getAuthority() == null) { return -1; } if (g1.getAuthority() == null) { return 1; } return g1.getAuthority().compareTo(g2.getAuthority()); } } public Long getId() { return id; } public void setId(Long id) { this.id = id; } 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; } //用户权限
 @Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub
        return authorities; } //用户是否没有失效
 @Override public boolean isAccountNonExpired() { // TODO Auto-generated method stub
        return accountNonExpried; } //用户是否被冻结
 @Override public boolean isAccountNonLocked() { // TODO Auto-generated method stub
        return accountNonLocked; } //用户是否证实权限过时
 @Override public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub
        return credentialsNonExpired; } //判断用户是否删除
 @Override public boolean isEnabled() { // TODO Auto-generated method stub
        return enabled; } }
User.java

 

  完善UserRepository.java接口,实现查找用户姓名方法

@Query(value = "select * from user where username = ?1",nativeQuery = true) User findUserByUsername(String username);

 

  在UserService.java中实现查找用户Service

 @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserRepository userRepository; //spring security默认处理登录(username为输入的username)
 @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub //System.out.println(username);
        User user = userRepository.findUserByUsername(username); //用户名,密码,权限 //User实现UserDetails接口
        return new User(username,passwordEncoder.encode(user.getPassword()),AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); }

 

  测试时发现,当用户输入错误的用户名和密码时,控制台会报空指针异常,前台为给出“坏的凭证”给用户提示信息。

  缘由:springsecurity会拦截一切其它的请求。只有当用户输入正确的用户名和密码,springsecurity才会释放用户正常的请求。

 

package com.Gary.GaryRESTful.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; //Web应用安全适配器
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter{ //告诉SpringSecurity密码用什么加密的
 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } //表单验证(身份认证)
    protected void configure(HttpSecurity http) throws Exception{ http.formLogin() .and() //请求受权
 .authorizeRequests() //全部请求都被拦截,跳转到(/login请求中)
 .anyRequest() //都须要咱们身份认证
 .authenticated(); } }
SecurityConfig.java

 

package com.Gary.GaryRESTful.repository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import com.Gary.GaryRESTful.domain.User; public interface UserRepository extends CrudRepository<User,Long>{ @Query(value = "select * from user where username = ?1",nativeQuery = true) User findUserByUsername(String username); }
UserRepository.java

 

package com.Gary.GaryRESTful.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; //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.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import com.Gary.GaryRESTful.domain.User; import com.Gary.GaryRESTful.repository.UserRepository; //用SprinSecurity默认的登录系统 //UserService要实现UserDetailsService接口
@Component public class UserService implements UserDetailsService{ @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserRepository userRepository; //spring security默认处理登录(username为输入的username)
 @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub //System.out.println(username);
        User user = userRepository.findUserByUsername(username); //用户名,密码,权限 //User实现UserDetails接口
        return new User(username,passwordEncoder.encode(user.getPassword()),AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); } }
UserService.java

 

  因此咱们能够在UserDetails.java中进行修改,添加判断,若是在数据库中未查询到用户时返回null

  @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub //System.out.println(username);
        User user = userRepository.findUserByUsername(username); //用户名,密码,权限
        if(user == null) { throw new UsernameNotFoundException(username); } //User实现UserDetails接口
        return new User(username,passwordEncoder.encode(user.getPassword()),AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); }

 

 

package com.Gary.GaryRESTful.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.authority.AuthorityUtils; //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.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import com.Gary.GaryRESTful.domain.User; import com.Gary.GaryRESTful.repository.UserRepository; //用SprinSecurity默认的登录系统 //UserService要实现UserDetailsService接口
@Component public class UserService implements UserDetailsService{ @Autowired private PasswordEncoder passwordEncoder; @Autowired private UserRepository userRepository; //spring security默认处理登录(username为输入的username)
 @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // TODO Auto-generated method stub //System.out.println(username);
        User user = userRepository.findUserByUsername(username); //用户名,密码,权限
        if(user == null) { throw new UsernameNotFoundException(username); } //User实现UserDetails接口
        return new User(username,passwordEncoder.encode(user.getPassword()),AuthorityUtils.commaSeparatedStringToAuthorityList("admin")); } }
UserService.java

 

  拓展:根据SpringSecurity提供的User方法

//给SpringSecurity用的构造方法
    public User(String username,String password, Collection<? extends GrantedAuthority> authorities) { this(username,password,true,true,true,true,authorities); }

 

  能够在UserService.java中提供的UserDetails返回值中添加4个boolean值

return new User(user.getUsername(),passwordEncoder.encode(user.getPassword()),true,true,true,true,AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));

 

  这四个boolean值表明着

//用户是否没有失效
 @Transient private boolean accountNonExpried; //用户是否冻结
 @Transient private boolean accountNonLocked; //证实是否过时
 @Transient private boolean credentialsNonExpired; //判断是否删除
 @Transient private boolean enabled;

 

  若是return返回值中四个参数都为true,springscurity不会去进行拦截验证,

  当其中一个参数为false时,springsecurity就会对用户进行拦截验证~

相关文章
相关标签/搜索