📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados em Especialização em Backend com Java e Spring Boot. Recomendado revisar antes de começar.

🚀 Guia Didático: Segurança com Spring Security e JWT

Bem-vindo ao Módulo 6 do nosso plano de expansão! Agora que nossa aplicação está testada e funcionando, vamos dar o próximo passo rumo ao nível profissional: Segurança.

Neste guia, vamos aprender a proteger nossa API da Biblioteca de Jogos usando o framework Spring Security e tokens JWT (JSON Web Token) para autenticação sem estado (stateless).


O que vamos aprender?


Passo 1: Adicionando as Dependências no pom.xml

Para trabalhar com segurança e JWT, precisamos adicionar o starter do Spring Security e uma biblioteca para manipulação de tokens JWT. Vamos usar a biblioteca jjwt, que é muito robusta e popular.

Abra o arquivo pom.xml e adicione as seguintes dependências:

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Dependências para o JWT -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

Passo 2: Configuração Básica do Spring Security

Por padrão, ao adicionar o Spring Security, ele bloqueia todas as rotas da aplicação e gera uma senha aleatória no console. Vamos criar uma classe de configuração para dizer ao Spring como queremos que a segurança funcione.

Crie a classe SecurityConfig.java no pacote br.com.bibliotecajogos.config:

package br.com.bibliotecajogos.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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            .csrf(csrf -> csrf.disable()) // Desabilita CSRF (comum em APIs REST)
            // Configura a sessão como STATELESS (sem estado), necessária para JWT
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) 
            .authorizeHttpRequests(authorize -> authorize
                // Permite que qualquer pessoa liste os jogos
                .requestMatchers("/jogos").permitAll() 
                // Apenas usuários logados com a role ADMIN podem criar ou excluir jogos
                .requestMatchers("/jogos/novo", "/jogos/excluir/**").hasRole("ADMIN") 
                // Qualquer outra requisição exige autenticação
                .anyRequest().authenticated() 
            )
            .build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // Define o codificador de senhas que usaremos no banco de dados
        return new BCryptPasswordEncoder();
    }
}

Passo 3: Entendendo a Estrutura do JWT

O JSON Web Token é uma string longa dividida em 3 partes separadas por pontos (.):

  1. Header: Diz qual é o algoritmo usado (geralmente HS256).
  2. Payload: Contém as informações do usuário (ex: “id”: 1, “username”: “admin”, “role”: “ROLE_ADMIN”).
  3. Signature: É a assinatura digital que garante que ninguém alterou o token no meio do caminho.

Fluxo de Funcionamento:

  1. O cliente envia usuário e senha.
  2. O servidor valida, gera o Token JWT e devolve para o cliente.
  3. Nas próximas requisições, o cliente envia esse token no cabeçalho Authorization: Bearer <TOKEN>.
  4. O servidor valida o token e libera o acesso!

🎓 Dissecando o Código (Revisão Didática)

  1. @EnableWebSecurity: Diz ao Spring para desativar a segurança padrão e usar as regras que definimos nesta classe.
  2. csrf().disable(): O CSRF protege contra ataques em aplicações que usam cookies/sessões. Como usaremos JWT (stateless), podemos desabilitá-lo.
  3. SessionCreationPolicy.STATELESS: Garante que o Spring não criará sessões HTTP no servidor. Cada requisição deve ser independente e trazer seu próprio token.
  4. hasRole("ADMIN"): É aqui que a mágica da Autorização acontece. O Spring verifica se o usuário autenticado possui essa permissão antes de liberar o acesso à rota.

Desafio para o Aluno

Pesquise sobre a diferença entre .hasRole("ADMIN") e .hasAuthority("ADMIN") no Spring Security. Como isso muda a forma como guardamos as permissões no banco de dados?

—`

🚀 Como Executar no Laboratório

1. Abra o terminal na pasta deste projeto

No seu editor/IDE, abra a pasta deste projeto (File > Open Folder) ou navegue via terminal:

cd javaweb_jogos_guia_seguranca

2. Execute a aplicação e os testes

./mvnw spring-boot:run
./mvnw test

[!TIP] Dica para execução a partir da raiz do repositório: Se você abriu o repositório completo no VS Code, basta navegar até a pasta antes de executar: cd proj_aplicacoes_full_stack/projetos/javaweb_jogos_guia_seguranca