Bom dia.
A arquitetura do Spring Security funciona como uma "esteira" de filtros sequenciais. Por padrão, o Spring já possui uma lista ordenada de filtros internos (autenticação, CSRF, sessão, etc.).
O método addFilterBefore(meuFiltro, FiltroExistente.class) diz ao Spring: "Execute o meu filtro customizado imediatamente antes do filtro padrão X."
Em APIs REST que utilizam tokens JWT, é quase obrigatório usar o addFilterBefore da seguinte forma:
http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
O filtro padrão do Spring (UsernamePasswordAuthenticationFilter) espera receber um usuário e senha tradicionais (geralmente via formulário de login).
Como a sua API usa JWT, a requisição não terá usuário e senha, mas sim um Header Authorization: Bearer .Se você não colocar o seu filtro de JWT antes, o filtro padrão do Spring vai rodar primeiro, não vai encontrar as credenciais tradicionais e vai barrar ou falhar a requisição antes mesmo do seu validador de token ser executado.
O filtro do Spring Security vai tentar fazer o processo de autenticação, mas não queremos isso, pois a autenticação já foi feita anteriormente ao gerar o token.
Outros métodos semelhantes de ordenação:
Além do addFilterBefore, a classe HttpSecurity fornece alternativas dependendo da sua necessidade:
addFilterAfter(meuFiltro, FiltroExistente.class): Executa o seu filtro imediatamente após um filtro específico. Útil para logs ou auditoria após a autenticação ter sido realizada com sucesso
addFilterAt(meuFiltro, FiltroExistente.class): Executa o seu filtro na mesma posição (ordem numérica interna) do filtro alvo. Ele não substitui o filtro original, mas garante que ambos rodem na mesma etapa de prioridade.
Espero ter ajudado. Se sua dúvida foi sanada, marque este tópico como solucionado.
Bons estudos!