關於spring security 認證的簡單知識整理
1.認證
幾個重要的類:
UsernamePasswordAuthenticationFilter
從名字上看,就知道,這是一個驗證username 和 password的過濾器,通過 filter獲取request,從request獲取username 和 password 來進行驗證,最後生成一個UsernamePasswordAuthenticationToken ,這個類繼承自Authentication,儲存一個使用者資訊,然後交由後面來進行驗證
Authentication
public interface Authentication extends Principal, Serializable { Collection<? extends GrantedAuthority> getAuthorities(); Object getCredentials(); Object getDetails(); Object getPrincipal(); boolean isAuthenticated(); void setAuthenticated(boolean var1) throws IllegalArgumentException; }
這個介面表示使用者的登陸資訊,登陸後包裝結果
AuthenticationManager
public interface AuthenticationManager {
Authentication authenticate(Authentication var1) throws AuthenticationException;
}
這個是認證的主要管理類,主要實現類是ProviderManager,它也只是負責管理,實現認證的並不是這個類,它委託給了多個AuthenticationProvider,只要有一個通過了認證,AuthenticationManager就算認證成功
AuthenticationProvider
public interface AuthenticationProvider {
Authentication authenticate(Authentication var1) throws AuthenticationException;
boolean supports(Class<?> var1);
}
真正實現認證的類,主要實現是DaoAuthenticationProvider,主要目的是想通過查詢資料來實現認證,自己不查詢資料,交UserDetailsService來完成查詢資料的任務,supports 判斷是否支援認證
UserDetailsService
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
通過過username 來獲取使用者的各種資訊,包括許可權,密碼,為之後驗證做準備,返回一個UserDetails
UserDetails
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
使用者的具體資訊,登陸是未經過包裝的使用者資訊,是最原始的資訊
查詢完成後 在 AuthenticationProvider 中,進行密碼檢驗對比
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
if (authentication.getCredentials() == null) {
this.logger.debug("Authentication failed: no credentials provided");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
} else {
String presentedPassword = authentication.getCredentials().toString();
if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
this.logger.debug("Authentication failed: password does not match stored value");
throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
}
}
}
下面是一些輔助類:
GrantedAuthority
public interface GrantedAuthority extends Serializable {
String getAuthority();
}
許可權實體類,獲取主要許可權標識,和 所需許可權做對比,一般在投票器中使用,在後面授權在做介紹
PasswordEncoder
public interface PasswordEncoder {
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);
}
密碼編譯器,具有編碼功能,可以重寫,也可以用現成的,這個不做介紹
AuthenticationFailureHandler
public interface AuthenticationFailureHandler {
void onAuthenticationFailure(HttpServletRequest var1, HttpServletResponse var2, AuthenticationException var3) throws IOException, ServletException;
}
認證失敗處理器,有request,response,AuthenticationException ,自己定義,使用者是UsernamePasswordAuthenticationFilter
AuthenticationSuccessHandler
public interface AuthenticationSuccessHandler {
void onAuthenticationSuccess(HttpServletRequest var1, HttpServletResponse var2, Authentication var3) throws IOException, ServletException;
}
認證成功處理器,自己定義,可以用現成,不多說