Spring Security 6 集成常见操作指南

Spring Security 6 集成常见操作指南

一、核心依赖与基础配置
1. 添加 Maven 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- 集成JWT时添加 -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.1</version>
</dependency>
<!-- 集成OAuth2时添加 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
2. 安全配置类(SecurityFilterChain)
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
            )
            .logout(logout -> logout
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            )
            .csrf(CsrfConfigurer::disable) // 开发环境可禁用CSRF
            .exceptionHandling(ex -> ex
                .accessDeniedPage("/403")
            );
        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
二、认证与授权核心操作
1. 自定义用户服务(UserDetailsService)
@Service
public class CustomUserService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) {
        return userRepository.findByUsername(username)
            .map(user -> User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .roles(user.getRoles())
                .build()
            )
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));
    }
}
2. 基于角色的访问控制
http.authorizeHttpRequests(auth -> auth
    .requestMatchers("/admin/**").hasRole("ADMIN")
    .requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
);
3. 方法级安全(@PreAuthorize)
@Service
public class DataService {

    @PreAuthorize("hasRole('ADMIN')")
    public void deleteData(Long id) {
        // 仅ADMIN可执行
    }
}
三、高级功能集成
1. JWT 集成
  • 生成JWT令牌
    public String generateToken(UserDetails userDetails) {
        return Jwts.builder()
            .setSubject(userDetails.getUsername())
            .claim("roles", userDetails.getAuthorities())
            .setExpiration(new Date(System.currentTimeMillis() + 86400000))
            .signWith(SignatureAlgorithm.HS256, "secretKey")
            .compact();
    }
    
  • JWT验证过滤器
    public class JwtFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
            String token = request.getHeader("Authorization");
            if (token != null && token.startsWith("Bearer ")) {
                String jwt = token.substring(7);
                Claims claims = Jwts.parser().setSigningKey("secretKey").parseClaimsJws(jwt).getBody();
                String username = claims.getSubject();
                UserDetails user = userDetailsService.loadUserByUsername(username);
                UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                    user, null, user.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(auth);
            }
            chain.doFilter(request, response);
        }
    }
    
2. OAuth2 集成
  • 配置application.yml
    spring:
      security:
        oauth2:
          client:
            registration:
              google:
                client-id: YOUR_CLIENT_ID
                client-secret: YOUR_CLIENT_SECRET
                scope: profile, email
            provider:
              google:
                authorization-uri: https://accounts.google.com/o/oauth2/auth
                token-uri: https://oauth2.googleapis.com/token
    
3. 动态权限控制
  • 从数据库加载权限
    public class DynamicAuthorityLoader {
        @Autowired
        private PermissionRepository permissionRepo;
    
        public List<GrantedAuthority> loadAuthorities(Long userId) {
            return permissionRepo.findByUserId(userId).stream()
                .map(perm -> new SimpleGrantedAuthority("ROLE_" + perm.getCode()))
                .collect(Collectors.toList());
        }
    }
    
四、会话与安全管理
1. 记住我(Remember-Me)
http.rememberMe(remember -> remember
    .key("uniqueAndSecret")
    .tokenValiditySeconds(1209600) // 14天
);
2. 会话管理
http.sessionManagement(session -> session
    .maximumSessions(1)
    .maxSessionsPreventsLogin(true)
);
3. 安全头配置
http.headers(headers -> headers
    .contentSecurityPolicy("default-src 'self'")
    .xssProtection(XssProtectionConfigurer::block)
);
五、测试与调试
1. 安全测试
@Test
@WithMockUser(username = "admin", roles = "ADMIN")
void testAdminAccess() throws Exception {
    mockMvc.perform(get("/admin"))
        .andExpect(status().isOk());
}
2. 日志审计
@EventListener
public void onAuthenticationSuccess(AuthenticationSuccessEvent event) {
    logger.info("User {} logged in from {}", 
        event.getAuthentication().getName(),
        event.getAuthenticationDetails());
}
六、迁移指南(5.x → 6.x)
  1. 配置类调整

    • 移除@EnableWebSecurity(6.x默认启用)。
    • 替换WebSecurityConfigurerAdapterSecurityFilterChain Bean。
  2. 路径匹配语法

    • antMatchers("/api/**")替换为requestMatchers("/api/**")
  3. 过滤器链控制

    • 使用SecurityFilterChain Bean显式定义多条链,通过@Order控制优先级。
七、最佳实践
  1. 密码安全:始终使用BCryptPasswordEncoder,避免明文存储。
  2. 最小权限原则:优先使用hasAuthority()替代hasRole()实现细粒度控制。
  3. 性能优化:对高频查询接口,结合缓存减少UserDetailsService调用。
  4. 安全头防护:启用CSP、XSS防护等,防御常见Web攻击。

通过以上步骤,您可快速集成Spring Security 6并实现企业级安全控制。核心原则是最小权限、加密存储、日志审计,结合Spring Security 6的Lambda DSL和组件化设计,可显著提升配置可读性与维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值