1. 概述
Spring Security 處理接收和解析身份驗證憑據。
在本簡短教程中,我們將學習如何從請求中獲取 SecurityContext 信息,並在我們的處理代碼中實現。
2. 當前安全上下文 註解
我們可以使用一些樣板代碼來讀取安全上下文:
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
但是,現在有了 @CurrentSecurityContext 註解來幫助我們
此外,使用註解使代碼更具聲明性,並使 身份驗證 對象可注入。 藉助 @CurrentSecurityContext,我們還可以訪問當前用户的 主要身份 實現。
在下面的示例中,我們將查看獲取安全上下文數據的一些方法,例如 身份驗證 對象和 主要身份 的名稱。 此外,我們還將看到如何測試我們的代碼。
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. 實現中使用
我們可以使用 SpEL(Spring 表達式語言)與 結合,注入 Authentication 對象或 Principal。SpEL 與類型查找一起工作。默認情況下,類型檢查不會強制執行,但我們可以通過啓用 errorOnInvalidType 參數來啓用它,該參數位於 註解中。
4.1. 獲取 Authentication 對象
讓我們讀取 Authentication 對象,以便返回其詳細信息:
@GetMapping("/authentication")
public Object getAuthentication(@CurrentSecurityContext(expression = "authentication")
Authentication authentication) {
return authentication.getDetails();
}
請注意,SpEL 表達式引用的是 authentication 對象本身。
讓我們測試一下:
@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());
}
我們應該注意的是,在這個例子中,我們正在獲取連接的所有詳細信息。由於我們的測試代碼無法預測 remoteAddress 或 tokenValue,我們正在使用正則表達式來檢查生成的 JSON。
4.2. 獲取 Principal
如果我們只想從身份驗證數據中獲取 Principal,我們可以更改 SpEL 表達式和注入的對象:
@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 註解來實現的。