Spring Security-从入门到精通-UserDetailsService 详解
基本思路
- 从数据库中查出用户相关数据 (自定义逻辑 UserDetailsServic)
- 去执行认证逻辑增加相关权限或抛出异常 (认证逻辑)
总结:通过自定义逻辑去控制认证逻辑 对比数据库中的用户和前端传来的用户
UserDetailsServic接口
package org.springframework.security.core.userdetails; public interface UserDetailsService { /** *加载用户通过用户名 返回 UserDetails 用户名找不到异常 */ UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; }
UserDetails接口
/** * UserDetails 接口 继承 Serializable 返回UserDetails接口的实现类 */ package org.springframework.security.core.userdetails; import java.io.Serializable; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; public interface UserDetails extends Serializable { /** * 获取所有权限 不能返回null * * @return */ Collection<? extends GrantedAuthority> getAuthorities(); /** * 获取密码 * * @return */ String getPassword(); /** * 获取用户名 * * @return */ String getUsername(); /** * 判断用户是否过期 * * @return */ boolean isAccountNonExpired(); /** * 判断用户是否被锁定 * * @return */ boolean isAccountNonLocked(); /** * 凭证是否过期 密码是否过期 * * @return */ boolean isCredentialsNonExpired(); /** * 账户时候可用 * * @return */ boolean isEnabled(); }
UserDetails接口的实现类 User
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.security.core.userdetails; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.security.core.CredentialsContainer; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.crypto.factory.PasswordEncoderFactories; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.util.Assert; public class User implements UserDetails, CredentialsContainer { private static final long serialVersionUID = 510L; private static final Log logger = LogFactory.getLog(User.class); private String password; private final String username; private final Set<GrantedAuthority> authorities; private final boolean accountNonExpired; private final boolean accountNonLocked; private final boolean credentialsNonExpired; private final boolean enabled; 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) { this.username = username; this.password = password; this.enabled = enabled; this.accountNonExpired = accountNonExpired; this.credentialsNonExpired = credentialsNonExpired; this.accountNonLocked = accountNonLocked; this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities)); } else { throw new IllegalArgumentException("Cannot pass null or empty values to constructor"); } } public Collection<GrantedAuthority> getAuthorities() { return this.authorities; } public String getPassword() { return this.password; } public String getUsername() { return this.username; } public boolean isEnabled() { return this.enabled; } public boolean isAccountNonExpired() { return this.accountNonExpired; } public boolean isAccountNonLocked() { return this.accountNonLocked; } public boolean isCredentialsNonExpired() { return this.credentialsNonExpired; } public void eraseCredentials() { this.password = null; } private static SortedSet<GrantedAuthority> sortAuthorities(Collection<? extends GrantedAuthority> authorities) { Assert.notNull(authorities, "Cannot pass a null GrantedAuthority collection"); SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet(new User.AuthorityComparator()); Iterator var2 = authorities.iterator(); while(var2.hasNext()) { GrantedAuthority grantedAuthority = (GrantedAuthority)var2.next(); Assert.notNull(grantedAuthority, "GrantedAuthority list cannot contain any null elements"); sortedAuthorities.add(grantedAuthority); } return sortedAuthorities; } public boolean equals(Object rhs) { return rhs instanceof User ? this.username.equals(((User)rhs).username) : false; } public int hashCode() { return this.username.hashCode(); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()).append(": "); sb.append("Username: ").append(this.username).append("; "); sb.append("Password: [PROTECTED]; "); sb.append("Enabled: ").append(this.enabled).append("; "); sb.append("AccountNonExpired: ").append(this.accountNonExpired).append("; "); sb.append("credentialsNonExpired: ").append(this.credentialsNonExpired).append("; "); sb.append("AccountNonLocked: ").append(this.accountNonLocked).append("; "); if (!this.authorities.isEmpty()) { sb.append("Granted Authorities: "); boolean first = true; Iterator var3 = this.authorities.iterator(); while(var3.hasNext()) { GrantedAuthority auth = (GrantedAuthority)var3.next(); if (!first) { sb.append(","); } first = false; sb.append(auth); } } else { sb.append("Not granted any authorities"); } return sb.toString(); } public static User.UserBuilder withUsername(String username) { return builder().username(username); } public static User.UserBuilder builder() { return new User.UserBuilder(); } /** @deprecated */ @Deprecated public static User.UserBuilder withDefaultPasswordEncoder() { logger.warn("User.withDefaultPasswordEncoder() is considered unsafe for production and is only intended for sample applications."); PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder(); User.UserBuilder var10000 = builder(); encoder.getClass(); return var10000.passwordEncoder(encoder::encode); } public static User.UserBuilder withUserDetails(UserDetails userDetails) { return withUsername(userDetails.getUsername()).password(userDetails.getPassword()).accountExpired(!userDetails.isAccountNonExpired()).accountLocked(!userDetails.isAccountNonLocked()).authorities(userDetails.getAuthorities()).credentialsExpired(!userDetails.isCredentialsNonExpired()).disabled(!userDetails.isEnabled()); } public static class UserBuilder { private String username; private String password; private List<GrantedAuthority> authorities; private boolean accountExpired; private boolean accountLocked; private boolean credentialsExpired; private boolean disabled; private Function<String, String> passwordEncoder; private UserBuilder() { this.passwordEncoder = (password) -> { return password; }; } public User.UserBuilder username(String username) { Assert.notNull(username, "username cannot be null"); this.username = username; return this; } public User.UserBuilder password(String password) { Assert.notNull(password, "password cannot be null"); this.password = password; return this; } public User.UserBuilder passwordEncoder(Function<String, String> encoder) { Assert.notNull(encoder, "encoder cannot be null"); this.passwordEncoder = encoder; return this; } public User.UserBuilder roles(String... roles) { List<GrantedAuthority> authorities = new ArrayList(roles.length); String[] var3 = roles; int var4 = roles.length; for(int var5 = 0; var5 < var4; ++var5) { String role = var3[var5]; Assert.isTrue(!role.startsWith("ROLE_"), () -> { return role + " cannot start with ROLE_ (it is automatically added)"; }); authorities.add(new SimpleGrantedAuthority("ROLE_" + role)); } return this.authorities((Collection)authorities); } public User.UserBuilder authorities(GrantedAuthority... authorities) { return this.authorities((Collection)Arrays.asList(authorities)); } public User.UserBuilder authorities(Collection<? extends GrantedAuthority> authorities) { this.authorities = new ArrayList(authorities); return this; } public User.UserBuilder authorities(String... authorities) { return this.authorities((Collection)AuthorityUtils.createAuthorityList(authorities)); } public User.UserBuilder accountExpired(boolean accountExpired) { this.accountExpired = accountExpired; return this; } public User.UserBuilder accountLocked(boolean accountLocked) { this.accountLocked = accountLocked; return this; } public User.UserBuilder credentialsExpired(boolean credentialsExpired) { this.credentialsExpired = credentialsExpired; return this; } public User.UserBuilder disabled(boolean disabled) { this.disabled = disabled; return this; } public UserDetails build() { String encodedPassword = (String)this.passwordEncoder.apply(this.password); return new User(this.username, encodedPassword, !this.disabled, !this.accountExpired, !this.credentialsExpired, !this.accountLocked, this.authorities); } } private static class AuthorityComparator implements Comparator<GrantedAuthority>, Serializable { private static final long serialVersionUID = 510L; private AuthorityComparator() { } public int compare(GrantedAuthority g1, GrantedAuthority g2) { if (g2.getAuthority() == null) { return -1; } else { return g1.getAuthority() == null ? 1 : g1.getAuthority().compareTo(g2.getAuthority()); } } } }