知識庫 / Spring / Spring Security RSS 訂閱

在Spring Security中檢索用户信息

Spring Security
HongKong
6
03:02 PM · Dec 06 ,2025

1. 概述

本教程將演示如何在 Spring Security 中檢索用户詳情

當前已認證的用户可以通過 Spring 中多種機制訪問。我們首先介紹最常見的解決方案——編程訪問。

2. 獲取用户到 Bean

獲取當前已認證的主體最簡單的方法是使用 SecurityContextHolder 的靜態調用:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

為了改進此片段,首先應檢查是否存在已認證的用户後再嘗試訪問它:

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof AnonymousAuthenticationToken)) {
    String currentUserName = authentication.getName();
    return currentUserName;
}

當然,這種靜態調用存在一些缺點,其中一個比較明顯的就是代碼的可測試性降低。我們現在將探討一些更常見的解決方案。

3. 在控制器中獲取用户

我們有額外的選項,位於一個@RestController註解的 Bean 中。

@RestController
public class GetUserWithPrincipalController {

    @GetMapping(value = "/username")
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
}

當然,以下是翻譯後的內容:

或者,我們還可以使用身份驗證令牌

@RestController
public class GetUserWithAuthenticationController {

    @GetMapping(value = "/username")
    public String currentUserName(Authentication authentication) {
        return authentication.getName();
    }
}

身份驗證類的API非常開放,以便框架保持最大的靈活性。因此,Spring Security principal只能作為對象檢索,並且需要將其轉換為正確的UserDetails實例。

UserDetails userDetails = (UserDetails) authentication.getPrincipal();
System.out.println("User has authorities: " + userDetails.getAuthorities());

另外,以下是直接來自 HTTP 請求的內容:

@RestController
public class GetUserWithHTTPServletRequestController {

    @GetMapping(value = "/username")
    public String currentUserNameSimple(HttpServletRequest request) {
        Principal principal = request.getUserPrincipal();
        return principal.getName();
    }
}

最後,我們可以使用 @AuthenticationPrincipal 註解來獲取當前已認證的用户詳細信息。

@RestController
public class GetUserWithAuthenticationPrincipalAnnotationController {
    
    @GetMapping("/user")
    public String getUser(@AuthenticationPrincipal UserDetails userDetails) {
        return "User Details: " + userDetails.getUsername();
    }
}

此處,@AuthenticationPrincipal 註解將當前已認證用户的信息(UserDetails)注入到方法中。該註解有助於將 Authentication.getPrincipal() 解決為方法參數。

此外,當我們用 @AuthenticationPrincipal 註解標註方法參數時,Spring Security 會自動提供當前已認證用户的主體(principal)。主體代表用户的身份,可以是用户名、用户對象或任何形式的用户標識。

4. 通過自定義界面獲取用户

為了充分利用 Spring 依賴注入,並能夠在任何地方(不僅僅是在 @RestController 類型的 Bean 中)獲取認證,我們需要隱藏靜態訪問背後的簡單外觀模式:

public interface IAuthenticationFacade {
    Authentication getAuthentication();
}
@Component
public class AuthenticationFacade implements IAuthenticationFacade {

    @Override
    public Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }
}

外觀模式暴露 身份驗證 對象,同時隱藏靜態狀態,並保持代碼鬆散耦合和完全可測試:

@RestController
public class GetUserWithCustomInterfaceController {
    @Autowired
    private IAuthenticationFacade authenticationFacade;

    @GetMapping(value = "/username")
    public String currentUserNameSimple() {
        Authentication authentication = authenticationFacade.getAuthentication();
        return authentication.getName();
    }
}

5. 在 JSP 中獲取用户

我們可以通過利用 Spring Security Taglib 支持,從 JSP 頁面中訪問當前已認證的 principal。

首先,需要在頁面上定義標籤:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

接下來,我們可以參考負責人。

<security:authorize access="isAuthenticated()">
    authenticated as <security:authentication property="principal.username" /> 
</security:authorize>

6. 在 Thymeleaf 中獲取用户

Thymeleaf 是一款現代的服務器端 Web 模板引擎,與 Spring MVC 框架具有良好的集成性。

讓我們看看如何在 Thymeleaf 引擎的頁面中訪問當前認證的 principal。

首先,我們需要添加 thymeleaf-spring6thymeleaf-extras-springsecurity6 依賴項,以便將 Thymeleaf 與 Spring Security 集成:

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring6</artifactId>
</dependency>

現在,我們可以使用 HTML 頁面中的 sec:authorize 屬性引用主元素:

<html xmlns:th="https://www.thymeleaf.org" 
  xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<body>
    <div sec:authorize="isAuthenticated()">
      Authenticated as <span sec:authentication="name"></span></div>
</body>
</html>

7. 結論

本文介紹瞭如何在 Spring 應用中獲取用户信息的各種方法,從常用的靜態訪問機制開始,然後探討了更優的注入 principal 的方式。

http://localhost:8080/spring-security-rest-custom/foos/1
user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.