跳到正文
cccskills
免费在 GitHub 公开

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.

中文简介正在准备中。当前显示原文说明。

集成工具Redis
查看安装方法

包含的文件(20)

  • SKILL.md15.1 KB
  • assets/generate-jwt-keys.sh3.8 KB
  • references/authorization-patterns.md20.4 KB
  • references/configuration.md28.7 KB
  • references/examples.md27.9 KB
  • references/jwt-complete-configuration.md21.7 KB
  • references/jwt-configuration.md16.1 KB
  • references/jwt-quick-reference.md12.2 KB
  • references/jwt-testing-guide.md28.4 KB
  • references/microservices-security.md20.4 KB
  • references/migration-spring-security-6x.md14.1 KB
  • references/oauth2-integration.md23.4 KB
  • references/performance-optimization.md20.1 KB
  • references/security-hardening.md27.6 KB
  • references/structure.md5.2 KB
  • references/testing-jwt-security.md27.8 KB
  • references/testing.md40.5 KB
  • references/token-management.md24.0 KB
  • references/troubleshooting.md23.1 KB
  • scripts/test-jwt-setup.sh7.7 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

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)

ArtifactScope
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

See references/jwt-quick-reference.md for Maven and Gradle snippets.

Key Configuration Properties

PropertyExample ValueNotes
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

AnnotationExample
@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   # true in production

See 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.

@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 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.

@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 for the cookie-based variant.

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();
    }
}

See 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 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 for RefreshToken entity, rotation logic, and Redis-based blacklisting.

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) { ... }

See references/authorization-patterns.md for RBAC entity model, PermissionEvaluator, and ABAC patterns.

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());
    }
}

See references/testing.md and references/jwt-testing-guide.md for full test suites, Testcontainers setup, and a security test checklist.

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());
    }
}

See references/examples.md for complete entity models and service implementations.

References

FileContent
references/jwt-quick-reference.mdDependencies, minimal service, common patterns
references/jwt-complete-configuration.mdFull config: properties, SecurityFilterChain, JwtService, OAuth2 RS
references/configuration.mdJWT config beans, CORS, CSRF, error handling, session options
references/examples.mdComplete application setup: controllers, services, entities
references/authorization-patterns.mdRBAC/ABAC entity model, PermissionEvaluator, SpEL expressions
references/token-management.mdRefresh token entity, rotation, blacklisting with Redis
references/testing.mdUnit and MockMvc tests, test utilities
references/jwt-testing-guide.mdTestcontainers, load testing, security test checklist
references/security-hardening.mdSecurity headers, HSTS, rate limiting, audit logging
references/performance-optimization.mdCaffeine cache config, async validation, connection pooling
references/oauth2-integration.mdGoogle/GitHub OAuth2 login, OAuth2UserService
references/microservices-security.mdInter-service JWT propagation, resource server config
references/migration-spring-security-6x.mdMigration from Spring Security 5.x
references/troubleshooting.mdCommon 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

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Use when adding monitoring, metrics, logging, or tracing to Spring AI or LLM integration code. Covers token tracking, latency measurement, cost estimation, and prompt/response logging. Use when user mentions AI monitoring, token costs, or LLM observability.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

android

免费

Provides expert knowledge for building modern native Android apps using Kotlin, Jetpack Compose, Material Design 3, MVI architecture, Hilt dependency injection, and Media3/ExoPlayer.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

Design, implement, review, and audit Android Jetpack Compose UI/UX for phone interfaces. Use when a request concerns concrete Compose layout, components, interaction, accessibility, or visual behavior. Do not activate for framework or dependency presence alone; non-UI Android work is excluded.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

Provides expert knowledge for designing, implementing, and managing REST API versioning strategies with deprecation workflows.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

astro

免费

Provides expert knowledge for building Astro 5+ sites with Islands Architecture, Content Collections, TypeScript, and performance-first rendering strategies.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

Audits token storage mechanisms to prevent XSS-based JWT theft.

中文简介正在准备中。当前显示原文说明。

lgzarturo/springboot-course32026年10月20日 更新

查看 lgzarturo 的全部技能

报告此技能的问题