知識庫 / Spring / Spring Security RSS 訂閱

Spring Security 中的 @CurrentSecurityContext 指導手冊

Spring Security
HongKong
5
01:05 PM · Dec 06 ,2025

1. 概述

Spring Security 負責處理和解析身份驗證憑據。

在本簡短教程中,我們將學習如何從請求中獲取 SecurityContext 信息,並在我們的處理代碼中實現。

2. @CurrentSecurityContext 註解

我們可以使用一些樣板代碼來讀取安全上下文:

SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();

然而,現在有一個 @CurrentSecurityContext 註解可以幫助我們。

此外,使用註解使代碼更具聲明性,並使 認證 對象可注入。通過 @CurrentSecurityContext,我們還可以訪問當前用户的 Principal 實現。

在下面的示例中,我們將探討獲取安全上下文數據的一些方法,例如 AuthenticationPrincipal 的名稱。我們還將看到如何測試我們的代碼。

3. Maven 依賴

如果我們的 Spring Boot 版本是較新的,那麼我們只需要包含 spring-boot-starter-security 依賴項即可。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

否則,我們可以包含 spring-security-core

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>6.1.5</version>
</dependency>

4. 使用 @CurrentSecurityContext 實現

我們可以使用 Spring 表達式語言 (SpEL) 與 @CurrentSecurityContext 結合,注入 Authentication 對象或 Principal 對象。 SpEL 與類型查找機制協同工作。 默認情況下,類型檢查不會強制執行,但可以通過啓用 errorOnInvalidType 參數來啓用,該參數位於 @CurrentSecurityContext 註解中。

4.1. 獲取 身份驗證 對象

讓我們讀取 身份驗證 對象,以便返回其詳細信息:

@GetMapping("/authentication")
public Object getAuthentication(@CurrentSecurityContext(expression = "authentication") 
  Authentication authentication) {
    return authentication.getDetails();
}

請注意,SpEL表達式引用的是身份驗證 對象本身。

讓我們進行測試:

@Test
public void givenOAuth2Context_whenAccessingAuthentication_ThenRespondTokenDetails() {
    ClientCredentialsResourceDetails resourceDetails = 
      getClientCredentialsResourceDetails("baeldung", singletonList("read"));
    OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);

    String authentication = executeGetRequest(restTemplate, "/authentication");

    Pattern pattern = Pattern.compile("\\{\"remoteAddress\":\".*"
      + "\",\"sessionId\":null,\"tokenValue\":\".*"
      + "\",\"tokenType\":\"Bearer\",\"decodedDetails\":null}");
    assertTrue("authentication", pattern.matcher(authentication).matches());
}

我們應該注意的是,在這個例子中,我們獲取了連接的所有詳細信息。由於我們的測試代碼無法預測 remoteAddresstokenValue,我們使用正則表達式來檢查生成的 JSON。

4.2. 獲取 Principal

如果僅想從認證數據中獲取 Principal,我們可以修改 SpEL 表達式和注入的 Bean:

@GetMapping("/principal")
public String getPrincipal(@CurrentSecurityContext(expression = "authentication.principal") 
  Principal principal) { 
    return principal.getName(); 
}

在這種情況下,我們僅使用 getName 方法返回 Principal 名稱。

讓我們測試一下:

@Test
public void givenOAuth2Context_whenAccessingPrincipal_ThenRespondBaeldung() {
    ClientCredentialsResourceDetails resourceDetails = 
       getClientCredentialsResourceDetails("baeldung", singletonList("read"));
    OAuth2RestTemplate restTemplate = getOAuth2RestTemplate(resourceDetails);

    String principal = executeGetRequest(restTemplate, "/principal");

    assertEquals("baeldung", principal);
}

在這裏,我們看到名稱 baeldung 被添加到客户端憑據中,並且從 Principal 對象中注入到處理程序中被找到並返回。

5. 結論

在本文中,我們學習瞭如何在當前安全上下文中訪問屬性,並將它們注入到我們的處理方法參數中。

我們通過利用 SpEL 和 @CurrentSecurityContext 註解來實現的。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.