Reviews Spring Security best practices for authentication, authorization, input validation, CSRF, secret management, security headers, rate limiting, and dependency security in Java Spring Boot services.
How this skill is triggered — by the user, by Claude, or both
Slash command
/everything-claude-code:springboot-securityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
在添加认证、处理输入、创建端点或处理密钥时使用。
在添加认证、处理输入、创建端点或处理密钥时使用。
httpOnly、Secure、SameSite=Strict CookieOncePerRequestFilter 或资源服务器验证令牌@Component
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtService jwtService;
public JwtAuthFilter(JwtService jwtService) {
this.jwtService = jwtService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
Authentication auth = jwtService.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(auth);
}
chain.doFilter(request, response);
}
}
@EnableMethodSecurity@PreAuthorize("hasRole('ADMIN')") 或 @PreAuthorize("@authz.canEdit(#id)")@RestController
@RequestMapping("/api/admin")
public class AdminController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/users")
public List<UserDto> listUsers() {
return userService.findAll();
}
@PreAuthorize("@authz.isOwner(#id, authentication)")
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
@Valid@NotBlank、@Email、@Size、自定义验证器// 错误:没有验证
@PostMapping("/users")
public User createUser(@RequestBody UserDto dto) {
return userService.create(dto);
}
// 正确:已验证的 DTO
public record CreateUserDto(
@NotBlank @Size(max = 100) String name,
@NotBlank @Email String email,
@NotNull @Min(0) @Max(150) Integer age
) {}
@PostMapping("/users")
public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserDto dto) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(userService.create(dto));
}
:param 绑定;绝不拼接字符串// 错误:原生查询中的字符串拼接
@Query(value = "SELECT * FROM users WHERE name = '" + name + "'", nativeQuery = true)
// 正确:参数化原生查询
@Query(value = "SELECT * FROM users WHERE name = :name", nativeQuery = true)
List<User> findByName(@Param("name") String name);
// 正确:Spring Data 派生查询(自动参数化)
List<User> findByEmailAndActiveTrue(String email);
PasswordEncoder Bean,而非手动哈希@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12); // 成本因子 12
}
// 在服务中
public User register(CreateUserDto dto) {
String hashedPassword = passwordEncoder.encode(dto.password());
return userRepository.save(new User(dto.email(), hashedPassword));
}
http
.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
application.yml 无凭据;使用占位符# 错误:在 application.yml 中硬编码
spring:
datasource:
password: mySecretPassword123
# 正确:环境变量占位符
spring:
datasource:
password: ${DB_PASSWORD}
# 正确:Spring Cloud Vault 集成
spring:
cloud:
vault:
uri: https://vault.example.com
token: ${VAULT_TOKEN}
http
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'"))
.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)
.xssProtection(Customizer.withDefaults())
.referrerPolicy(rp -> rp.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER)));
*@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://app.example.com"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
config.setAllowCredentials(true);
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
return source;
}
// 在 SecurityFilterChain 中:
http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
// 使用 Bucket4j 进行每端点速率限制
@Component
public class RateLimitFilter extends OncePerRequestFilter {
private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
private Bucket createBucket() {
return Bucket.builder()
.addLimit(Bandwidth.classic(100, Refill.intervally(100, Duration.ofMinutes(1))))
.build();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
String clientIp = request.getRemoteAddr();
Bucket bucket = buckets.computeIfAbsent(clientIp, k -> createBucket());
if (bucket.tryConsume(1)) {
chain.doFilter(request, response);
} else {
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
response.getWriter().write("{\"error\": \"Rate limit exceeded\"}");
}
}
}
记住:默认拒绝、验证输入、最小权限、配置优先安全。
npx claudepluginhub aaione/everything-claude-code-zhReviews Spring Boot security best practices for authentication (JWT/OAuth2/Session), authorization (@PreAuthorize), input validation, CSRF/CORS/headers, secrets management, rate limiting, and dependency vulnerabilities.
Reviews Spring Security best practices for authentication, authorization, input validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.
Reviews existing Spring Security configs or implements JWT auth, OAuth2, method-level security, CORS, and CSRF in Spring Boot projects. Audits for OWASP issues like exposed actuators and weak hashing.