Spring security能夠進行認證和受權,認證和受權須要針對每個請求,因此這個功能,能夠用過濾器來實現,spring security正是經過一系列過濾器來實現認證和受權功能的。spring
咱們來看看其中幾個比較重要的過濾器,類和接口。安全
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}session
用來記錄用戶的信息,包括用戶名,權限等信息。ide
UserDetailsService接口用於返回用戶相關數據返回的是一個UserDetails實例,它有loadUserByUsername()方法,該方法能夠根據username查詢用戶實體,能夠實現該接口覆蓋該方法,實現自定義獲取用戶過程。加密
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}spa
封裝用戶信息的接口,UsernamePasswordAuthenticationToken是它的實現類,用戶登陸之後,用戶名,密碼等信息被封裝到了UsernamePasswordAuthenticationToken對象中。code
它和UserDetails不一樣之處在於Authentication記錄的是當前登陸用戶的信息,而UserDetails則是用戶信息的封裝。orm
public interface Authentication extends Principal, Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean var1) throws IllegalArgumentException;
}對象
getAuthorities方法獲取權限信息的列表接口
getCredentials方法獲取用戶認證時輸入的密碼
getDetails方法獲取訪問者的ip地址和sessionid的值
getPrincipal方法獲取用戶的信息,大部分狀況下返回的是UserDetails接口的實現類
是認證相關的核心接口,用來處理認證請求,若是認證成功則返回一個Authentication接口的實例,它的默認實現類是:ProviderManager。
SecurityContext:是安全上下文接口,用來存儲認證受權的相關信息,這個接口只有兩個方法,Authentication對象的getter、setter。
public interface SecurityContext extends Serializable {
Authentication getAuthentication();
void setAuthentication(Authentication var1);
}
保存系統當前的安全上下文,包括當前使用系統的用戶的信息。
該接口有不少實現類,它用來在認證的過程當中使用matches方法比對密碼,具體如何比對密碼則取決於PasswordEncoder的實現類。
public interface PasswordEncoder {
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);
}
好比不對密碼進行加密,採用明文字符串進行比對能夠:
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
可是在實際項目中咱們每每會對密碼進行加密,比較經常使用的PasswordEncoder實現類有:、
BCryptPasswordEncoder, Pbkdf2PasswordEncoder, SCryptPasswordEncoder
若是使用BcryptPasswordEncoder:
則:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
認證流程:
1.用戶提交用戶名密碼被UsernamePasswordAuthenticationFilter 過濾器獲取到,
封裝爲Authentication接口的實例,一般狀況下是UsernamePasswordAuthenticationToken。
2.過濾器將Authentication提交至認證管理器(AuthenticationManager)進行認證,認證成功後返回一個被填充滿信息的Authentication實例.
3. SecurityContextHolder保存返回的Authentication實例.
受權流程:
1.攔截請求:已認證的用戶請求將會被過濾器:FilterSecurityInterceptor攔截。
2. FilterSecurityInterceptor獲取訪問權限,該權限就是咱們配置的訪問規則如。
http
.authorizeRequests()
.antMatchers("/r/r1").hasAuthority("p1")
.antMatchers("/r/r2").hasAuthority("p2")
3. FilterSecurityInterceptor會調用訪問決策管理器 AccessDecisionManager 進行受權決策,若決策經過,則容許訪問資源,不然將禁止訪問
AccessDecisionManager:訪問決策管理器,用來控制用戶是否有相應的權限。
public interface AccessDecisionManager {
/**
* 經過傳遞的參數來決定用戶是否有訪問對應受保護資源的權限
*/
void decide(Authentication authentication , Object object, Collection<ConfigAttribute>
configAttributes ) throws AccessDeniedException, InsufficientAuthenticationException;
//略..
}
參數說明:
Authentication:要訪問資源的訪問者
object:要訪問的受保護資源
configAttributes:是受保護資源的訪問策略
decide方法就是用來判斷訪問者是否有訪問某資源的權限。
它用投票的方式來決定是否有訪問某資源的權限