亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于SpringSecurity?Context?中獲取和更改當(dāng)前用戶(hù)信息的問(wèn)題

 更新時(shí)間:2024年09月11日 16:12:48   作者:零offer在手  
SpringSecurityContext在異步線程中無(wú)法獲取用戶(hù)信息,因其與請(qǐng)求線程綁定;此外,用戶(hù)信息更新后跳轉(zhuǎn)頁(yè)面時(shí),身份會(huì)被降級(jí)為匿名,導(dǎo)致信息無(wú)法及時(shí)同步,本文給大家介紹SpringSecurity?Context?中獲取和更改當(dāng)前用戶(hù)信息的問(wèn)題,感興趣的朋友一起看看吧

SpringSecurity Context 獲取和更改用戶(hù)信息的問(wèn)題

SecurityContext 異步線程中獲取用戶(hù)信息

今天在做項(xiàng)目時(shí)遇到了一個(gè)問(wèn)題,我需要獲取當(dāng)前用戶(hù)的 ID。之前,前端并沒(méi)有存儲(chǔ)用戶(hù)信息,我一直是在后端的 service 中通過(guò) SecurityContext 來(lái)獲取用戶(hù)信息,這個(gè)方法之前一直有效。然而,今天在另一個(gè) service 中調(diào)用時(shí)卻無(wú)法獲取到用戶(hù)信息。

經(jīng)過(guò)詳細(xì)排查,發(fā)現(xiàn) SecurityContext 的內(nèi)容是與請(qǐng)求線程(如 HTTP 請(qǐng)求)綁定的。但我當(dāng)前的 service 是用于處理 MQTT 消息,這屬于異步線程。因此,在異步線程中無(wú)法從 SecurityContext 獲取用戶(hù)信息,只能另尋解決方案。

 /**
     * 處理接收到的設(shè)備數(shù)據(jù),根據(jù)數(shù)據(jù)類(lèi)型進(jìn)行不同的處理。energy數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù),其他數(shù)據(jù)通過(guò)WebSocket發(fā)送到前端展示。
     * @param data 數(shù)據(jù)內(nèi)容
     */
    private void handleIncomingData(String data) {
        	......
            /*
                * 通過(guò)設(shè)備ID找到用戶(hù)ID, 不能通過(guò)securityContext獲取當(dāng)前用戶(hù)ID,因?yàn)檫@里是異步處理消息,不在請(qǐng)求線程中。
                * 通過(guò)securityContext獲取當(dāng)前用戶(hù)ID的方法只能在請(qǐng)求線程中使用,通常是與HTTP請(qǐng)求相關(guān)的操作才能獲取到。
                * 這里是MQTT消息處理,不在請(qǐng)求線程中,所以要通過(guò)其他方式獲取當(dāng)前用戶(hù)ID。
                * 還因?yàn)檫@里是存入數(shù)據(jù)庫(kù),因?yàn)橐膊荒芤蕾?lài)物理設(shè)備的用戶(hù)ID,設(shè)備不一定是存用戶(hù)ID, 降低耦合性。
               TODO: 這里是否可以改進(jìn)?
             */
            long userId = deviceMapper.findDeviceById(deviceId).getUserId();
            if (userId<=0) {//如果userId<=0,說(shuō)明沒(méi)有找到對(duì)應(yīng)的設(shè)備
                logger.error("Failed to get user id by device id: {}", deviceId);
                throw new RuntimeException("Failed to get user id by device id: " + deviceId);
            }
            Energy energy = new Energy();
            energy.setDeviceId(deviceId);
            energy.setEnergy(totalEnergy);
            energy.setRecordDate(recordDate);
            energy.setUserId(userId);
			......
    }

SecurityContext 線程降級(jí)問(wèn)題

在項(xiàng)目中遇到 SecurityContext 線程降級(jí)的問(wèn)題,具體場(chǎng)景是用戶(hù)修改個(gè)人資料(如郵箱)后,我希望 SecurityContext 中的用戶(hù)信息能及時(shí)更新。然而,在修改郵箱后,用戶(hù)需要跳轉(zhuǎn)到郵箱驗(yàn)證碼驗(yàn)證頁(yè)面,該頁(yè)面通過(guò) security 配置中的 permitAll() 允許匿名訪問(wèn)。

這個(gè)配置導(dǎo)致一個(gè)問(wèn)題:雖然用戶(hù)已經(jīng)登錄認(rèn)證,但在訪問(wèn) /verify-code 頁(yè)面時(shí),SecurityContext 中的身份會(huì)被降級(jí)為匿名用戶(hù),進(jìn)而導(dǎo)致更新后的信息沒(méi)有在 SecurityContext 中及時(shí)反映。

我了解到可以通過(guò) setAuthentication() 手動(dòng)更新 SecurityContext,但嘗試后依然無(wú)法解決問(wèn)題,更新后的用戶(hù)信息仍舊無(wú)法及時(shí)同步到 SecurityContext 中~

   @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable) // disable csrf
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/login","/register","/verify-code","/forgot-password","/change-password").permitAll()// permit request without authentication
                        .requestMatchers("/ws/**").permitAll()// permit websocket request without authentication
                        .anyRequest().authenticated()
                )
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                .logout(AbstractHttpConfigurer::disable);// disable logout otherwise it will conflict with our custom logout
        return http.build();
    }

到此這篇關(guān)于SpringSecurity Context 中 獲取 和 更改 當(dāng)前用戶(hù)信息的問(wèn)題的文章就介紹到這了,更多相關(guān)SpringSecurity Context 獲取當(dāng)前用戶(hù)信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論