javascript
Spring Security中的SecurityContext和SecurityContextHolder是什么?
SecurityContext和SecurityContextHolder是Spring Security的兩個(gè)基本類。 SecurityContext用于存儲(chǔ)當(dāng)前經(jīng)過身份驗(yàn)證的用戶的詳細(xì)信息,也稱為原理。 因此,如果必須獲取用戶名或任何其他用戶詳細(xì)信息,則需要首先獲取此SecurityContext 。 SecurityContextHolder是一個(gè)幫助程序類,它提供對(duì)安全上下文的訪問。 默認(rèn)情況下,它使用ThreadLocal對(duì)象存儲(chǔ)安全性上下文,這意味著即使不傳遞SecurityContext對(duì)象,該安全性上下文也始終可用于同一執(zhí)行線程中的方法。 不過,不必?fù)?dān)心Web應(yīng)用程序中的ThreadLocal內(nèi)存泄漏 ,Spring Security會(huì)負(fù)責(zé)清理ThreadLocal。
順便說(shuō)一句,這不是SecurityContextHolder可以存儲(chǔ)當(dāng)前SecurityContext的唯一方法,可以在啟動(dòng)時(shí)為其配置策略,以指定如何存儲(chǔ)上下文。 例如,可以將SecurityContextHolder.MODE_GLOBAL策略用于獨(dú)立的應(yīng)用程序。
要學(xué)習(xí)的關(guān)鍵是, 如何從SecurityContextHolder獲得SecurityContext? 然后從中檢索當(dāng)前的用戶詳細(xì)信息? 例如,如果您想知道當(dāng)前登錄用戶的用戶名,那么如何在Spring security中獲得該用戶名?
為了獲取當(dāng)前的用戶名,首先需要一個(gè)SecurityContext ,它是從SecurityContextHolder獲得的。 此SecurityContext將用戶詳細(xì)信息保留在Authentication對(duì)象中,該對(duì)象可以通過調(diào)用getAuthentication()方法獲得。
一旦獲得身份驗(yàn)證對(duì)象,就可以轉(zhuǎn)換為UserDetails或按原樣使用它。 UserDetails對(duì)象是Spring Security用于保留用戶相關(guān)信息的對(duì)象。
如何在Spring Security中獲取當(dāng)前的登錄用戶名
這是獲取Spring安全性中的安全性上下文并獲取當(dāng)前登錄用戶的名稱的代碼:
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();if (principal instanceof UserDetails) {String username = ((UserDetails)principal).getUsername(); } else {String username = principal.toString(); }getContext()返回的對(duì)象是SecurityContext接口的實(shí)例。 這是存儲(chǔ)在線程本地存儲(chǔ)中的對(duì)象。
getPrincipal()方法通常在Spring Security中返回UserDetails對(duì)象,該對(duì)象包含當(dāng)前登錄用戶的所有詳細(xì)信息。
無(wú)論如何,如果您仔細(xì)觀察,您會(huì)發(fā)現(xiàn)在考慮Spring和依賴注入時(shí),這并不是一個(gè)很好的代碼。 因此,如果您需要了解當(dāng)前登錄的用戶詳細(xì)信息(例如在Spring MVC控制器中),建議您聲明一個(gè)依賴項(xiàng),然后讓Spring為您提供Principal對(duì)象,而不是查詢它們并創(chuàng)建一個(gè)緊密耦合的系統(tǒng)。
這是一個(gè)例子
import java.security.Principal; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;@Controller public class MVCController {@RequestMapping(value = "/username", method = RequestMethod.GET)@ResponseBodypublic String currentUserName(Principal principal) {return principal.getName();}}另外,您也可以要求提供Authentication對(duì)象而不是Principal對(duì)象,如下所示:
import org.springframework.security.core.Authentication; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody;@Controller public class SpringMVCController {@RequestMapping(value = "/username", method = RequestMethod.GET)@ResponseBodypublic String currentUserName(Authentication authentication) {return authentication.getName();} }如果您想了解更多方法,還可以參閱我的文章有關(guān)在Spring Security中獲取當(dāng)前用戶名的3種方法 ,在此我討論了幾種在Spring MVC控制器中獲取當(dāng)前用戶名的更多方法。
這就是Spring安全性中的安全性上下文,以及如何從SecurityContextHolder類獲取SecurityContext的全部?jī)?nèi)容。 這些是一些基本類,因此您必須熟悉它們。
存儲(chǔ)部分(即SecurityContext存儲(chǔ)在ThreadLocal是可選的,但最好了解詳細(xì)信息。 請(qǐng)記住,如果您需要用戶詳細(xì)信息(例如用戶名等),則最好在Spring MVC控制器中請(qǐng)求Principal或Authentication對(duì)象,而不要使用SecurityContextHolder來(lái)獲取它們。
感謝您到目前為止閱讀本文。 如果您喜歡此Spring Security教程,請(qǐng)與您的朋友和同事分享。 如果您有任何疑問或反饋,請(qǐng)留言。
翻譯自: https://www.javacodegeeks.com/2018/02/securitycontext-securitycontextholder-spring-security.html
總結(jié)
以上是生活随笔為你收集整理的Spring Security中的SecurityContext和SecurityContextHolder是什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 局域网路由器设置(局域网怎样设置路由器)
- 下一篇: 飞鱼星双wan口设置(飞鱼星多wan口路