AbstractAuthenticationToken 認證流程中??認證令牌的核心抽象類詳解
在 Spring Security 中,AbstractAuthenticationToken
是 Authentication
接口的??抽象實現類??,其核心作用是為具體的認證令牌(如用戶名密碼令牌、JWT 令牌等)提供??基礎結構與默認方法??,簡化開發者在實現自定義認證令牌時的重復代碼。它是 Spring Security 認證流程中“認證載體”的核心抽象,連接了認證請求與最終的認證結果。
核心作用詳解
1. ??實現 Authentication
接口的基礎結構??
Authentication
接口定義了認證令牌的核心行為(如獲取主體、權限、認證狀態等)。AbstractAuthenticationToken
實現了該接口,并提供了以下基礎能力:
- ??管理認證狀態??:通過
isAuthenticated()
判斷是否已認證,setAuthenticated(boolean)
控制認證狀態(部分子類會覆蓋此方法)。 - ??存儲主體與憑證??:通過
getPrincipal()
獲取用戶主體(如用戶名、用戶對象),getCredentials()
獲取驗證憑證(如密碼、token)。 - ??權限管理??:通過
getAuthorities()
獲取用戶權限集合(GrantedAuthority
),這是授權決策的關鍵依據。
2. ??提供默認方法實現??
AbstractAuthenticationToken
為 Authentication
接口的部分方法提供了默認實現,避免子類重復編寫代碼:
方法 | 說明 |
---|---|
getAuthorities() | 默認返回空集合(Collections.emptyList() ),子類需重寫以提供具體權限。 |
isAuthenticated() | 默認返回 false (未認證狀態),子類可根據實際情況調整(如 UsernamePasswordAuthenticationToken 由認證流程設置)。 |
eraseCredentials() | 默認清空憑證(setCredentials(null) ),子類可重寫以自定義清理邏輯(如保留必要信息)。 |
3. ??定義認證令牌的通用行為??
AbstractAuthenticationToken
明確了認證令牌的??生命周期規范??,例如:
- ??未認證狀態??:初始時(如用戶提交表單前),令牌處于未認證狀態(
isAuthenticated() == false
)。 - ??認證后狀態??:通過
setAuthenticated(true)
標記為已認證(通常由AuthenticationManager
完成)。 - ??憑證安全??:通過
eraseCredentials()
清理敏感信息(如密碼),防止內存泄漏導致的安全風險。
關鍵子類與典型場景
1. ??UsernamePasswordAuthenticationToken
(最常用)??
用于??表單登錄或 HTTP 基本認證??,表示“用戶名+密碼”的認證請求或結果。
??使用示例??:
// 認證請求階段(未認證)
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken("username", // principal(用戶主體)"password" // credentials(密碼憑證)
);// 認證成功后(已認證,包含權限)
Authentication authenticatedToken = new UsernamePasswordAuthenticationToken(user, // principal(用戶對象)null, // 憑證已清理(eraseCredentials())authorities // 權限集合(如 ROLE_USER)
);
2. ??JwtAuthenticationToken
(JWT 場景)??
用于??JWT 令牌認證??,表示通過 JWT 令牌完成的認證。
??自定義示例??:
public class JwtAuthenticationToken extends AbstractAuthenticationToken {private final String token; // JWT 令牌字符串private UserDetails userDetails; // 解析后的用戶詳情// 構造未認證的 JWT 令牌(僅包含令牌字符串)public JwtAuthenticationToken(String token) {super(null); // 初始權限為空this.token = token;setAuthenticated(false); // 未認證}// 構造已認證的 JWT 令牌(包含用戶詳情和權限)public JwtAuthenticationToken(UserDetails userDetails, Collection<? extends GrantedAuthority> authorities) {super(authorities);this.userDetails = userDetails;this.token = null; // 認證后無需保留原始令牌(可選)setAuthenticated(true); // 標記為已認證}@Overridepublic Object getPrincipal() {return userDetails != null ? userDetails.getUsername() : token;}@Overridepublic Object getCredentials() {return token; // 憑證是 JWT 令牌本身(認證后可能被清理)}@Overridepublic void eraseCredentials() {super.eraseCredentials();this.token = null; // 清理令牌(可選)}
}
3. ??AnonymousAuthenticationToken
(匿名用戶場景)??
用于??未登錄用戶的匿名訪問??,表示一個“匿名主體”(如訪客用戶)。
??特點??:
- 認證狀態為
true
(視為已認證,但權限受限)。 - 主體通常是
AnonymousAuthenticationToken
自身的實例。
核心方法與設計細節
1. ??構造方法??
AbstractAuthenticationToken
提供了兩個構造方法:
// 構造未認證的令牌(權限集合由參數指定)
public AbstractAuthenticationToken(Collection<? extends GrantedAuthority> authorities) {this.authorities = Collections.unmodifiableList(new ArrayList<>(authorities));
}// 構造已認證的令牌(權限集合由參數指定)
protected AbstractAuthenticationToken(Collection<? extends GrantedAuthority> authorities, Object principal, Object credentials) {this.authorities = authorities;this.principal = principal;this.credentials = credentials;setAuthenticated(true);
}
- 子類通常根據場景選擇構造方法(如
UsernamePasswordAuthenticationToken
在認證前使用無權限構造,認證后使用帶權限構造)。
2. ??setAuthenticated(boolean)
的限制??
默認情況下,AbstractAuthenticationToken
的 setAuthenticated(boolean)
方法會拋出 IllegalArgumentException
,因為??部分令牌的認證狀態應由 Spring Security 自動管理??(如 UsernamePasswordAuthenticationToken
)。
??示例(UsernamePasswordAuthenticationToken
的實現)??:
@Override
public void setAuthenticated(boolean isAuthenticated) {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);
}
- 若需手動設置認證狀態(如自定義令牌),需覆蓋此方法(如
AnonymousAuthenticationToken
)。
3. ??eraseCredentials()
的安全實踐??
AbstractAuthenticationToken
要求子類在認證完成后清理敏感憑證(如密碼),防止內存泄漏導致的信息泄露。典型實現:
@Override
public void eraseCredentials() {super.eraseCredentials();this.credentials = null; // 清空憑證字段
}
與 Authentication
接口的關系
Authentication
是接口,定義了認證令牌的行為規范(如獲取主體、權限、認證狀態)。AbstractAuthenticationToken
是其抽象實現,提供了基礎結構與默認方法,降低了自定義令牌的實現成本。
總結
AbstractAuthenticationToken
是 Spring Security 認證流程中??認證令牌的核心抽象類??,通過提供基礎結構、默認方法和安全規范,簡化了具體認證令牌(如 UsernamePasswordAuthenticationToken
、JwtAuthenticationToken
)的實現。它確保了認證令牌的一致性,是連接“認證請求”與“認證結果”的關鍵橋梁,也是開發者自定義認證邏輯的重要基礎。