Pular para o conteúdo principal

Capítulo 1: Introdução ao Spring Security

Introdução​

Antes de configurar qualquer coisa, é essencial entender como o Spring Security funciona. Este capítulo estabelece as bases que permitirão configurar a segurança corretamente.


🎯 Objetivos do Capítulo​

Ao final deste capítulo, você saberá:

  1. ✅ Por que a segurança é essencial
  2. ✅ A diferença entre Authentication e Authorization
  3. ✅ A arquitetura do Spring Security
  4. ✅ Como funciona a cadeia de filtros
  5. ✅ Os conceitos-chave: Principal, Credentials, Authorities

1. Por que Proteger uma Aplicação?​

As Ameaças​

Exemplos Reais​

AnoEmpresaImpacto
2023MOVEit60M+ usuários afetados
2021Facebook533M contas expostas
2019Capital One100M+ dados roubados
2017Equifax147M dados pessoais

Os 3 Pilares da Segurança (CIA)​

┌─────────────────────────────────────────────────┐
│ │
│ C - Confidencialidade │
│ Somente pessoas autorizadas │
│ podem ver os dados │
│ │
│ I - Integridade │
│ Os dados não podem ser │
│ modificados sem autorização │
│ │
│ A - Disponibilidade │
│ O sistema permanece acessível │
│ para usuários legítimos │
│ │
└─────────────────────────────────────────────────┘

2. Authentication vs Authorization​

A Diferença Fundamental​

ConceitoPerguntaExemplo
Authentication"Quem é você?"Login com email/senha
Authorization"Você tem permissão?"Acessar /admin (reservado para admins)

Analogia: O Clube VIP​

No Spring Security​

// Authentication: Quem está conectado?
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName(); // "jean@example.com"

// Authorization: Quais são seus direitos?
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
// [ROLE_USER] - Não é ROLE_ADMIN!

3. Arquitetura do Spring Security​

Visão Geral​

Componentes-Chave​

1. SecurityFilterChain​

A cadeia de filtros que intercepta TODAS as requisições:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.build();
}
}

2. AuthenticationManager​

Coordena a autenticação:

3. UserDetailsService​

Interface para carregar usuários:

public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

4. PasswordEncoder​

Codifica as senhas (NUNCA em texto claro!):

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

// Utilização
String encoded = passwordEncoder.encode("monMotDePasse");
// $2a$10$N9qo8uLOickgx2ZMRZoMye...

boolean matches = passwordEncoder.matches("monMotDePasse", encoded);
// true

4. A Cadeia de Filtros em Detalhe​

Ordem dos Filtros (Simplificado)​

1. CorsFilter                    → Gestão CORS
2. CsrfFilter → Proteção CSRF
3. LogoutFilter → Gestão de logout
4. UsernamePasswordAuthFilter → Login via formulário
5. BasicAuthenticationFilter → HTTP Basic Auth
6. BearerTokenAuthFilter → JWT/OAuth2
7. AnonymousAuthenticationFilter → Usuário anônimo
8. ExceptionTranslationFilter → Gestão de erros
9. FilterSecurityInterceptor → Decisão final de acesso

Visualização do Fluxo​


5. Conceitos-Chave​

Principal​

A identidade do usuário conectado:

@GetMapping("/profile")
public String profile(Principal principal) {
String username = principal.getName();
return "Bem-vindo " + username;
}

Authentication Object​

Contém todas as informações de autenticação:

public interface Authentication {
Collection<? extends GrantedAuthority> getAuthorities(); // Papéis/Permissões
Object getCredentials(); // Senha (geralmente apagada após auth)
Object getDetails(); // Detalhes adicionais (IP, etc.)
Object getPrincipal(); // O usuário (UserDetails)
boolean isAuthenticated();
}

GrantedAuthority​

Representa um papel ou permissão:

// Papéis (prefixo ROLE_)
new SimpleGrantedAuthority("ROLE_ADMIN");
new SimpleGrantedAuthority("ROLE_USER");

// Permissões
new SimpleGrantedAuthority("READ_USERS");
new SimpleGrantedAuthority("WRITE_USERS");
new SimpleGrantedAuthority("DELETE_USERS");

SecurityContext​

Armazena a Authentication do usuário atual:

// Recuperar o usuário conectado
SecurityContext context = SecurityContextHolder.getContext();
Authentication auth = context.getAuthentication();

if (auth != null && auth.isAuthenticated()) {
String username = auth.getName();
// ...
}

UserDetails​

Interface que representa um usuário:

public interface UserDetails {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}

6. Tipos de Autenticação​

1. Form Login (Sessão)​

Cliente → POST /login (user, pass)
Servidor → Set-Cookie: JSESSIONID=xyz
Cliente → GET /api/data (Cookie: JSESSIONID=xyz)
Servidor → Verifica sessão → 200 OK

Vantagens: Simples, gerenciado pelo navegador
Desvantagens: Não adequado para APIs REST stateless

2. HTTP Basic​

Cliente → GET /api/data
Servidor → 401 + WWW-Authenticate: Basic
Cliente → GET /api/data (Authorization: Basic base64(user:pass))
Servidor → 200 OK

Vantagens: Simples
Desvantagens: Credenciais enviadas a cada requisição

3. JWT (Token)​

Cliente → POST /login (user, pass)
Servidor → {"token": "eyJhbGciOiJIUzI1..."}
Cliente → GET /api/data (Authorization: Bearer eyJhbGciOiJIUzI1...)
Servidor → Verifica token → 200 OK

Vantagens: Stateless, perfeito para API REST
Desvantagens: Gestão de expiração

4. OAuth2​

Cliente → Redirect para Google
Google → Login do usuário
Google → Redirect com código
Servidor → Troca código por token
Servidor → Recupera perfil do usuário

Vantagens: Sem senha para gerenciar, UX moderna
Desvantagens: Dependência externa


7. Configuração Moderna (Spring Security 6+)​

Método Antigo (Depreciado)​

// ❌ NÃO UTILIZAR MAIS
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
}

Novo Método (Spring Security 6+)​

// ✅ USE ESTA ABORDAGEM
@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.build();
}

@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}

8. Primeira Configuração​

Dependência Maven​

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

Comportamento Padrão​

Sem nenhuma configuração, o Spring Security:

  • Protege TODOS os endpoints
  • Gera uma senha aleatória (exibida nos logs)
  • Ativa o form login em /login
  • Ativa o logout em /logout
Using generated security password: 8e3d7a2c-1234-5678-abcd-ef0123456789

Configuração Mínima​

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/home", "/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.permitAll()
)
.logout(logout -> logout
.permitAll()
)
.build();
}
}

9. Resumo​

Conceitos-Chave​

ConceitoDescrição
AuthenticationVerifica a identidade (quem?)
AuthorizationVerifica as permissões (o quê?)
SecurityFilterChainCadeia de filtros de segurança
AuthenticationManagerOrquestra a autenticação
UserDetailsServiceCarrega os usuários
PasswordEncoderCodifica as senhas
SecurityContextArmazena o usuário atual

Arquitetura Simplificada​

Requisição HTTP
↓
SecurityFilterChain (filtros)
↓
AuthenticationManager
↓
UserDetailsService + PasswordEncoder
↓
SecurityContext (armazenamento)
↓
Aplicação (Controller)

Pontos Importantes​

✅ Spring Security 6+ usa @Bean, não extends WebSecurityConfigurerAdapter
✅ Sempre codifique as senhas (BCrypt)
✅ Entenda Authentication vs Authorization
✅ A segurança é configurada via SecurityFilterChain

🎯 Próximo Passo​

Agora que você entende a arquitetura, vamos para a prática com a autenticação básica.

➡️ Capítulo 2: Autenticação Básica


⬅️ Voltar ao Módulo 8