Spring Security原理簡略分析

導讀

Spring Security是一個提供身份驗證、授權和針對常見攻擊的保護的框架。它對命令式和反應式應用程序都提供了一流的支持,是保護基於spring的應用程序的事實標準。

原理

流程圖

整體流程:

clientFilterDelegatingFilterProxFilterChainProxySecurityFilterChainSecurityContextPDispatcheServletFilter攔截請求進行鏈式調用掛載的filter委託調用Spring實現的Filter委託調用Security的Filter匹配對應的Filter組會創建Security上下文信息依次進行filter調用後續請求由spring mvc進行後續請求處理clientFilterDelegatingFilterProxFilterChainProxySecurityFilterChainSecurityContextPDispatcheServlet

委託給security後的驗證流程:

SecurityFilterChainSecurityFilrerProviderManagerAuthenticatUserDetailsServicePasswordEncoder用戶自己實現的Filter調用Provider管理器進行表決獲取保存的用戶信息對保存用戶編碼返回用戶信息將請求用戶密碼編碼並和保存用戶進行比對返回結果驗證失敗會拋出異常SecurityFilterChainSecurityFilrerProviderManagerAuthenticatUserDetailsServicePasswordEncoder

流程分析

典型HTTP處理程序方式,由一系列的fiter調用鏈組成,無異常情況下請求最終由serverlet去處理:

過濾鏈

Filter 過濾器

DelegatingFilterProxy

允許在Servlet容器的生命週期和Spring的生命週期之間進行橋接ApplicationContext。Servlet容器允許Filter使用其自己的標準註冊,但是它不知道Spring定義的Bean。 DelegatingFilterProxy可以通過標準Servlet容器機制進行註冊,但是將所有工作委託給實現的Spring Bean Filter

委託代理

FilterChainProxy

Spring Security的Filtert支持包含在中FilterChainProxyFilterChainProxyFilterSpring Security提供的一種特殊功能,它允許Filter通過委派許多實例SecurityFilterChain。由於FilterChainProxy是Bean,因此通常將其包裝在DelegatingFilterProxy中

過濾鏈代理

SecurityFilterChain

FilterChainProxy用於確定Filter應對此請求調用哪些Spring Security 。

安全過濾鏈

FilterChainProxy維護了多組SecurityChain,每次請求FilterChainProxy會找到匹配的一組,包裝成VirtualFilterChain,由VirtualFilterChain進行調用:

多重安全過濾鏈

目前的所有的Filter列表

ChannelProcessingFilter
ConcurrentSessionFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
CsrfFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
Saml2WebSsoAuthenticationRequestFilter
X509AuthenticationFilter
AbstractPreAuthenticatedProcessingFilter
CasAuthenticationFilter
OAuth2LoginAuthenticationFilter
Saml2WebSsoAuthenticationFilter
UsernamePasswordAuthenticationFilter
ConcurrentSessionFilter
OpenIDAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
DigestAuthenticationFilter
BearerTokenAuthenticationFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
SwitchUserFilter

Servlet

DispatcheServlet

Spring Mvc的統一入口,它實現了標準的Sevlet Api,它是spring 的基礎Servlet。

Security上下文

上下文是有SecurityContextPersistenceFilter放入的,HttpSessionSecurityContextRepository是Session倉庫

SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
SecurityContextHolder.setContext(contextBeforeChainExecution);

SecurityContextHolder 包含了SecurityContext,一個hold代表着當前的一個驗證用戶,獲取用戶的方式有2種:

1、註解方式

@GetMapping("/")
public String index(@AuthenticationPrincipal User user) {
		System.out.println(user);
}

2、調用SecurityContextHolder 方法獲取

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
// 用戶名/賬戶
String username = authentication.getName();
// 當前用戶,一般是UserDetail的一個實現
Object principal = authentication.getPrincipal();
// 密碼信息,驗證成功後會清除
Object credentials = authentication.getCredentials();
// 角色權限
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

Security Filter 組成

Security調用流程Filter -> ProvidderManager -> UserDetailsService -> PasswordEncoder

AuthenticationManager

ProviderManager是最常用的實現,它可以由WebSecurityConfigurerAdapter的configure(AuthenticationManagerBuilder auth)構建出來。

ProviderManager

它維護了一組Provicider,每個Provicider可以爲自己支持的類型進行表決驗證成功或者失敗,如果沒有找到對應的類型會直接拋出異常,同時它有個parent屬性,支持繼承,無法驗證時會使用parent來完成驗證。

UserDetailsService

加載用戶使用,加載方式支持多種,比如jdbc,redis,內存等等,用戶可以自行擴展。

PasswordEncoder

對請求數據進行編解碼操作,security默認提供了多種編碼器,也可自行實現。

默認提供了多種編碼器,比如:BCryptPasswordEncoder、Pbkdf2PasswordEncoder、SCryptPasswordEncoder、StandardPasswordEncoder等,也允許用戶實現自己的編解碼器。

DelegatingPasswordEncoder爲一個特殊的編碼器,它支持一組編碼器,通過頭匹配模式,進行密碼解碼和重新編碼。在編碼格式改變時非常有用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章