Spring Boot Security Core

发布于:2025-06-27 ⋅ 阅读:(20) ⋅ 点赞:(0)

依赖配置(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";
    }
}

关键类说明

  1. SecurityContextHolder

    • 位置:org.springframework.security.core.context.SecurityContextHolder

    • 作用:Spring Security 的安全上下文容器,存储当前线程的安全信息

    • 核心方法:getContext() 获取当前安全上下文

  2. 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("管理员专属内容");
    }
}

常见问题解决方案

  1. 返回 null 而不是用户名

    java

    复制

    下载

    // 使用 getPrincipal() 替代 getName()
    Object principal = authentication.getPrincipal();
    if (principal instanceof UserDetails) {
        return ((UserDetails) principal).getUsername();
    } else if (principal instanceof String) {
        return (String) principal;
    }
  2. 匿名用户处理

    java

    复制

    下载

    // 检查匿名用户
    if (authentication instanceof AnonymousAuthenticationToken) {
        return "ANONYMOUS";
    }
  3. 自定义用户ID

    java

    复制

    下载

    // 实现自定义UserDetails
    public class CustomUserDetails implements UserDetails {
        private String userId; // 使用用户ID代替用户名
        
        // 其他实现...
        
        @Override
        public String getUsername() {
            return userId; // 返回用户ID
        }
    }
  4. 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 是获取当前用户信息的标准方式:

  1. 通过 getAuthentication() 获取认证信息

  2. 通过 getName() 或 getPrincipal() 获取用户标识

  3. 检查 isAuthenticated() 确保用户已认证

  4. 处理匿名用户情况

在实际项目中,通常会创建 SecurityUtils 工具类封装这些安全相关操作,提高代码复用性和可维护性。


网站公告

今日签到

点亮在社区的每一天
去签到