欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Security異步無法獲取用戶認(rèn)證信息的解決方法

 更新時(shí)間:2024年09月14日 09:31:13   作者:憶昔年.  
最近使用 Springboot 中 @Async 注解異步調(diào)用方法時(shí),發(fā)現(xiàn)無法獲取到用戶認(rèn)證信息,本文小編給大家介紹了Spring Security異步無法獲取用戶認(rèn)證信息的原因和解決方法,并通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下

原因:

Spring Security中的上下文SecurityContext的管理策略有三種

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";
}

默認(rèn)的管理策略是:MODE_THREADLOCAL,對應(yīng)的策略類是
org.springframework.security.core.context.ThreadLocalSecurityContextHolderStrategy

以下是 Spring Security 初始化策略的代碼:

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";
    // 獲取系統(tǒng)配置的策略
    private static String strategyName = System.getProperty(SYSTEM_PROPERTY);
    // 預(yù)初始化策略
    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;
        }
        // Try to load a custom strategy
        try {
            Class<?> clazz = Class.forName(strategyName);
            Constructor<?> customStrategy = clazz.getConstructor();
            strategy = (SecurityContextHolderStrategy) customStrategy.newInstance();
        }
        catch (Exception ex) {
            ReflectionUtils.handleReflectionException(ex);
        }
    }
}

ThreadLocalSecurityContextHolderStrategy 里保存Context的方式是 ThreadLocal,ThreadLocal 子線程并不能獲取父類線程的 ThreadLocalMap,
所以就導(dǎo)致了異步無法獲取到用戶認(rèn)證信息。

final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {

    private static final ThreadLocal<Supplier<SecurityContext>> contextHolder = new ThreadLocal<>();

}

解決方法:

更改上下文的管理策略 SecurityContextHolderStrategy 為 MODE_INHERITABLETHREADLOCAL,即

InheritableThreadLocalSecurityContextHolderStrategy,里面保存上下文的方式是 InheritableThreadLocal,可以獲取父線程的 ThreadLocalMap。

final class InheritableThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {

	private static final ThreadLocal<Supplier<SecurityContext>> contextHolder = new InheritableThreadLocal<>();

}

InheritableThreadLocal可以獲取到子線程信息‌,主要是因?yàn)樗荰hreadLocal的一個(gè)子類,設(shè)計(jì)用來在父子線程間傳遞數(shù)據(jù)。
ThreadLocal變量通常只在當(dāng)前線程中存在,并且每個(gè)線程都有其自己的ThreadLocalMap,
這樣保證了線程間的數(shù)據(jù)隔離。然而,在某些情況下,我們需要父線程中的數(shù)據(jù)能夠在由父線程創(chuàng)建的子線程中被訪問,
這時(shí)就需要使用InheritableThreadLocal。
InheritableThreadLocal的實(shí)現(xiàn)機(jī)制使其能夠在子線程中訪問父線程的數(shù)據(jù)。具體來說,當(dāng)父線程創(chuàng)建一個(gè)子線程時(shí),
InheritableThreadLocal會采取措施確保子線程可以訪問到父線程中設(shè)置的InheritableThreadLocal變量。
這通常涉及到在子線程的Thread對象中復(fù)制父線程的ThreadLocalMap,從而使子線程能夠訪問到父線程中設(shè)置的變量。
這種機(jī)制允許在多線程環(huán)境中,特別是在使用線程池等場景下,實(shí)現(xiàn)父子線程間數(shù)據(jù)的傳遞和共享。
需要注意的是,雖然InheritableThreadLocal提供了在子線程中訪問父線程數(shù)據(jù)的能力,但它并不適用于所有情況,
特別是在復(fù)雜的線程交互中可能需要更精細(xì)的控制。此外,使用InheritableThreadLocal時(shí)也需要注意避免內(nèi)存泄漏等問題,因?yàn)槿绻划?dāng)使用,
它可能會導(dǎo)致資源的不當(dāng)占用‌。

代碼:

  • 1、可以在配置 Security 的配置類中添加 Bean
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public MethodInvokingFactoryBean methodInvokingFactoryBean() {
        MethodInvokingFactoryBean factoryBean = new MethodInvokingFactoryBean();
        factoryBean.setTargetClass(SecurityContextHolder.class);
        factoryBean.setTargetMethod("setStrategyName");
        factoryBean.setArguments(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
        return factoryBean;
    }
}
  • 2、可以在配置 Security 的配置類中添加類初始化方式,會在注入 SecurityContextHolder 之后調(diào)用其中靜態(tài)方法更改 SecurityContextHolderStrategy 的實(shí)現(xiàn)類
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @PostContruct
    public void init() {
        SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
    }
}
  • 3、可以在啟動項(xiàng)加上 -Dspring.security.strategy=MODE_INHERITABLETHREADLOCAL 參數(shù),啟動時(shí)更改 SecurityContextHolderStrategy 的實(shí)現(xiàn)類

以上就是Spring Security異步無法獲取用戶認(rèn)證信息的解決方法的詳細(xì)內(nèi)容,更多關(guān)于Spring Security異步無法獲取信息的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java集合中l(wèi)ist的用法代碼示例

    java集合中l(wèi)ist的用法代碼示例

    這篇文章主要介紹了java集合中l(wèi)ist的用法代碼示例,分享了相關(guān)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java線程變量ThreadLocal詳細(xì)解讀

    Java線程變量ThreadLocal詳細(xì)解讀

    這篇文章主要介紹了Java線程變量ThreadLocal詳細(xì)解讀,多線程訪問同一個(gè)變量的時(shí)候,很容易出現(xiàn)問題,特別是多線程對一個(gè)共享變量進(jìn)行寫入的時(shí)候,為了線程的安全在進(jìn)行數(shù)據(jù)寫入時(shí)候會進(jìn)行數(shù)據(jù)的同步,需要的朋友可以參考下
    2024-01-01
  • 詳解Java中的ReentrantLock鎖

    詳解Java中的ReentrantLock鎖

    這篇文章主要介紹了Java中ReentrantLock鎖的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01
  • 淺談JVM之java class文件的密碼本

    淺談JVM之java class文件的密碼本

    一切的一切都是從javac開始的。從那一刻開始,java文件就從我們?nèi)庋劭煞直娴奈谋疚募兂闪死浔亩M(jìn)制文件。變成了二進(jìn)制文件是不是意味著我們無法再深入的去了解java class文件了呢?答案是否定的。本文將詳細(xì)介紹JVM之java class文件的密碼本。
    2021-06-06
  • Spring Boot 和 Spring 到底有啥區(qū)別你知道嗎

    Spring Boot 和 Spring 到底有啥區(qū)別你知道嗎

    Spring Boot框架的核心就是自動配置,只要存在相應(yīng)的jar包,Spring就幫我們自動配置。接下來通過本文給大家介紹Spring與Spring boot的區(qū)別介紹,非常不錯(cuò),需要的朋友參考下吧
    2021-08-08
  • uploadify上傳及后臺文件合法性驗(yàn)證的代碼解析

    uploadify上傳及后臺文件合法性驗(yàn)證的代碼解析

    這篇文章主要介紹了uploadify上傳及后臺文件合法性驗(yàn)證的代碼解析,整段代碼分為后臺上傳方法,文件合法性驗(yàn)證類,前端上傳js,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • Springboot整合Shiro之加鹽MD5加密的方法

    Springboot整合Shiro之加鹽MD5加密的方法

    這篇文章主要介紹了Springboot整合Shiro之加鹽MD5加密的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-12-12
  • Java util concurrent及基本線程原理簡介

    Java util concurrent及基本線程原理簡介

    這篇文章主要介紹了Java util concurrent及基本線程原理簡介,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Javaweb開發(fā)中通過Servlet生成驗(yàn)證碼圖片

    Javaweb開發(fā)中通過Servlet生成驗(yàn)證碼圖片

    這篇文章主要為大家詳細(xì)介紹了Javaweb開發(fā)中通過Servlet生成驗(yàn)證碼圖片的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • java map中相同的key保存多個(gè)value值方式

    java map中相同的key保存多個(gè)value值方式

    這篇文章主要介紹了java map中相同的key保存多個(gè)value值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論