← Spring Boot®: aplicações, contratos e operação
07 / 10 · 60 MIN

Segurança e fronteiras de autorização

Define a cobertura de segurança de cada pedido, separa autenticação de autorização e diagnostica rejeições sem retirar controlos.

A cadeia define a cobertura

SecurityFilterChain é selecionada por um matcher. Se a cadeia prioritária usa securityMatcher("/api/**"), só recebe esse conjunto de pedidos. anyRequest dentro dela abrange o que entrou nessa cadeia, não todas as URLs da aplicação. Um controller /exports pode ficar fora dela.

Quando há várias cadeias, a prioridade e a correspondência determinam a escolha. Uma cadeia final sem restrição de caminho pode estabelecer uma política de recurso. Se nenhuma cadeia corresponde, Spring Security não protege o pedido; a ausência de regra não equivale a denyAll.

A primeira correspondência decide

Dentro da cadeia, as regras de autorização são avaliadas pela ordem declarada. Se /reports/** aceita qualquer utilizador autenticado antes de /reports/admin/** exigir ADMIN, um pedido administrativo encontra primeiro a regra abrangente. A especificidade do segundo caminho não o promove automaticamente.

Coloca as condições restritivas antes das abrangentes e decide explicitamente o comportamento residual. Inclui o método HTTP: ler um relatório e publicá-lo podem exigir autoridades distintas. A matriz deve conter tanto acessos legítimos como tentativas sem a autoridade necessária.

Autoridades e fronteiras de serviço

hasAuthority compara a autoridade indicada. Com o prefixo predefinido, hasRole("ADMIN") procura ROLE_ADMIN. Um nome de utilizador admin não substitui essa autoridade. O contrato de autenticação deve explicar como o principal obtém as suas autoridades e quem controla essa atribuição.

EnableMethodSecurity ativa anotações como PreAuthorize em métodos de beans geridos; adicionar o starter não basta. A fronteira de serviço pode precisar de decisões sobre parâmetros e objetos concretos. Uma regra HTTP de leitura geral não demonstra, por si só, que o utilizador pode ler qualquer relatório identificado por id.

Separar CSRF de autoridade

Um POST pode ser rejeitado antes do controller porque falta o token CSRF, mesmo que a sessão esteja autenticada e possua REPORT_WRITE. Por defeito, a proteção cobre métodos inseguros. O token recebido tem de ser resolvido e comparado com o valor esperado pelo mecanismo configurado.

Para analisar autoridade, usa um pedido que satisfaça CSRF. Para analisar CSRF, mantém identidade e autoridade suficientes e varia o token. Não transformes uma alteração num GET para evitar a verificação. A política de proteção deve resultar do modelo de autenticação e dos clientes, não de um 403 isolado.

Verificar credenciais guardadas

PasswordEncoder representa uma transformação num só sentido destinada ao armazenamento e à verificação de palavras-passe. matches recebe o segredo apresentado e o valor codificado guardado. Não é necessário nem apropriado recuperar uma palavra-passe original a partir desse valor.

DelegatingPasswordEncoder usa o formato {id}encodedPassword para escolher a implementação. Sem id reconhecido, e sem encoder de recurso configurado, a comparação pode lançar IllegalArgumentException. Identifica o algoritmo histórico antes de migrar; acrescentar um rótulo bcrypt a bytes de outro formato não os converte.

Validar o destino de um token

Num resource server JWT, ler o payload não estabelece confiança. A validação inclui assinatura e condições temporais; a configuração de emissor deve verificar iss. Uma assinatura válida do emissor esperado ainda pode pertencer a um token destinado a outro recurso.

Quando a API exige uma audiência, configura audiences no Boot ou um validador equivalente, conservando os restantes validadores. Depois da validação, as autoridades continuam a determinar o acesso. Um token aceite não substitui a autorização por objeto, nem demonstra que uma operação de escrita chegou a ser confirmada.

Leitura guiada da política

O exemplo tem uma única cadeia sem securityMatcher restritivo. GET /public/status é permitido pela política HTTP; GET /reports/42 exige REPORT_READ e POST /reports/42 exige REPORT_WRITE. Outros métodos e caminhos chegam a denyAll. As regras não criam controllers nem fornecem um provider de autenticação.

O exemplo conserva CSRF e usa HTTP Basic como mecanismo de autenticação; uma publicação real precisa de transporte protegido e configuração de credenciais própria. Na avaliação, interpreta os pedidos e as condições dadas. Não executes código nem deduzas autorização por objeto a partir destas regras de caminho.

// SecurityConfiguration.java in package com.acme.reports.
// Servlet MVC with Spring Security. A compatible authentication provider is
// configured separately; no credentials are defined in this teaching excerpt.
package com.acme.reports;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
@EnableMethodSecurity
public class SecurityConfiguration {
  @Bean
  SecurityFilterChain reportsSecurity(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(rules -> rules
        .requestMatchers(HttpMethod.GET, "/public/status").permitAll()
        .requestMatchers(HttpMethod.GET, "/reports/**").hasAuthority("REPORT_READ")
        .requestMatchers(HttpMethod.POST, "/reports/**").hasAuthority("REPORT_WRITE")
        .anyRequest().denyAll());
    http.httpBasic(Customizer.withDefaults());
    // CSRF protection remains enabled. No restrictive securityMatcher.
    return http.build();
  }
}
NA PRÁTICA

Lê três pedidos: GET de relatórios com REPORT_READ, POST com a mesma autoridade e POST com REPORT_WRITE. Para isolar autoridade nos POST, considera token CSRF válido. O primeiro pode ser autorizado, o segundo é rejeitado e o terceiro satisfaz a regra de autoridade. O handler e os restantes controlos ainda têm de permitir a operação.

Armadilhas comuns

Colocar regras abrangentes primeiro; confundir hasRole com hasAuthority; deixar URLs fora de todas as cadeias; tratar autenticação como prova CSRF; aceitar JWT apenas por conseguir ler os claims.

Tópicos relacionados: Âmbito de testes e evidência de integração · Rotas HTTP e contratos de pedidos · Saúde, observabilidade e diagnóstico

Leva esta ideia contigo

Uma decisão de acesso precisa de cobertura, identidade válida e autorização adequada. Regista qual controlo tomou a decisão e preserva os restantes ao corrigir a falha.

Criar conta

Referência: Authorize HTTP requests · Spring Boot 4.1.1 / Spring Framework 7.0.9 / Java 25