标签:rop uil form blank check framework 返回值 请求 构造方法
系列博文
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实体
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; } }
完善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(); } }
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); }
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")); } }
所以我们可以在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")); } }
拓展:根据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就会对用户进行拦截验证~
JavaWeb-SpringSecurity在数据库中查询用户
标签:rop uil form blank check framework 返回值 请求 构造方法
原文地址:https://www.cnblogs.com/1138720556Gary/p/11745700.html