spring-security-oauth2(三) 認證流程原始碼分析
認證流程原始碼分析
之前的程式碼中,我們自定義了登陸路徑,自定義成功和失敗處理器以及自定義的使用者登陸資訊校驗,下面我們通過簡單的原始碼分析,來把這些串聯起來
- 認證流程處理說明
- 認證結果如何在多個請求之間共享
- 獲取認證使用者資訊
認證處理流程說明
spring-security過濾器鏈
關於web中過濾器 、攔截器 、監聽器區別 https://blog.csdn.net/Jintao_Ma/article/details/52972482
idea斷點除錯:https://blog.csdn.net/deepwishly/article/details/54645022
表單過濾器認證流程如下:
UsernamePasswordAuthenticationFilter:表單使用者名稱登陸過濾器
AuthenticationManager:管理所有的Provider,並選擇適合的進行驗證
AuthenticationProvider:驗證提供者,可以自己寫provider處理自己的業務場景邏輯
UserDetailsService:驗證使用者登陸資訊
UserDetails:使用者資訊
Authentication:認證資訊封裝
下面我們進行登陸斷點除錯:
UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationToken 它實現Authentication這個認證介面
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean
AbstractUserDetailsAuthenticationProvider
DaoAuthenticationProvider
MyUserDetailServiceImpl 確實是我們自定義的實現
AbstractUserDetailsAuthenticationProvider
登陸驗證成功後 AbstractAuthenticationProcessingFilter
認證結果如何在多個請求之間共享
在已經認證成功的情況下
SecurityContext 默策略是一個 org.springframework.security.core.context.ThreadLocalSecurityContextHolderStrategy 物件,
內部使用`ThreadLocal<SecurityContext>`來儲存;ThreadLocal執行緒的變數,同一個執行緒可以讀取
SecurityContextPersistenceFilter會先查詢session中是否已經認證了。出去的時候回將認證資訊存入session。這樣就解決了請求的共享的問題
獲取認證使用者資訊
UserController,通過前面的認證資訊如何在多個請求之間共享我們知道可以直接從SecurityContextHolder中獲取認證資訊,我們來測試下
package com.rui.tiger.auth.demo.controller;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 使用者控制器
*
* @author CaiRui
* @date 2018-12-6 8:16
*/
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/hello")
public String hello() {
return "Hello,World";
}
/**
*獲取使用者認證資訊
* @return
*/
@GetMapping("authentication")
public Authentication getCurrentAuthentication(){
return SecurityContextHolder.getContext().getAuthentication();
}
/**
* 獲取使用者認證資訊
* 同getCurrentAuthentication spring 會幫我們注入
* @param authentication
* @return
*/
@GetMapping("authentication/auto")
public Authentication getCurrentAuthentication2(Authentication authentication){
return authentication;
}
}
首先進入登陸介面,登入成功後我們再輸入http://localhost:8070/user/authentication可以看到成功獲取到認證資訊
序列化格式看下
有時我們只想看到認證主體資訊可以這樣設定 使用引數註解@AuthenticationPrincipal UserDetails userDetails
獲取User的資訊
ok基於原始碼分析的 我們就先到這裡,下一章我們將開發通用的驗證碼登陸