依赖配置(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
工具类封装这些安全相关操作,提高代码复用性和可维护性。