Claude
Skills
Sign in
Back

spring-boot-security-jwt

Included with Lifetime
$97 forever

Provides JWT authentication and authorization patterns for Spring Boot 3.5.x covering token generation with JJWT, Bearer/cookie authentication, database/OAuth2 integration, and RBAC/permission-based access control using Spring Security 6.x. Use when implementing authentication or authorization in Spring Boot applications.

Securityscriptsassets

What this skill does


# Spring Boot JWT Security

JWT authentication and authorization patterns for Spring Boot 3.5.x using Spring Security 6.x and JJWT. Covers token generation, validation, refresh strategies, RBAC/ABAC, and OAuth2 integration.

## Overview

This skill provides implementation patterns for stateless JWT authentication in Spring Boot applications. It covers the complete authentication flow including token generation with JJWT 0.12.6, Bearer/cookie-based authentication, refresh token rotation, and method-level authorization with `@PreAuthorize` expressions.

Key capabilities:
- Access and refresh token generation with configurable expiration
- Bearer token and HttpOnly cookie authentication strategies
- Integration with Spring Data JPA and OAuth2 providers
- RBAC with role/permission-based `@PreAuthorize` rules
- Token revocation and blacklisting for logout/rotation

## When to Use

Activate when user requests involve:
- "Implement JWT authentication", "secure REST API with tokens"
- "Spring Security 6.x configuration", "SecurityFilterChain setup"
- "Role-based access control", "RBAC", `` `@PreAuthorize` ``
- "Refresh token", "token rotation", "token revocation"
- "OAuth2 integration", "social login", "Google/GitHub auth"
- "Stateless authentication", "SPA backend security"
- "JWT filter", "OncePerRequestFilter", "Bearer token"
- "Cookie-based JWT", "HttpOnly cookie"
- "Permission-based access control", "custom PermissionEvaluator"

## Quick Reference

### Dependencies (JJWT 0.12.6)

| Artifact | Scope |
|----------|-------|
| `spring-boot-starter-security` | compile |
| `spring-boot-starter-oauth2-resource-server` | compile |
| `io.jsonwebtoken:jjwt-api:0.12.6` | compile |
| `io.jsonwebtoken:jjwt-impl:0.12.6` | runtime |
| `io.jsonwebtoken:jjwt-jackson:0.12.6` | runtime |
| `spring-security-test` | test |

See [references/jwt-quick-reference.md](references/jwt-quick-reference.md) for Maven and Gradle snippets.

### Key Configuration Properties

| Property | Example Value | Notes |
|----------|--------------|-------|
| `jwt.secret` | `${JWT_SECRET}` | Min 256 bits, never hardcode |
| `jwt.access-token-expiration` | `900000` | 15 min in milliseconds |
| `jwt.refresh-token-expiration` | `604800000` | 7 days in milliseconds |
| `jwt.issuer` | `my-app` | Validated on every token |
| `jwt.cookie-name` | `jwt-token` | For cookie-based auth |
| `jwt.cookie-http-only` | `true` | Always true in production |
| `jwt.cookie-secure` | `true` | Always true with HTTPS |

### Authorization Annotations

| Annotation | Example |
|-----------|---------|
| `@PreAuthorize("hasRole('ADMIN')")` | Role check |
| `@PreAuthorize("hasAuthority('USER_READ')")` | Permission check |
| `@PreAuthorize("hasPermission(#id, 'Doc', 'READ')")` | Domain object check |
| `@PreAuthorize("@myService.canAccess(#id)")` | Spring bean check |

## Instructions

### Step 1 — Add Dependencies

Include `spring-boot-starter-security`, `spring-boot-starter-oauth2-resource-server`, and the three JJWT artifacts in your build file. See [references/jwt-quick-reference.md](references/jwt-quick-reference.md) for exact Maven/Gradle snippets.

### Step 2 — Configure application.yml

```yaml
jwt:
  secret: ${JWT_SECRET:change-me-min-32-chars-in-production}
  access-token-expiration: 900000
  refresh-token-expiration: 604800000
  issuer: my-app
  cookie-name: jwt-token
  cookie-http-only: true
  cookie-secure: false   # true in production
```

See [references/jwt-complete-configuration.md](references/jwt-complete-configuration.md) for the full properties reference.

### Step 3 — Implement JwtService

Core operations: generate access token, generate refresh token, extract username, validate token.

```java
@Service
public class JwtService {

    public String generateAccessToken(UserDetails userDetails) {
        return Jwts.builder()
            .subject(userDetails.getUsername())
            .issuer(issuer)
            .issuedAt(new Date())
            .expiration(new Date(System.currentTimeMillis() + accessTokenExpiration))
            .claim("authorities", getAuthorities(userDetails))
            .signWith(getSigningKey())
            .compact();
    }

    public boolean isTokenValid(String token, UserDetails userDetails) {
        try {
            String username = extractUsername(token);
            return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
        } catch (JwtException e) {
            return false;
        }
    }
}
```

See [references/jwt-complete-configuration.md](references/jwt-complete-configuration.md) for the complete JwtService including key management and claim extraction.

### Step 4 — Create JwtAuthenticationFilter

Extend `OncePerRequestFilter` to extract a JWT from the `Authorization: Bearer` header (or HttpOnly cookie), validate it, and set the `SecurityContext`.

```java
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            chain.doFilter(request, response);
            return;
        }
        String jwt = authHeader.substring(7);
        String username = jwtService.extractUsername(jwt);
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (jwtService.isTokenValid(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authToken =
                    new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        chain.doFilter(request, response);
    }
}
```

See [references/configuration.md](references/configuration.md) for the cookie-based variant.

### Step 5 — Configure SecurityFilterChain

```java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(AbstractHttpConfigurer::disable)
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**", "/swagger-ui/**").permitAll()
                .anyRequest().authenticated()
            )
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}
```

See [references/jwt-complete-configuration.md](references/jwt-complete-configuration.md) for CORS, logout handler, and OAuth2 login integration.

### Step 6 — Create Authentication Endpoints

Expose `/register`, `/authenticate`, `/refresh`, and `/logout` via `@RestController`. Return `accessToken` + `refreshToken` in the response body (and optionally set an HttpOnly cookie).

See [references/examples.md](references/examples.md) for the complete `AuthenticationController` and `AuthenticationService`.

### Step 7 — Implement Refresh Token Strategy

Store refresh tokens in the database with `user_id`, `expiry_date`, `revoked`, and `expired` columns. On `/refresh`, verify the stored token, revoke it, and issue a new pair (token rotation).

See [references/token-management.md](references/token-management.md) for `RefreshToken` entity, rotation logic, and Redis-based blacklisting.

### Step 8 — Add Authorization Rules

Use `@EnableMethodSecurity` and `@PreAuthorize` annotations f

Related in Security