1
resposta

Configuração de uma API Stateless com Spring Security: Desativando Sessões e Proteção CSRF

Eu aprendi como configurar uma API sem estado (stateless) usando o Spring Security, o que é essencial para quando estamos trabalhando com APIs que não devem manter informações de sessão entre as requisições. Em uma aplicação web tradicional, o Spring Security usa o JSESSIONID para manter a sessão do usuário, ou seja, ele armazena dados sobre a sessão no servidor, e o navegador envia esse identificador de sessão com cada requisição. No entanto, como estamos criando uma API, a gente não pode depender disso, já que nossa API será consumida por front-ends e aplicativos móveis, que não têm esse tipo de sessão como as aplicações web.

Para isso, o Spring Security tem uma forma de configurar a API como stateless, ou seja, sem estado. Isso significa que a API não mantém informações sobre o usuário entre uma requisição e outra. Cada requisição precisa carregar todas as informações necessárias para ser autenticada e autorizada. Essa é a principal característica de uma API RESTful, que precisa ser independente e sem estado.

Eu aprendi que para tornar a API stateless, a gente tem que ajustar a configuração do Spring Security, criando um filtro de segurança customizado. Isso é feito através da classe SecurityFilterChain, que vai definir como as requisições são tratadas, como por exemplo, como a autenticação será feita e como a sessão será gerenciada. No caso de uma API sem estado, o que a gente faz é configurar o SessionCreationPolicy.STATELESS. Isso informa ao Spring que ele não deve criar sessões, e que cada requisição será independente. Ou seja, a cada nova requisição, o Spring não tentará associar a requisição a uma sessão existente. Isso é fundamental para garantir que a nossa API esteja preparada para trabalhar de forma eficiente com clientes como apps móveis e outros sistemas.

Outro ponto importante que aprendi foi sobre a proteção CSRF. Em uma aplicação web tradicional, o Spring Security protege contra ataques CSRF (Cross-Site Request Forgery), mas essa proteção não é necessária em uma API, porque as requisições não vêm de formulários de HTML. Quando estamos lidando com APIs, a comunicação geralmente é feita através de requisições HTTP feitas com ferramentas como Postman ou diretamente por código. Por isso, o Spring ativa o CSRF por padrão, mas em uma API, a gente pode desativá-lo facilmente com o método csrf().disable() na configuração.

Uma vez que a API foi configurada como stateless e com a proteção CSRF desativada, o Spring não vai mais gerenciar as sessões nem gerar a página de login padrão. Isso é algo que eu aprendi também: ao tentar acessar uma URL como localhost:8080/login, que normalmente seria a página de login gerada pelo Spring Security, isso não vai mais funcionar. Isso acontece porque, ao configurar a API para ser stateless, o Spring não tem mais a responsabilidade de gerenciar a autenticação dessa forma.

Agora, com a autenticação e sessões removidas da configuração padrão do Spring, o próximo passo é criar um filtro personalizado de autenticação. Isso é algo que eu ainda vou implementar, mas basicamente será necessário para garantir que apenas usuários autenticados possam acessar as rotas da nossa API. Como o Spring não vai mais gerar as páginas de login nem controlar sessões, eu preciso fazer isso manualmente, criando um filtro que valide se o usuário está autenticado antes de permitir o acesso às rotas protegidas.

Em resumo, o que eu aprendi foi como configurar uma API sem estado usando o Spring Security, desativando as sessões e a proteção CSRF, e como essa abordagem deixa a API mais adequada para ser consumida por clientes como aplicativos móveis. Também aprendi que, como o Spring não vai mais fornecer autenticação ou gestão de sessão por padrão, vou precisar criar filtros de segurança personalizados para garantir que a autenticação e autorização sejam tratadas corretamente, o que será o próximo passo na configuração dessa API.

1 resposta

Olá, Danilo. Tudo bem?

Você mencionou corretamente a importância de desativar a criação de sessões e a proteção CSRF em APIs, já que essas práticas são mais adequadas para aplicações web tradicionais.

Sobre o próximo passo que você mencionou, que é a criação de um filtro de autenticação personalizado, você pode considerar usar um filtro que verifica tokens JWT (JSON Web Tokens), que são uma forma comum de autenticação em APIs stateless. Isso pode ser feito implementando um filtro que intercepta as requisições, extrai o token do cabeçalho Authorization e valida sua autenticidade e autorização antes de permitir o acesso aos recursos protegidos.

Aqui está um exemplo básico de como você poderia começar a implementar isso:

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String header = request.getHeader("Authorization");
        if (header != null && header.startsWith("Bearer ")) {
            String token = header.substring(7);
            // Aqui você deve validar o token e extrair as informações do usuário
            // Se o token for válido, você pode definir a autenticação no contexto de segurança
        }
        filterChain.doFilter(request, response);
    }
}

Este é apenas um ponto de partida, e você precisará adaptar conforme suas necessidades específicas, como a forma de validação do token e o que fazer quando um token não é válido.

Espero ter ajudado de alguma forma.

  Alura   Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!