依赖配置(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(); // 处理不同类型的Principal if (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代替用户名 // 其他实现... @Override public String getUsername() { return userId; // 返回用户ID } }
JWT 集成:
java
复制
下载
// 在JWT认证中获取用户ID public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected 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
工具类封装这些安全相关操作,提高代码复用性和可维护性。