Autenticação Basic com Java Spring

alexandretannus

Alexandre Tannus

Posted on March 11, 2021

Autenticação Basic com Java Spring

A autenticação de usuários é uma necessidade básica em boa parte das aplicações web e mobile. Realizar essa autenticação utilizando o framework Spring é fácil. Este artigo mostra como realizar a autenticação básica no Spring, com a criação de um servidor de recursos (Resource Server) e a configuração com o modelo Basic.

Introdução

A autenticação Basic é a forma mais simples de autenticar um usuário. Ela consiste na configuração de um servidor de recursos e a definição de um usuário e senha. O Spring possui essa autenticação embutida automaticamente no pacote spring-boot-starter-security, ou seja, caso essa dependência seja adicionada ao projeto já é possível utilizar essa autenticação sem a necessidade de configurações adicionais.
No entanto, para definir usuários e senhas específicos para a aplicação é necessário que algumas configurações sejam adicionadas ao projeto.

Criação do projeto base

O projeto base pode ser criado utilizando qualquer ferramenta/IDE que permita a geração de projetos Spring. Algumas opções para realizar esta tarefa são:

Na criação do projeto devem ser adicionadas as dependências

  • Spring Boot Starter Web
  • Spring Security

Para os testes da autenticação de rotas é necessário implementar um controlador simples. Este controlador proverá conteúdos estáticos, apenas para exemplificar o funcionamento.



@RestController
@RequestMapping("/main")
public class BasicController {

    @GetMapping("protect")
    public String protectedRoute() {
        return "Rota Protegida";
    }

    @GetMapping("free")
    public String unprotectedRoute() {
        return "Rota Livre";
    }
}


Enter fullscreen mode Exit fullscreen mode

A princípio, as duas rotas estarão bloqueadas para acesso autenticado apenas. Após a configuração personalizada será possível liberar uma delas da autenticação e deixar a outra protegida.

Com essas duas dependências adicionadas uma configuração de segurança padrão é adicionada ao projeto utilizando o nome de usuário user e uma senha aleatória que é mostrada no log de inicialização do sistema, conforme mostrado na figura a seguir

image

Além disso, o Spring provê automaticamente a seguinte página de login
image

A estilização desta página de login e sua correta configuração não estão no escopo deste artigo

O maior problema desta geração de senha padrão é que a cada reinicialização do sistema a senha será alterada, tornando essa configuração padrão inviável para ambiente de produção e muito difícil de gerenciar até em ambiente de desenvolvimento.

Configurando o usuário e senha através das propriedades

Algumas propriedades de configuração da aplicação podem ser definidas no arquivo application.properties ou no arquivo application.yml, assim como via linha de comando. Dentre estas propriedades estão o usuário e senha para a autenticação Basic. Um exemplo de configuração é mostrado a seguir, com a alteração do nome do usuário para alexandre e a senha para 123456



spring.security.user.name=alexandre
spring.security.user.password=123456


Enter fullscreen mode Exit fullscreen mode

A figura a seguir é um print da tela do Insomnia, uma ferramenta gratuita para teste de APIs, quando é feita a requisição para a rota /main/protect sem que sejam passadas as informações de usuário e senha. O retorno é um status HTTP 403, que informa que o usuário não está autorizado a acessar o recurso.

image

O mesmo resultado é obtido para a rota /main/free sem autenticação

image

Para obter um resultado de sucesso na requisição é necessário configurar a autenticação, conforme mostrado a seguir.

image

Esta configuração pode ser interessante para ambientes de desenvolvimento, mas dificilmente será utilizada em produção, a não ser em casos específicos em que apenas um usuário é necessário.

Personalizando configurações da autenticação Basic

Para personalizar alguns aspectos da autenticação Basic é preciso criar uma nova classe para redefinir as configurações do Spring Security. Esta classe sobrescreverá as configurações realizadas pela classe WebSecurityConfigurerAdapter e seu código inicial é o seguinte



@Configuration
@EnableWebSecurity
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

}


Enter fullscreen mode Exit fullscreen mode

Conforme já mencionado, esta é uma classe de configuração para o Spring. Sendo assim, ela poderia ser explicitamente anotada com @Configuration. No entanto, como a anotação @EnableWebSecurity já traz consigo a anotação @Configuration não é necessária a repetição da mesma. Entretanto, não é errado fazer isso e o código fica mais legível.

Métodos de configuração

A classe WebSecurityConfigurerAdapter possui alguns métodos de configuração com a assinatura configure. Estes métodos podem ser sobrescritos para a personalização da autenticação com relação às requisições HTTP e também dos usuário permitidos.

Método configure(HttpSecurity http)

Este método permite a alteração de configurações relativas às requisições do protocolo HTTP, tais como o fluxo de autenticação, o formulário de login padrão (já citado anteriormente), as requisições que serão protegidas pela autenticação, o tipo de token que será utilizado (quando necessário), configuração de servidores stateless ou stateless, dentre outras configurações. A documentação oficial do Spring traz uma relação das configurações possíveis de serem realizadas neste método de configuração.
Para este projeto serão utilizadas as seguintes configurações

  • Definição do HTTP Basic como método de autenticação
  • Desabilitação do form login
  • Definição de rotas que deverão ser autenticadas ou não
  • Configuração de gerenciamento de sessão

Os dois primeiros itens da lista são configurados da seguinte forma



@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic();
}


Enter fullscreen mode Exit fullscreen mode

O form login é habilitado através do método formLogin(). A omissão deste método na configuração é suficiente para a sua inativação. Para concatenar configurações pode ser utilizado o método and(). Sendo assim, a habilitação do login pode ser feita com a configuração http.httpBasic().and.formLogin().

A definição de quais rotas deverão ser autenticadas ou não é feita pelo método authorizeRequests(). Este método permite a configuração através dos métodos antMatchers e anyRequest, sendo o primeiro para definir de forma personalizada a rota e o segundo uma forma generalista para buscar todas as outras requisições. Neste exemplo será configurada a permissão para acessar a rota /main/free sem autenticação e todas as outras rotas precisarão passar por autenticação prévia.



@Override
protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and()      
      .authorizeRequests()
          .antMatchers("/main/free").permitAll()
          .anyRequest().authenticated();
}


Enter fullscreen mode Exit fullscreen mode

Outra configuração importante é referente ao controle de sessão e armazenamento de cookies. Por padrão, o Spring Security armazena cookies que retém informações sobre a autenticação previamente realizada. Isso permite que após uma requisição bem sucedida com autenticação o usuário consiga acessar o recurso mesmo que não utilize os dados de autenticação. Esse é um problema que deve ser resolvido e uma das formas de fazer isso é configurando o gerenciamento de sessão para que seja utilizada uma política stateless, ou seja, sem armazenamento de estado. Para isso, pode ser adicionado à configuração anterior o método sessionManagement, da seguinte forma.



@Override
protected void configure(HttpSecurity http) throws Exception {
  http.httpBasic()
    .and()      
      .authorizeRequests()
        .antMatchers("/main/free").permitAll()
        .anyRequest().authenticated()
    .and()
      .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}


Enter fullscreen mode Exit fullscreen mode

Método configure(AuthenticationManagerBuilder auth)

Este método permite a configuração de usuários e senhas para a aplicação. Neste artigo é abordada apenas uma estratégia de armazenamento destes usuários em memória de forma completamente programática (definidos no próprio código).

Para configurar a autenticação em memória é utilizado o método inMemoryAuthentication() que permite as seguintes configurações

  • Nome do usuário: withUser("nome")
  • Senha: password("password")
  • Permissões: roles("roles")

A partir da versão 5 do Spring Security é necessário colocar qualquer tipo de senha de forma codificada para o correto funcionamento. Uma forma de fazer isso é colocar a configuração do password como password("{noop}password"), o que delega ao NoOpPasswrodEncoder a responsabilidade de realizar a codificação. Essa opção deve ser utilizada com muito cuidado, pois expõe um dado sensível no código, e não deve ser utilizada em ambiente de produção.

A configuração completa do método fica da seguinte forma



@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("alexandre")
        .password("{noop}123456")
        .roles("roles");
}


Enter fullscreen mode Exit fullscreen mode

É possível colocar outros usuários nesta configuração utilizando o conectivo and().



@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("alexandre")
.password("{noop}123456")
.roles("roles")
.and()
.withUser("admin")
.password("{noop}admin")
.roles("roles");
}

Enter fullscreen mode Exit fullscreen mode




Conclusão

Este artigo mostrou a configuração inicial de autenticação Basic utilizando o Spring Security. Foram abordadas as questões sobre os métodos necessários para uma personalização simples da autenticação como configuração de usuários e senhas e definição de rotas que devem ou não ser autenticadas.
Apesar de haver uma configuração obrigatória de definição de permissões na configuração de usuários, a mesma não foi utilizada para definição de autorizações nas rotas. Esse tema poderá ser explicado em um futuro trabalho.

💖 💪 🙅 🚩
alexandretannus
Alexandre Tannus

Posted on March 11, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related