Skip to main content

JSON Web Token (JWT), é um padrão que define uma forma segura de transmitir mensagens utilizando um [su_tooltip title=”Token” text=”Token é um objeto ou símbolo que significa ou representa outra coisa, seja ela física ou virtual. No caso de telecnologia trata-se de um dispositivo ou programa criptografado que é capaz de gerar uma senha.” max_width=”360″]token[/su_tooltip] compacto e self-contained no formato de um objeto [su_tooltip title=”JSON” text=”JSON é o acrônimo de JavaScript Object Notation. É um formato criado para a troca de dados aberto que pode ser lido por humanos e por máquina. Apesar de ter JavaScript no nome o JSON é independente de qualquer linguagem de programação e pode ser uma saída de API para uma ampla variedade de aplicativos.” max_width=”360″]JSON[/su_tooltip].

A assinatura de um JSON Web Token é seu componente mais sensível por tratar justamente da segurança deste token. Por conta disto existe uma fórmula padrão para que o token seja adequadamente assinado, exigindo que o token seja uma [su_tooltip title=”Hash” text=”Hash é um algoritimo usado em operações de criptografia. Consiste em pegar um dado, ou vários de diferentes tamanhos, sejam eles arquivos, senhas ou textos e convertê-los em valores de saída padronizados com um tamanho fixo de caracteres na forma de conjuntos alfanuméricos.” max_width=”360″]hash[/su_tooltip] em Base64 gerada de um algoritmo de [su_tooltip title=”Criptografia” text=”Criptografia é uma técnica, ou conjunto delas, que visa tornar uma determinada informação digital ininteligível para todo aquele que não possui as convenções combinadas para poder ‘lê-la’ tornando-a uma informação privada.” max_width=”360″]criptografia[/su_tooltip], por exemplo SHA256 ou SHA512, e essa hash precisa ser feita a partir do header e do payload do token.

Se você ainda não possui um projeto criado e quer ver como fazer isso de maneira simples, preparei um outro tutorial extremamente simples de como inicializar o seu projeto spring.

Caso queira adicionar também o swagger ao seu projeto para ter uma ferramenta de documentação e teste de API pode seguir o seguinte post, aqui que irei mostrar como adicionar a permissão ao swagger ne tutorial também.

Agora que você já possui um projeto spring funcional, vamos configurar o Spring Security e o JWT para executar duas operações:
Gerar token JWT: Exponha uma API POST com mapping / authenticate. Ao passar o nome de usuário e a senha corretos, ele gerará um JSON Web Token (JWT).
Validar o JWT: Se um usuário tentar acessar a API GET com o mapeamento / hello, ele permitirá o acesso somente se uma solicitação tiver um JSON Web Token (JWT) válido.

Adicione a dependência do spring security e do jjwt

dentro do seu arquivo pom.xml, adicione essas dependências dentro das tags <dependencies></dependencies>:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
</dependency>

Dentro do seu application.properties adicione uma chave que vai ser usada para o algoritimo de hash.

jwt.secret=usersecretforjwtauthenticateoratoroeuaroupadoreideromalalalameudeuscomoessabencaodechave

Primeiro vamos criar um pacote config para colocar nossasclasses referentes as configurações da geração do JWT e criar nosso JwtTokenUtil que faz uso daio.jsonwebtoken.Jwts.

Adicione a dependência do spring security e do jjwt - JwtTokenUtil 
JwtTokenUtil hosted with ❤ by GitHub
Acesse o código aqui.

Agora vamos criar o nosso controller para gerenciar a autenticação da nossa aplicação. Usando o Spring Authentication Manager, autenticamos o nome de usuário e a senha. Se as credenciais forem válidas, um token JWT será criado usando o JWTTokenUtil e será fornecido ao cliente.

pring Authentication Manager - JWTTokenUtil 
JwtAuthenticationController hosted with ❤ by GitHub
Acesse o código aqui

Agora vamos criar um model para guardar os dados recebidos do cliente a JwtRequest

Autenticação JWT no Spring boot - JwtRequest
JwtRequest hosted with ❤ by GitHub
Acesse o código aqui

Agora iremos criar para guardar o token jwt que vai ser enviado para o client, JwtResponse

JwtResponse
JwtResponse hosted with ❤ by GitHub
acesse o código aqui

O JwtRequestFilter estende a classe do Spring Web Filter OncePerRequestFilter. Para qualquer solicitação recebida, essa classe de Filtro é executada. Ele verifica se a solicitação possui um token JWT válido. Se tiver um token JWT válido, ele define a autenticação no contexto para especificar que o usuário atual é autenticado.

JwtRequestFilter - OncePerRequestFilter
JwtRequestFilter hosted with ❤ by GitHub
Acesse o código aqui

Agora iremos criar a JwtAuthenticationEntryPoint, essa classe estenderá a classe AuthenticationEntryPoint do Spring e substituirá seu método commence. Ele rejeita todas as solicitações não autenticadas e envia o código de erro 401.

AuthenticationEntryPoint
JwtAuthenticationEntryPoint hosted with ❤ by GitHub
Acesse o código aqui

Agora iremos criar uma classe JwtUserDetailsService que implementaaUserDetailsService do spring security e checar o login do usuário, nesse tutorial o usuário e a senha serão fixos no código, em um tutorial futuro iremos buscar esses dados no banco.

Autenticação JWT no Spring boot - JwtUserDetailsService 
JwtUserDetailsService hosted with ❤ by GitHub
Acesse o código aqui

Esta classe estende o WebSecurityConfigurerAdapter. Essa é uma classe que permite a personalização para o WebSecurity e o HttpSecurity, aqui podemos definir que urls devemos permitir ou não.

WebSecurityConfigurerAdapter
WebSecurityConfig hosted with ❤ by GitHub
Acesse o código aqui

Projeto com autenticação pronta, as collections do postman para testar fica dentro de resources, na raiz da pasta do projeto.

Neste artigo vimos uma autenticação padrão, sem níveis de acesso, mas muitas vezes podemos querer criar roles, que irão definir o que cada tipo de usuário pode acessar, para isso temos a continuação deste artigo aqui.

Espero que ajude a quem está procurando implementar este tipo de autenticação, em breve irei tratar sobre outros métodos.

Escrito pelo #FERA Odilio Noronha para Medium:

BRQ fale conosco