依賴配置(Maven)
xml
復制
下載
運行
<!-- Spring Security Core --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>6.2.5</version> <!-- 使用最新版本 --> </dependency><!-- 如果使用Web安全 --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>6.2.5</version> </dependency><!-- 如果使用配置 --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>6.2.5</version> </dependency>
要正確實現?getCurrentUserId()
?方法,需要導入以下 Spring Security 相關的包:
java
復制
下載
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder;
完整代碼示例
java
復制
下載
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder;public class SecurityUtils {/*** 獲取當前用戶ID(需要根據實際認證系統實現)* * 此方法從Spring Security的SecurityContextHolder中獲取當前認證信息,* 并返回用戶名作為用戶ID。如果用戶未認證,返回"ANONYMOUS"。* * @return 當前用戶ID或"ANONYMOUS"*/public static String getCurrentUserId() {// 從SecurityContextHolder獲取認證信息Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication != null && authentication.isAuthenticated()) {// 返回用戶名(可根據需要調整為其他用戶標識)return authentication.getName();}return "ANONYMOUS";} }
關鍵類說明
-
SecurityContextHolder
:-
位置:
org.springframework.security.core.context.SecurityContextHolder
-
作用:Spring Security 的安全上下文容器,存儲當前線程的安全信息
-
核心方法:
getContext()
?獲取當前安全上下文
-
-
Authentication
:-
位置:
org.springframework.security.core.Authentication
-
作用:表示用戶認證信息的接口
-
核心方法:
-
getName()
:獲取用戶名(通常是用戶ID) -
isAuthenticated()
:檢查用戶是否已認證 -
getPrincipal()
:獲取用戶主體(可能是用戶名或UserDetails對象) -
getAuthorities()
:獲取用戶權限
-
-
實際項目中的增強實現
在真實項目中,您可能需要更完整的實現:
java
復制
下載
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails;public class SecurityUtils {/*** 獲取當前用戶ID*/public static String getCurrentUserId() {Authentication authentication = getAuthentication();if (authentication != null && authentication.isAuthenticated()) {Object principal = authentication.getPrincipal();// 處理不同類型的Principalif (principal instanceof UserDetails) {return ((UserDetails) principal).getUsername();} else if (principal instanceof String) {return (String) principal;} else if (principal instanceof CustomUser) { // 自定義用戶對象return ((CustomUser) principal).getUserId();}}return "ANONYMOUS";}/*** 獲取當前用戶詳細信息*/public static UserDetails getCurrentUserDetails() {Authentication authentication = getAuthentication();if (authentication != null && authentication.isAuthenticated() &&authentication.getPrincipal() instanceof UserDetails) {return (UserDetails) authentication.getPrincipal();}return null;}/*** 檢查用戶是否具有特定角色*/public static boolean hasRole(String role) {Authentication authentication = getAuthentication();return authentication != null && authentication.getAuthorities().stream().anyMatch(a -> a.getAuthority().equals("ROLE_" + role));}/*** 安全獲取Authentication對象*/private static Authentication getAuthentication() {try {return SecurityContextHolder.getContext().getAuthentication();} catch (Exception e) {// 處理非Web環境或安全上下文未初始化的情況return null;}} }
使用場景示例
java
復制
下載
@RestController @RequestMapping("/api/user") public class UserController {@GetMapping("/profile")public ResponseEntity<UserProfile> getUserProfile() {String userId = SecurityUtils.getCurrentUserId();// 防止匿名訪問if ("ANONYMOUS".equals(userId)) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();}UserProfile profile = userService.getProfile(userId);return ResponseEntity.ok(profile);}@PreAuthorize("hasRole('ADMIN')")@GetMapping("/admin")public ResponseEntity<String> adminOnly() {return ResponseEntity.ok("管理員專屬內容");} }
常見問題解決方案
-
返回 null 而不是用戶名:
java
復制
下載
// 使用 getPrincipal() 替代 getName() Object principal = authentication.getPrincipal(); if (principal instanceof UserDetails) {return ((UserDetails) principal).getUsername(); } else if (principal instanceof String) {return (String) principal; }
-
匿名用戶處理:
java
復制
下載
// 檢查匿名用戶 if (authentication instanceof AnonymousAuthenticationToken) {return "ANONYMOUS"; }
-
自定義用戶ID:
java
復制
下載
// 實現自定義UserDetails public class CustomUserDetails implements UserDetails {private String userId; // 使用用戶ID代替用戶名// 其他實現...@Overridepublic String getUsername() {return userId; // 返回用戶ID} }
-
JWT 集成:
java
復制
下載
// 在JWT認證中獲取用戶ID public class JwtAuthenticationFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {String token = getToken(request);if (token != null && jwtUtil.validateToken(token)) {String userId = jwtUtil.getUserIdFromToken(token);// 創建認證信息UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userId, null, authorities);SecurityContextHolder.getContext().setAuthentication(auth);}chain.doFilter(request, response);} }
總結
核心導入包:
java
復制
下載
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder;
在 Spring Security 環境中,SecurityContextHolder
?是獲取當前用戶信息的標準方式:
-
通過?
getAuthentication()
?獲取認證信息 -
通過?
getName()
?或?getPrincipal()
?獲取用戶標識 -
檢查?
isAuthenticated()
?確保用戶已認證 -
處理匿名用戶情況
在實際項目中,通常會創建?SecurityUtils
?工具類封裝這些安全相關操作,提高代碼復用性和可維護性。