Article image
Leandro Galvao
Leandro Galvao30/08/2021 15:27
Compartilhe

#DIOProGrátis - Spring Security - Entenda o que nunca te contaram sobre o fluxo desse framework de autenticação de autorização

  • #Spring Boot / Spring Framework
  • #Spring Security / Spring Framework
  • #REST

Autenticação

O fluxo de autenticação por meio do Spring Security é o seguinte:

image

Tendo em vista essa cadeia de dependências, a cofiguração do processo de autenticação por meio do Spring Security deverá obedecer a seguinte sequência:

  1. Definir uma classe que implemente a interface UserDetails
  2. Definir uma classe que implemente a interface UserDetailsService
  3. Definir a lógica de criptografia de senha ou utilizar uma implementação da interface PasswordEncoder fornecida pelo Spring Security
  4. Definir a lógica de autenticação a ser implementada ou utilizar uma implementação da interface AuthenticationProvider disponibilizada pelo Spring Security
  5. Implementar a interface AuthenticationManager ou utilizar uma implementação dessa interface construída por meio da classe AuthenticationManagerBuilder.

Após a configuração do Spring Security, será possível adicionar o AuthenticationManager como um bean ao contexto da aplicação por meio do método authenticationManagerBean() da classe WebSecurityConfigurerAdapter

image

O processo de autenticação tem dois objetivos no Spring Security:

  • Prover ao AuthenticationManager as credenciais fornecidas pelo usuário para se autenticar
  • Representar o usuário autenticado por meio da interface Authentication, que pode ser obtida a partir do SecurityContext: SecurityContextHolder.getContext().getAuthentication()

image

A interface Authentication dispõe de métodos para obter:

  • authorities, que são permissões em alto nível atribuídas ao usuário, como papéis ou escopos. Permissões são definidas por Strings e, por padrão, prefixadas com 'ROLE_'
  • credentials, geralmente uma senha, mas também pode ser um token.
  • principal, que identifica o usuário. É geralmente uma implementação da interface UserDetails quando se autentica com usuário e senha

Authentication Filter

primeira etapa deste processo ocorre no Spring Security Authentication Filter, que tem três responsabilidades:

  1. Extrair o usuário e a senha que foram fornecidos para autenticação
  2. Criar um token de autenticação usando UsernamePasswordAuthenticationToken, que é uma implementação da interface Authentication
  3. Delegar a continuação do processo de autenticação à interface AuthenticationManager, reponsável por analisar o token de autenticação e decidir se é uma credencial válida.

image

AuthenticationManager

principal interface da estratégia de autenticação do Spring Security é AuthenticationManager, cujo único método (authenticate( )) pode fazer uma das seguintes coisas:

  1. Retornar uma Authentication se puder ser verificado que as credenciais apresentadas são válidas.
  2. Jogar uma exceção AuthenticationException se as credenciais apresentadas não forem válidas.
  3. Retornar null, se ela não conseguir decidir.

image

A implementação mais comum do AuthenticationManager é o ProviderManager, que possui uma lista de AuthenticationProviders aos quais é dada a oportunidade de indicar se a autenticação deveria ter sucesso, falhar ou indicar que não consegue decidir e deixar essa tarefa para o próximo AuthenticationProvider da lista.

image

Também é possível obter rapidamente o AuthenticationManager padrão por meio do AuthenticationManagerBuilder

image

AuthenticationProvider

O AuthenticationProvider implementa a lógica de autenticação e delega o gerenciamento de usuários e senhas às interfaces UserDetailsService e PasswordEncoder, ambas definidas na classe de configuração do projeto.

image

UserDetailService

A interface UserDetailsService possui um único método que deve ser implementado conforme a lógica do sistema e retornar um objeto que implementa a interface UserDetails

UserDetails

É a interface UserDetails que provê ao sistema as informações básicas sobre os usuários. Implementações dessa interface guardam informações que serão posteriormente encapsuladas em objeto que implementa a interface Authentication.

image

Essas implementações não são usadas diretamente pelo Spring para fins de segurança, o que permite que outras informações não relacionadas à segurança (telefone, email, etc.) sejam concentradas no mesmo lugar.

Password Encoder

A interface PasswordEncoder possui dois métdodos abstratos, encode e matches, que são autoexplicativos:

image

SecurityContext

É no SecurityContextHolder que o Spring guarda os detalhes de quem está autenticado:

Os relacionamentos entre as interfaces e classes que participam do processo de autenticação são os seguintes:

image

pom.xml

Para adicionar o Spring Security no seu projeto Spring Boot, adicione a seguinte dependência no arquivo pom.xml ou o equivalente no Gradle:

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

Para ver uma implementação de autenticação e autorização por meio do Spring Security com usuários e senhas armazenados em um banco de dados, pode dar uma olhada no meu github: https://github.com/lmgbsb/jwt

Referências:

https://livebook.manning.com/book/spring-security-in-action/chapter-2/section-2-2?origin=product-toc

https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.html

https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html#authenticationManagerBean--

https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurerAdapter.html

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#servlet-authentication-authentication

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetails.html

https://2darray.com/featured/spring-security-architecture-authentication/

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/authentication/UsernamePasswordAuthenticationToken.html

https://spring.io/guides/topicals/spring-security-architecture

https://docs.spring.io/spring-security/site/docs/4.2.15.RELEASE/apidocs/org/springframework/security/authentication/AuthenticationManager.html

https://docs.spring.io/spring-security/site/docs/5.5.1/api/org/springframework/security/core/Authentication.html

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#servlet-authentication-providermanager

https://docs.spring.io/spring-security/site/docs/4.2.3.RELEASE/apidocs/index.html?org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.html

https://livebook.manning.com/book/spring-security-in-action/chapter-5/59

https://docs.spring.io/spring-security/site/docs/3.2.x/apidocs/org/springframework/security/core/userdetails/UserDetailsService.html

https://www.javadevjournal.com/spring-security/spring-security-authentication/

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/UserDetails.html

https://livebook.manning.com/concept/spring/userdetails-contract

https://en.wikipedia.org/wiki/Decorator_pattern

https://docs.spring.io/spring-security/site/docs/5.0.0.M5/api/org/springframework/security/crypto/password/PasswordEncoder.html

https://waynestalk.com/en/spring-security-architecture-explained-en/

https://ducmanhphan.github.io/2019-02-09-The-mechanism-of-spring-security/

Compartilhe
Comentários (2)

AF

Alan Freitas - 28/04/2022 19:22

Opa, me ajudou bastante. Muito bom!

Gustavo Lemos
Gustavo Lemos - 11/09/2021 20:03

Parabéns pelo artigo, é uma excelente introdução que serve como ponto de partida para demais aprofundamentos neste framework. No meu ponto de vista, além de introdução é um overview com detalhamentos. Híper aprovado!!