最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security獲取用戶認證信息的實現流程

 更新時間:2022年12月27日 15:20:02   作者:一個雙子座的Java攻城獅  
Spring Security是一個能夠為基于Spring的企業(yè)應用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP功能,為應用系統(tǒng)提供聲明式的安全訪問控制功能

登錄用戶數據獲取

SecurityContextHolder

? Spring Security 會將登錄用戶數據保存在 Session 中。但是,為了使用方便,Spring Security在此基礎上還做了一些改進,其中最主要的一個變化就是線程綁定。當用戶登錄成功后,Spring Security 會將登錄成功的用戶信息保存到 SecurityContextHolder 中。

? SecurityContextHolder 中的數據保存默認是通過ThreadLocal 來實現的,使用 ThreadLocal 創(chuàng)建的變量只能被當前線程訪問,不能被其他線程訪問和修改,也就是用戶數據和請求線程綁定在一起。當登錄請求處理完畢后,Spring Security 會將 SecurityContextHolder 中的數據拿出來保存到 Session 中,同時將 SecurityContexHolder 中的數據清空。以后每當有請求到來時,Spring Security 就會先從 Session 中取出用戶登錄數據,保存到SecurityContextHolder 中,方便在該請求的后續(xù)處理過程中使用,同時在請求結束時將 SecurityContextHolder 中的數據拿出來保存到 Session 中,然后將SecurityContextHolder 中的數據清空。

? 實際上 SecurityContextHolder 中存儲是 SecurityContext,在 SecurityContext 中存儲是 Authentication。

這種設計是典型的策略設計模式:

public class SecurityContextHolder {
	public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
	public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
	public static final String MODE_GLOBAL = "MODE_GLOBAL";
	private static final String MODE_PRE_INITIALIZED = "MODE_PRE_INITIALIZED";
	private static SecurityContextHolderStrategy strategy;
  //....
	private static void initializeStrategy() {
		if (MODE_PRE_INITIALIZED.equals(strategyName)) {
			Assert.state(strategy != null, "When using " + MODE_PRE_INITIALIZED
					+ ", setContextHolderStrategy must be called with the fully constructed strategy");
			return;
		}
		if (!StringUtils.hasText(strategyName)) {
			// Set default
			strategyName = MODE_THREADLOCAL;
		}
		if (strategyName.equals(MODE_THREADLOCAL)) {
			strategy = new ThreadLocalSecurityContextHolderStrategy();
			return;
		}
		if (strategyName.equals(MODE_INHERITABLETHREADLOCAL)) {
			strategy = new InheritableThreadLocalSecurityContextHolderStrategy();
			return;
		}
		if (strategyName.equals(MODE_GLOBAL)) {
			strategy = new GlobalSecurityContextHolderStrategy();
			return;
		}
    //.....
  }
}
  • MODE THREADLOCAL:這種存放策略是將 SecurityContext 存放在 ThreadLocal中,大家知道 Threadlocal 的特點是在哪個線程中存儲就要在哪個線程中讀取,這其實非常適合 web 應用,因為在默認情況下,一個請求無論經過多少 Filter 到達 Servlet,都是由一個線程來處理的。這也是 SecurityContextHolder 的默認存儲策略,這種存儲策略意味著如果在具體的業(yè)務處理代碼中,開啟了子線程,在子線程中去獲取登錄用戶數據,就會獲取不到。
  • MODE INHERITABLETHREADLOCAL:這種存儲模式適用于多線程環(huán)境,如果希望在子線程中也能夠獲取到登錄用戶數據,那么可以使用這種存儲模式。
  • MODE GLOBAL:這種存儲模式實際上是將數據保存在一個靜態(tài)變量中,在 JavaWeb開發(fā)中,這種模式很少使用到。

SecurityContextHolderStrategy

通過 SecurityContextHolder 可以得知,SecurityContextHolderStrategy 接口用來定義存儲策略方法

public interface SecurityContextHolderStrategy {
	void clearContext();
	SecurityContext getContext();
	void setContext(SecurityContext context);
	SecurityContext createEmptyContext();
}

接口中一共定義了四個方法:

  • clearContext:該方法用來清除存儲的 SecurityContext對象。
  • getContext:該方法用來獲取存儲的 SecurityContext 對象。
  • setContext:該方法用來設置存儲的 SecurityContext 對象。
  • create Empty Context:該方法則用來創(chuàng)建一個空的 SecurityContext 對象。

代碼中獲取認證之后用戶數據

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
      Authentication authentication = SecurityContextHolder
        .getContext().getAuthentication();
      User principal = (User) authentication.getPrincipal();
      System.out.println("身份 :"+principal.getUsername());
      System.out.println("憑證 :"+authentication.getCredentials());
      System.out.println("權限 :"+authentication.getAuthorities());
      return "hello security";
    }
}

多線程情況下獲取用戶數據

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
      new Thread(()->{
        Authentication authentication = SecurityContextHolder
          .getContext().getAuthentication();
        User principal = (User) authentication.getPrincipal();
        System.out.println("身份 :"+principal.getUsername());
        System.out.println("憑證 :"+authentication.getCredentials());
        System.out.println("權限 :"+authentication.getAuthorities());
      }).start();
      return "hello security";
    }
}

可以看到默認策略,是無法在子線程中獲取用戶信息,如果需要在子線程中獲取必須使用第二種策略,默認策略是通過 System.getProperty 加載的,因此我們可以通過增加 VM Options 參數進行修改。

-Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL

頁面上獲取用戶信息

引入依賴

<dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-springsecurity5</artifactId>
  <version>3.0.4.RELEASE</version>
</dependency>

頁面加入命名空間

<html lang="en" xmlns:th="https://www.thymeleaf.org" 
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

頁面中使用

<!--獲取認證用戶名-->
<ul>
  <li sec:authentication="principal.username"></li>
  <li sec:authentication="principal.authorities"></li>
  <li sec:authentication="principal.accountNonExpired"></li>
  <li sec:authentication="principal.accountNonLocked"></li>
  <li sec:authentication="principal.credentialsNonExpired"></li>
</ul>

到此這篇關于Spring Security獲取用戶認證信息的實現流程的文章就介紹到這了,更多相關Spring Security獲取認證信息內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 初識Spring Boot框架之Spring Boot的自動配置

    初識Spring Boot框架之Spring Boot的自動配置

    本篇文章主要介紹了初識Spring Boot框架之Spring Boot的自動配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • SpringBoot實現重試機制的四種方案

    SpringBoot實現重試機制的四種方案

    在分布式系統(tǒng)和微服務架構中,服務調用失敗是不可避免的現象,網絡不穩(wěn)定、服務過載、臨時故障等因素都可能導致調用失敗,重試機制作為一種處理臨時性故障的解決方案,能夠有效提高系統(tǒng)的可用性,需要的朋友可以參考下
    2025-04-04
  • Java實現簡單班級管理系統(tǒng)

    Java實現簡單班級管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Java實現簡單班級管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • MyBatis-Plus 如何單元測試的實現

    MyBatis-Plus 如何單元測試的實現

    這篇文章主要介紹了MyBatis-Plus 如何單元測試的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java常用工具類—集合排序

    Java常用工具類—集合排序

    這篇文章主要介紹了Java集合排序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • springboot springmvc拋出全局異常的解決方法

    springboot springmvc拋出全局異常的解決方法

    這篇文章主要為大家詳細介紹了springboot springmvc拋出全局異常的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 使用@DS輕松解決動態(tài)數據源的問題

    使用@DS輕松解決動態(tài)數據源的問題

    這篇文章主要介紹了使用@DS輕松解決動態(tài)數據源的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 利用Java實現word導入導出富文本(含圖片)的詳細代碼

    利用Java實現word導入導出富文本(含圖片)的詳細代碼

    這篇文章主要為大家詳細介紹了利用Java實現word導入導出富文本(含圖片),文中的示例代碼講解詳細,對大家的學習或工作有一定的幫助,感興趣的小伙伴可以學習一下
    2024-02-02
  • 二種jar包制作方法講解(dos打包jar eclipse打包jar文件)

    二種jar包制作方法講解(dos打包jar eclipse打包jar文件)

    這篇文章主要介紹了二種jar包制作方法講解:dos打包jar和eclipse打包jar文件,大家參考使用吧
    2013-11-11
  • 利用Spring Social輕松搞定微信授權登錄的方法示例

    利用Spring Social輕松搞定微信授權登錄的方法示例

    這篇文章主要介紹了利用Spring Social輕松搞定微信授權登錄的方法示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12

最新評論

荔波县| 象州县| 堆龙德庆县| 西丰县| 昌乐县| 盐源县| 南投县| 唐山市| 马尔康县| 九江市| 响水县| 淳化县| 翁源县| 灵宝市| 乌鲁木齐县| 平度市| 独山县| 乌海市| 昌宁县| 靖边县| 武鸣县| 兖州市| 郧西县| 冕宁县| 涡阳县| 柳林县| 通城县| 探索| 新昌县| 丰城市| 宝坻区| 滁州市| 新兴县| 宾川县| 榆社县| 迁西县| 孙吴县| 安岳县| 云浮市| 龙海市| 蕲春县|