新聞中心
在某些場(chǎng)景中我們需要獲取當(dāng)前的用戶是誰(shuí)?如果你使用了Spring Secrity作為安全框架你可以通過(guò)以下手段獲取當(dāng)前用戶。

創(chuàng)新互聯(lián)成都網(wǎng)站建設(shè)專業(yè)公司,是成都網(wǎng)站開(kāi)發(fā)公司,為服務(wù)器租用提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計(jì)服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計(jì)、前端HTML5制作、后臺(tái)程序開(kāi)發(fā)等。成都網(wǎng)站改版熱線:028-86922220
SecurityContext
無(wú)論是有狀態(tài)的Session模式還是流行的JWT模式你都可以通過(guò)SecurityContext來(lái)獲取當(dāng)前的用戶:
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- String currentPrincipalName = authentication.getName();
當(dāng)然這種方式是不夠嚴(yán)謹(jǐn)?shù)?,如果接口允許匿名訪問(wèn)很可能返回一個(gè)匿名用戶,而匿名用戶并不能直接通過(guò)getName獲取,所以我們需要優(yōu)化上面的邏輯為:
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (!(authentication instanceof AnonymousAuthenticationToken)) {
- String currentUserName = authentication.getName();
- return currentUserName;
- }else{
- throw RuntimeException("No User")
- }
其實(shí)我平常使用這種方式的最多,我喜歡使用一個(gè)抽象的父類控制器來(lái)封裝獲取當(dāng)前用戶的方法。
Principal
java.security.Principal對(duì)象也可以獲取當(dāng)前的用戶信息,在Spring Security中該對(duì)象表現(xiàn)為Authentication對(duì)象,如果我們?cè)赟pring MVC接口中定義Principal對(duì)象也可以獲取當(dāng)前用戶:
- @GetMapping("/currentusername")
- public String currentUserName(Principal principal) {
- return principal.getName();
- }
同理Authentication對(duì)象也是可以的:
- @GetMapping("/currentusername")
- public String currentUserName(Authentication authentication) {
- return authentication.getName();
- }
AuthenticationPrincipal
很多時(shí)候我們自定義了用戶對(duì)象UserDetails, 我們可以通過(guò)Spring Security 4.0提供的注解@AuthenticationPrincipal來(lái)獲取當(dāng)前用戶的自定義UserDetails對(duì)象。如果CustomUser是UserDetails的實(shí)現(xiàn),那么我們可以:
- @GetMapping("/currentusername")
- public String currentUserName(@AuthenticationPrincipal CustomUser customUser) {
- return customUser.getUsername();
- }
更簡(jiǎn)單點(diǎn)的話:
- @GetMapping("/currentusername")
- public String currentUserName(@AuthenticationPrincipal(expression = "username") String username) {
- return username;
- }
這需要CustomUser包含一個(gè)getUsername方法。
甚至我們自定義一個(gè)注解也是可以的:
- @Target({ElementType.PARAMETER, ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @AuthenticationPrincipal
- public @interface CurrentUser {}
CurrentSecurityContext
Spring Security 5 提供了一個(gè)新的注解@CurrentSecurityContext來(lái)獲取當(dāng)前用戶的安全上下文,你可以:
- @GetMapping("/currentusername")
- public String currentUserName(@CurrentSecurityContext(expression = "authentication")
- Authentication authentication) {
- return authentication.getName();
- }
當(dāng)然你還可以通過(guò)expression參數(shù)聲明SpEL表達(dá)式來(lái)獲取其它屬性,例如獲取Principal對(duì)象:
- @GetMapping("/principal")
- public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal")
- Principal principal) {
- return principal.getName();
- }
HttpServletRequest
據(jù)說(shuō)HttpServletRequest的getUserPrincipal()方法也可以,但是我沒(méi)有用過(guò),感興趣的同學(xué)可以試試能不能在Spring Security框架中直接通過(guò)該方法獲取。
總結(jié)
今天總結(jié)了如何在Spring Security獲取當(dāng)前用戶的各種方法,它們的各自場(chǎng)景都略有不同,你可以根據(jù)這些羅列選擇最適合你的應(yīng)用場(chǎng)景。
本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)小胖哥」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)小胖哥公眾號(hào)。
網(wǎng)頁(yè)標(biāo)題:Spring Security 實(shí)戰(zhàn)干貨:如何獲取當(dāng)前用戶信息
本文來(lái)源:http://www.5511xx.com/article/coedjed.html


咨詢
建站咨詢
