All Java templates

Spring Security Rules

SecurityFilterChain (no WebSecurityConfigurerAdapter), OAuth2 resource server, JWT.

DevZone Tools1,860 copiesUpdated Apr 8, 2026SpringJava
# CLAUDE.md — Spring Security

## Configuration

- Use the modern `SecurityFilterChain` bean approach. The deprecated `WebSecurityConfigurerAdapter` is gone.
- One `@Bean SecurityFilterChain` per filter chain. Multiple chains for `/api/**` vs `/admin/**` if their auth differs.
- Configure with the lambda DSL:
  ```java
  http.authorizeHttpRequests(auth -> auth
      .requestMatchers("/public/**").permitAll()
      .requestMatchers("/admin/**").hasRole("ADMIN")
      .anyRequest().authenticated()
  );
  ```
- Always end with `.anyRequest().authenticated()` (or `.denyAll()`). Default-allow is a foot-gun.

## Method security

- Enable with `@EnableMethodSecurity`. Use `@PreAuthorize` on service methods.
- `@PreAuthorize("hasRole('ADMIN')")` for role checks. Use SpEL for object-level: `@PreAuthorize("#user.id == authentication.name")`.
- Don't put auth checks in controllers. They live at the service boundary so non-HTTP callers (jobs, schedulers) get them too.

## Password handling

- `BCryptPasswordEncoder` with cost factor 12+. Re-evaluate yearly.
- Or `Argon2PasswordEncoder` if starting fresh.
- Use `DelegatingPasswordEncoder` (`PasswordEncoderFactories.createDelegatingPasswordEncoder()`) to support migration between algorithms.
- Never log raw passwords. Configure your error reporter to filter.

## OAuth2 Resource Server

- For JWT-protected APIs:
  ```java
  http.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt -> jwt.jwkSetUri(jwksUri)));
  ```
- Configure `JwtAuthenticationConverter` to map claims to authorities. Don't roll your own JWT validation.
- Validate `iss`, `aud`, and `exp` — set them in your authorization server, verify them here.

## CSRF

- Default-on for browser apps. Disable only for stateless APIs:
  ```java
  http.csrf(AbstractHttpConfigurer::disable);
  ```
- For session-based forms, use the cookie-based token strategy (`CookieCsrfTokenRepository`).
- Never disable CSRF on session-authenticated endpoints that mutate state.

## CORS

- Use `CorsConfigurationSource` bean. Define an explicit allowlist — never `allowedOrigins("*")` with `allowCredentials(true)` (Spring will refuse).
- Configure once globally for cross-origin APIs. Don't sprinkle `@CrossOrigin` on controllers.

## Session management

- Stateless APIs: `http.sessionManagement(sm -> sm.sessionCreationPolicy(STATELESS))`.
- Stateful (server-rendered): default is fine. Set `maximumSessions` and `expiredUrl` for fixed concurrency.
- Always invalidate sessions on logout: `http.logout(logout -> logout.invalidateHttpSession(true).deleteCookies("JSESSIONID"))`.

## Don't

- Don't put `permitAll()` on `**/*` to "fix" auth for now. The fix becomes permanent.
- Don't store auth tokens in `localStorage` from server-rendered Spring apps. HttpOnly cookies are the answer.
- Don't write your own `UserDetailsService` if Spring's defaults plus a JPA-backed one cover you.
- Don't expose actuator endpoints (`/actuator/**`) without auth. They leak everything.

Other Java templates