Pular para conteúdo

Aula 17 - Spring Security 6+ com Autenticação Stateless JWT 🛡️

Objetivo Pedagógico

Objetivo: Arquitetura de segurança corporativa com Spring Security 6, filtros customizados, autorização baseada em Roles/Authorities e tokens stateless JWT.


📑 1. Fundamentos Teóricos & Análise Técnica

No ecossistema Java corporativo, o Spring Security é a espinha dorsal para proteção de aplicações de missão crítica. Com o lançamento do Spring Boot 3 e Spring Security 6, a configuração de segurança foi profundamente modernizada: 1. Fim dos Adaptadores Legados: A classe WebSecurityConfigurerAdapter foi completamente extinta em favor de uma abordagem baseada em componentes funcionais com o bean SecurityFilterChain. 2. Arquitetura Baseada em Cadeia de Filtros (Filter Chain): Cada requisição atravessa uma sequência rigorosa de filtros de segurança (SecurityContextHolderFilter, UsernamePasswordAuthenticationFilter, filtros customizados). 3. Sessão Stateless: Para APIs REST modernas, a criação de sessões HTTP no servidor é desativada via SessionCreationPolicy.STATELESS. O contexto de segurança é reidratado a cada chamada através de um filtro que inspeciona o token JWT no cabeçalho Authorization: Bearer <token>.

📐 Arquitetura Conceitual & Diagrama de Fluxo

flowchart LR
    Req["Requisição HTTP"] --> Filter1["CorsFilter"]
    Filter1 --> Filter2["CsrfFilter"]
    Filter2 --> CustomFilter["JwtAuthenticationFilter (Custom)"]
    CustomFilter -->|Token Válido| Context["SecurityContextHolder (Autenticado!)"]
    CustomFilter --> FilterSecurity["AuthorizationFilter"]
    FilterSecurity --> Controller["Spring RestController"]
    style Req fill:#e1f5fe,stroke:#01579b
    style CustomFilter fill:#fff3e0,stroke:#e65100
    style Context fill:#e8f5e9,stroke:#2e7d32

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Configuração Funcional e Declarativa: Definição do SecurityFilterChain com lambdas fluentes legíveis. - Segurança Stateless: Eliminação de estado de sessão na JVM, viabilizando escalabilidade horizontal instantânea. - Controle de Acesso Fino: Uso da anotação @PreAuthorize("hasRole('ADMIN')") em nível de método. - Tratamento de Exceções de Segurança: Customização de AuthenticationEntryPoint (401) e AccessDeniedHandler (403).


🛠️ 2. Implementação Prática em Java 21, Spring Boot 3+ e Spring Security 6

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// SecurityConfig.java (Spring Security 6 com SecurityFilterChain)
package com.empresa.core.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;

    public SecurityConfig(JwtAuthenticationFilter jwtAuthFilter) {
        this.jwtAuthFilter = jwtAuthFilter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(csrf -> csrf.disable()) // Desativa CSRF para APIs REST Stateless
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/v1/auth/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
                .requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}

💡 Análise Passo a Passo do Código

  1. SessionCreationPolicy.STATELESS: Impede a alocação de cookies de sessão JSESSIONID, delegando toda autenticação ao token JWT.
  2. Regras com RequestMatchers: Define permissões públicas para rotas de autenticação e documentação, restringindo o restante.
  3. Filtro Customizado: addFilterBefore posiciona o interceptor de token JWT antes do filtro padrão de usuário/senha.

🎯 3. Próximos Passos & Sequência Didática