Skip to main content
spring-boot-security-jwt 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.
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-security-jwtコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... typescript-security-review Provides security review capability for TypeScript/Node.js applications, validates code against XSS, injection, CSRF, JWT/OAuth2 flaws, dependency CVEs, and secrets exposure. Use when performing security audits, before deployment, reviewing authentication/authorization implementations, or ensuring OWASP compliance for Express, NestJS, and Next.js. Triggers on "security review", "check for security issues", "TypeScript security audit".
name spring-boot-security-jwt description 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. allowed-tools Read, Write, Edit, Bash, Glob, Grep
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-securitycompile spring-boot-starter-oauth2-resource-servercompile io.jsonwebtoken:jjwt-api:0.12.6compile io.jsonwebtoken:jjwt-impl:0.12.6runtime io.jsonwebtoken:jjwt-jackson:0.12.6runtime spring-security-testtest
Key Configuration Properties Property Example Value Notes jwt.secret${JWT_SECRET}Min 256 bits, never hardcode jwt.access-token-expiration90000015 min in milliseconds jwt.refresh-token-expiration6048000007 days in milliseconds jwt.issuermy-appValidated on every token jwt.cookie-namejwt-tokenFor cookie-based auth jwt.cookie-http-onlytrueAlways true in production jwt.cookie-securetrueAlways 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 for exact Maven/Gradle snippets.
Step 2 — Configure application.yml 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
Step 3 — Implement JwtService Core operations: generate access token, generate refresh token, extract username, validate token.
@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 ;
}
}
}
Step 4 — Create JwtAuthenticationFilter Extend OncePerRequestFilter to extract a JWT from the Authorization: Bearer header (or HttpOnly cookie), validate it, and set the SecurityContext.
@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);
}
}
Step 5 — Configure SecurityFilterChain @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();
}
}
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).
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).
Step 8 — Add Authorization Rules Use @EnableMethodSecurity and @PreAuthorize annotations for fine-grained control:
@PreAuthorize("hasRole('ADMIN')")
public Page<UserResponse> getAllUsers (Pageable pageable) { ... }
@PreAuthorize("hasPermission(#documentId, 'Document', 'READ')")
public Document getDocument (Long documentId) { ... }
Step 9 — Write Security Tests @SpringBootTest
@AutoConfigureMockMvc
class AuthControllerTest {
@Test
void shouldDenyAccessWithoutToken () throws Exception {
mockMvc.perform(get("/api/orders" ))
.andExpect(status().isUnauthorized());
}
@Test
@WithMockUser(roles = "ADMIN")
void shouldAllowAdminAccess () throws Exception {
mockMvc.perform(get("/api/admin/users" ))
.andExpect(status().isOk());
}
}
Best Practices
Token Security
Use minimum 256-bit secret keys — load from environment variables, never hardcode
Set short access token lifetimes (15 min); use refresh tokens for longer sessions
Implement token rotation: revoke old refresh token when issuing a new one
Use jti (JWT ID) claim for blacklisting on logout
Cookie vs Bearer Header
Prefer HttpOnly cookies for browser clients (XSS-safe)
Use Authorization: Bearer header for mobile/API clients
Set Secure, SameSite=Lax or Strict on cookies in production
Spring Security 6.x
Use SecurityFilterChain bean — never extend WebSecurityConfigurerAdapter
Disable CSRF only for stateless APIs; keep it enabled for session-based flows
Use @EnableMethodSecurity instead of deprecated @EnableGlobalMethodSecurity
Validate iss and aud claims; reject tokens from untrusted issuers
Performance
Cache UserDetails with @Cacheable to avoid DB lookup on every request
Cache signing key derivation (avoid re-computing HMAC key per request)
Use Redis for refresh token storage at scale
What NOT to Do
Do not store sensitive data (passwords, PII) in JWT claims — claims are only signed, not encrypted
Do not issue tokens with infinite lifetime
Do not accept tokens without validating signature and expiration
Do not share signing keys across environments
Examples
Basic Authentication Flow @RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthService authService;
@PostMapping("/authenticate")
public ResponseEntity<AuthResponse> authenticate (
@RequestBody LoginRequest request) {
return ResponseEntity.ok(authService.authenticate(request));
}
@PostMapping("/refresh")
public ResponseEntity<AuthResponse> refresh (@RequestBody RefreshRequest request) {
return ResponseEntity.ok(authService.refreshToken(request.refreshToken()));
}
@PostMapping("/logout")
public ResponseEntity<Void> logout () {
authService.logout();
return ResponseEntity.ok().build();
}
}
JWT Authorization on Controller Method @RestController
@RequestMapping("/api/admin")
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
@GetMapping("/users")
public ResponseEntity<List<UserResponse>> getAllUsers () {
return ResponseEntity.ok(adminService.getAllUsers());
}
}
References File Content references/jwt-quick-reference.md Dependencies, minimal service, common patterns references/jwt-complete-configuration.md Full config: properties, SecurityFilterChain, JwtService, OAuth2 RS references/configuration.md JWT config beans, CORS, CSRF, error handling, session options references/examples.md Complete application setup: controllers, services, entities references/authorization-patterns.md RBAC/ABAC entity model, PermissionEvaluator, SpEL expressions references/token-management.md Refresh token entity, rotation, blacklisting with Redis references/testing.md Unit and MockMvc tests, test utilities references/jwt-testing-guide.md Testcontainers, load testing, security test checklist references/security-hardening.md Security headers, HSTS, rate limiting, audit logging references/performance-optimization.md Caffeine cache config, async validation, connection pooling references/oauth2-integration.md Google/GitHub OAuth2 login, OAuth2UserService references/microservices-security.md Inter-service JWT propagation, resource server config references/migration-spring-security-6x.md Migration from Spring Security 5.x references/troubleshooting.md Common errors, debugging tips
Constraints and Warnings
Security Constraints
JWT tokens are signed but not encrypted — do not include sensitive data in claims
Always validate exp, iss, and aud claims before trusting the token
Signing keys must be at least 256 bits; never use weak keys in production
Load secrets from environment variables or secure vaults, never from config files
SameSite cookie attribute is essential for CSRF protection in cookie-based flows
Spring Security 6.x Constraints
WebSecurityConfigurerAdapter is removed — use SecurityFilterChain beans only
@EnableGlobalMethodSecurity is deprecated — use @EnableMethodSecurity
Lambda DSL is required for HttpSecurity configuration (no method chaining)
WebSecurityConfigurerAdapter.order() replaced by @Order on @Configuration classes
Token Constraints
Access tokens should expire in 5-15 minutes for security
Refresh tokens should be stored server-side (DB or Redis), never in localStorage
Implement token blacklisting for immediate revocation on logout
jti claim is required for token blacklisting to work correctly
Related Skills
spring-boot-dependency-injection — Constructor injection patterns used throughout
spring-boot-rest-api-standards — REST API security patterns and error handling
unit-test-security-authorization — Testing Spring Security configurations
spring-data-jpa — User entity and repository patterns
spring-boot-actuator — Security monitoring and health endpoints