> 技术文档 > Spring Boot 3整合Spring Security 6全攻略:从零构建安全防线_springboot3 security6

Spring Boot 3整合Spring Security 6全攻略:从零构建安全防线_springboot3 security6


🔒 Spring Boot 3整合Spring Security 6全攻略:从零构建安全防线

#SpringSecurity #SpringBoot3 #安全认证 #JWT

一、环境准备与版本匹配

技术栈选型

组件 版本 必要性说明 Spring Boot 3.2.0+ 要求JDK17+ Spring Security 6.2.0+ 全新配置链式API Java 17+ Records特性优化DTO封装 Lombok 1.18.30 简化实体类开发
 org.springframework.boot spring-boot-starter-security com.baomidou mybatis-plus-spring-boot3-starter {version} com.mysql mysql-connector-j runtime

二、基础安全配置四步曲

1. 安全配置类(Lambda DSL新写法)

@Configuration@EnableWebSecurity@EnableMethodSecuritypublic class SecurityConfig { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtUtil jwtUtil; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers(\"/api/auth/login\").permitAll() .anyRequest().authenticated() ) .addFilterBefore(new JwtAuthenticationFilter(jwtUtil, userDetailsService), UsernamePasswordAuthenticationFilter.class); return http.build(); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin(\"http://localhost:8080/\"); // 允许的源 config.setAllowCredentials(true); // 是否允许发送凭证(如 cookies) config.addAllowedMethod(\"*\"); // 允许的方法 config.addAllowedHeader(\"*\"); // 允许的头 config.addExposedHeader(\"*\"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(\"/**\", config); return source; } @Bean public AuthenticationManager authenticationManager( AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }}

三、数据库用户认证实战

1. 用户实体类设计

@Getter@Setter@ToStringpublic class User implements Serializable, UserDetails { private static final long serialVersionUID = 1L; /** * 用户ID */ private String id; /** * 用户名称 */ private String username; /** * 密码 */ private String password; @TableField(exist = false) private List<String> roleIdList; /** * 账户是否未过期(1未过期 0已过期) */ private boolean isAccountNonExpired = true; /** * 账户是否未锁定(1未锁定 0已锁定) */ private boolean isAccountNonLocked = true; /** * 密码是否未过期(1未过期 0已过期) */ private boolean isCredentialsNonExpired = true; /** * 账户是否可用(1可用 0不可用) */ private boolean isEnabled = true; // 实现UserDetails接口方法 @Override public Collection<? extends GrantedAuthority> getAuthorities() { return roles.stream() .map(SimpleGrantedAuthority::new) .toList(); }}

2. 自定义UserDetailsService

@Servicepublic class UserDetailsServiceImpl implements UserDetailsService { @Autowired private IUserService userService; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userService.selectUserByUserName(username); if (user == null) { throw new UsernameNotFoundException(\"用户不存在\"); } return user; }}

四、JWT整合方案(REST API安全)

1. JWT工具类

import com.auth0.jwt.JWT;import com.auth0.jwt.JWTCreator;import com.auth0.jwt.algorithms.Algorithm;import com.auth0.jwt.exceptions.AlgorithmMismatchException;import com.auth0.jwt.exceptions.JWTVerificationException;import com.auth0.jwt.exceptions.SignatureVerificationException;import com.auth0.jwt.exceptions.TokenExpiredException;import com.auth0.jwt.interfaces.DecodedJWT;import com.blog.common.enums.ResultCode;import com.blog.common.exception.CommonException;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import java.util.Calendar;import java.util.Date;import java.util.Map;@Componentpublic class JwtUtil { @Value(\"${jwt.issuer}\") private String issuer; @Value(\"${jwt.secret}\") private String secret; @Value(\"${jwt.expiration}\") private int expiration; public String generateToken(Map<String, String> map) { //设置令牌的过期时间 Calendar instance = Calendar.getInstance(); instance.add(Calendar.MINUTE, expiration); JWTCreator.Builder builder = JWT.create(); map.forEach(builder::withClaim); return builder.withIssuer(issuer) .withIssuedAt(new Date()) .withExpiresAt(instance.getTime()) .sign(Algorithm.HMAC256(secret)); } /** * 解析领陪 * * @param token * @return */ public DecodedJWT jwtDecode(String token) { try { return JWT.require(Algorithm.HMAC256(secret)).build().verify(token); } catch (SignatureVerificationException e) { throw new CommonException(ResultCode.TOKEN_SIGNATURE_ERROR); } catch (AlgorithmMismatchException e) { throw new CommonException(ResultCode.TOKEN_ALGORITHM_MISMATCH); } catch (TokenExpiredException e) { throw new CommonException(ResultCode.TOKEN_EXPIRED); } catch (Exception e) { throw new CommonException(ResultCode.TOKEN_ERROR); } } /** * 校验令牌 * * @param token * @return */ public boolean validateToken(String token) { try { JWT.require(Algorithm.HMAC256(secret)).build().verify(token); } catch (JWTVerificationException e) { return false; } return true; } // 验证 Token 并提取用户名 public String getUsernameFromToken(String token) { DecodedJWT decodedJWT = jwtDecode(token); return decodedJWT.getClaim(\"username\").asString(); }}

2. JWT认证过滤器

import com.blog.common.utils.JwtUtil;import jakarta.servlet.FilterChain;import jakarta.servlet.ServletException;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import java.io.IOException;@Componentpublic class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtUtil jwtUtil; private final UserDetailsService userDetailsService; public JwtAuthenticationFilter(JwtUtil jwtUtil, UserDetailsService userDetailsService) { this.jwtUtil = jwtUtil; this.userDetailsService = userDetailsService; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = extractToken(request); if (token != null && jwtUtil.validateToken(token)) { String username = jwtUtil.getUsernameFromToken(token); UserDetails userDetails = userDetailsService.loadUserByUsername(username); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(  userDetails, null, userDetails.getAuthorities() ); SecurityContextHolder.getContext().setAuthentication(authentication); } filterChain.doFilter(request, response); } private String extractToken(HttpServletRequest request) { String bearerToken = request.getHeader(\"Authorization\"); if (bearerToken != null && bearerToken.startsWith(\"Bearer \")) { return bearerToken.substring(7); } return null; }}

五、安全测试与调试技巧

1. 接口测试

import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;@Controllerpublic class LoginController { @GetMapping(\"/login\") public LoginVo login(@RequestBody LoginDto loginDto) { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword()); // 认证 Authentication authenticate = authenticationManager.authenticate(authenticationToken); // 保存认证状态 SecurityContextHolder.getContext().setAuthentication(authenticate); //获取用户信息 User user = (User) authenticate.getPrincipal(); LoginVo loginVo = new LoginVo(); loginVo.setId(user.getId()); Map<String, String> map = new HashMap<>(); map.put(\"id\", user.getId()); map.put(\"username\", user.getUsername()); String token = jwtUtil.generateToken(map); loginVo.setToken(token); return loginVo; }}

2. 安全日志监控配置

# application.propertieslogging.level.org.springframework.security=DEBUGlogging.level.org.springframework.web=INFO

六、生产环境加固建议

  1. 密码存储:必须使用BCrypt/SCrypt等强哈希算法
  2. HTTPS强制:配置server.ssl.enabled=true
  3. CSRF保护:正式环境务必启用
  4. 速率限制:集成Spring Boot Starter Actuator监控
  5. 安全头配置
http.headers(headers -> headers .contentSecurityPolicy(csp -> csp.policyDirectives(\"default-src \'self\'\")) .httpStrictTransportSecurity(hsts -> hsts.includeSubDomains(true)));