1. 程式人生 > >spring-security-oauth2(三) 認證流程原始碼分析

spring-security-oauth2(三) 認證流程原始碼分析

認證流程原始碼分析

之前的程式碼中,我們自定義了登陸路徑,自定義成功和失敗處理器以及自定義的使用者登陸資訊校驗,下面我們通過簡單的原始碼分析,來把這些串聯起來

  1. 認證流程處理說明
  2. 認證結果如何在多個請求之間共享
  3. 獲取認證使用者資訊

認證處理流程說明

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基於原始碼分析的 我們就先到這裡,下一章我們將開發通用的驗證碼登陸