Boas-vindas a mais um curso de Segurança em Java na Alura. Sou a Iasmin Araújo e faço parte do time da Escola de Programação!
Audiodescrição: Iasmin é uma mulher branca de cabelos longos, castanhos e olhos claros. Usa uma blusa regata na cor vinho e está sentada em uma cadeira gamer preta e rosa. Ao fundo, uma parede lisa e uma iluminação azul.
Este curso é destinado a quem já está acompanhando nossa formação em Segurança em Java e deseja aprofundar seus conhecimentos, mais especificamente na parte de login.
Para que você possa realizar esse curto é importante que tenha assistido aos cursos anteriores da formação de segurança e saber tanto implementar APIs REST quanto utilizá-las.
Neste curso, aprenderemos a implementar o login com GitHub e Google na API. Isso facilitará a experiência do usuário no momento da autenticação, além de ajudar na parte de segurança. Para efetuar esse login externo, utilizaremos os protocolos OAuth e OpenID Connect, que são protocolos usados para comunicação entre aplicações.
Além disso, nós também vamos adicionar a autenticação de dois fatores na aplicação. Vamos explorar os tipos de autenticação de dois fatores existentes e como podemos utilizá-los. Mais especificamente, vamos integrar nossa API a aplicativos autenticadores, como o Google Authenticator ou o Microsoft Authenticator, tornando o fluxo mais completo.
Vamos implementar tudo isso no projeto do Fórum Hub, que simula o comportamento do Fórum da Alura. Este projeto é implementado como uma API Rest, e vamos incrementar funcionalidades associadas à segurança e ao login.
Lembrando que, além dos vídeos, temos várias outras atividades complementares, como textos e exercícios que você pode resolver. Praticar ajudará a desenvolver suas habilidades com o código. Se tiver alguma dúvida, envie para nós no fórum ou na comunidade da Alura, nós ajudaremos a resolver seus problemas para que tudo funcione corretamente.
Vamos começar nosso desenvolvimento?
Neste curso, continuaremos trabalhando com a aplicação do Fórum Hub, uma API REST que simula todo o comportamento do Fórum da Alura. No curso anterior, desenvolvemos todo o fluxo de login padrão da API. Esse login padrão envolve um cliente, que pode ser um front-end ou um aplicativo móvel, onde a pessoa usuária interage visualmente e insere suas informações. Após a inserção, o cliente envia uma requisição para a aplicação do Fórum Hub, contendo o login e a senha.
O Fórum Hub verifica esses dados realizando uma consulta no banco de dados. Se tudo estiver correto, ele gera um token JWT e o devolve ao cliente, que será responsável por gerenciar esse token. Assim, a cada nova requisição, o cliente enviará o token JWT recebido da API.
Além do token JWT, desenvolvemos a funcionalidade de refresh token. Isso significa que, em vez de solicitar que a pessoa usuária faça login novamente sempre que o token JWT expirar, o cliente pode se comunicar com a API usando o refresh token, sem a necessidade de solicitar que a pessoa usuária insira seus dados novamente. Isso melhora a experiência do usuário.
Esse é o fluxo que temos até agora. A autenticação já está funcionando completamente. No entanto, sempre podemos evoluir as aplicações. Uma das melhorias mais comuns em autenticação é a implementação de um login externo, ou seja, um login com outra aplicação, como o GitHub.
O login externo é comum e importante, pois as pessoas usuárias possuem contas em diversos sites diferentes. Se cada site exigir uma senha diferente, o que é recomendado para a segurança das aplicações, gerenciar e lembrar de todas essas senhas pode ser complicado. O login externo facilita a vida das pessoas usuárias.
Por exemplo, ao implementar o login com o GitHub, o cliente terá um botão para "Entrar com o GitHub". Quando a pessoa clicar nesse botão, o cliente fará uma requisição para API na URL //login//github
. Essa URL redireciona a pessoa usuária para a página de login do GitHub, que autoriza e verifica os dados. Se tudo estiver correto, devolve os dados da pessoa usuária armazenados em sua API.
Esses dados são utilizados no Fórum Hub para realizar uma consulta no banco de dados. Se tudo estiver correto, geramos o token JWT e o devolvemos ao cliente novamente. Com essa modificação no fluxo, teremos duas aplicações interagindo: o Fórum Hub e a aplicação externa, que neste caso é o GitHub.
Nossa aplicação precisa estar ciente da existência do GitHub para implementar esse login externo. No entanto, o GitHub não conhece nossa aplicação. Portanto, precisamos nos registrar no GitHub para que ele possa nos reconhecer.
Esse processo será realizado na aplicação do GitHub, então, no navegador, acessamos a página de configurações de desenvolvimento no site do GitHub. Estamos na área de OAuth apps, onde vamos criar um novo app OAuth, no qual entenderemos mais em breve.
No centro da tela, clicamso no botão "New OAuth app". Uma nova página será exibida, na qual precisaremos digitar os dados da nossa aplicação, que é o Forum Hub.
Primeiramente, é solicitado o nome da aplicação, que será "Forum Hub". Além disso, é necessário informar a URL da página inicial da aplicação. No nosso caso, utilizaremos http://localhost:8080
, que é o endereço de desenvolvimento. No futuro, quando a aplicação estiver em produção, usaremos a URL padrão da aplicação, como www.forumhub.com.br
.
Também é solicitada uma descrição da aplicação, mas essa informação não é obrigatória, então não a incluiremos. Por fim, precisamos fornecer uma URL de retorno (callback), que é essencial para que, após a pessoa usuária fazer login com uma aplicação externa, seja redirecionada de volta para a nossa aplicação. Vamos construir essa URL de retorno como http://localhost:8080/login/github/autorizado
, indicando que o usuário fez login no GitHub com sucesso.
Com todos os dados preenchidos, podemos registrar a aplicação clicando em "Register Application" na parte inferior da página. A aplicação será criada, e um Client ID será gerado. Na aba de Client Secrets, podemos clicar em "Generate New Client Secret" para gerar um novo dado. Agora, temos um ID e um Secret.
Esses dados são necessários para registrar o Fórum Hub como uma aplicação no GitHub, permitindo que ele reconheça nossa aplicação. O ID funciona como o login da aplicação, e o Secret como a senha. Com o ID e o Secret, podemos copiá-los e colá-los em um bloco de notas para referência futura.
Feito isso, temos todas as informações necessárias, e o GitHub já reconhece nossa aplicação. Na sequência, utilizaremos essas propriedades e entenderemos melhor por que elas são chamadas de Client ID e Client Secret.
Registramos o Fórum Hub como um aplicativo OAuth no GitHub no momento em que essa configuração era necessária. O OAuth é um protocolo que facilita a interação entre aplicações, permitindo que um usuário acesse serviços sem precisar compartilhar suas credenciais diretamente.
No nosso caso, o Fórum Hub é uma aplicação onde um usuário deseja fazer login. Para autenticar esse usuário, consultamos seus dados no GitHub. Isso cria uma interação entre três partes: a aplicação 1 (Forum Hub), a aplicação 2 (GitHub) e a pessoa usuária. O OAuth é o protocolo que gerencia essa comunicação de forma segura.
Como protocolo, o OAuth define diferentes papéis para seu funcionamento. O primeiro deles é o cliente. No Forum Hub, vimos a presença do client ID
e do client secret
. Esses dados são gerados porque, ao registrarmos um aplicativo OAuth, o GitHub reconhece que ele será um cliente e precisa de credenciais para se comunicar com a plataforma. Outros papéis do OAuth serão abordados ao longo dos vídeos, mas, focaremos no cliente.
Agora que geramos o client ID
e o client secret
, precisamos utilizá-los para integrar nossa aplicação ao GitHub. No fluxo de autenticação, o primeiro passo é a requisição ao GitHub e, no segundo, a obtenção dos dados do usuário. Neste momento, nosso foco será no primeiro passo: o redirecionamento da aplicação para o GitHub.
Para entender melhor como isso funcionará, vamos para outro esquema. Temos uma parte com a pessoa usuária, que interage com o Fórum Hub. Neste momento, consideramos a pessoa usuária final. Imagine que há um cliente no meio, que é o front-end ou mobile. Quando clicamos no botão, uma requisição é feita para a URL /login/GitHub
, e essa requisição atinge nossa API, que é o Fórum Hub.
Uma vez que a requisição chega ao Fórum Hub, ele redireciona a pessoa usuária para o GitHub, onde deve inserir seus dados, se autentica, digita login e senha, o GitHub valida e devolve a informação de que a pessoa usuária está logado. Esses dados são devolvidos na URL de callback que vimos, por isso é tão importante.
Nossa API deve ser capaz de realizar o redirecionamento do Fórum Hub para o GitHub e ter a URL /login/GitHub
. Vamos agora para o código que implementará essa parte. No IntelliJ, a ideia é mapear a rota /login/GitHub
para que faça o redirecionamento ao GitHub. Para isso, podemos criar um novo controller.
No pacote controller dentro do Fórum Hub, pressionamso "Alt + Insert" para criar uma nova classe Java chamada LoginGitHubController
.
Primeiro, vamos importar as anotações necessárias e definir a classe como um @RestController
.
Dentro dessa classe, precisamos de uma rota específica que será o @RequestMapping
com a URL /login/GitHub
. Esse @GetMapping
deve devolver um ResponseEntity
, que é o padrão que utilizamos. Assim, declaramos um public ResponseEntity<Void>
, pois realizaremos um redirecionamento. Para termos um retorno http semântico, devolveremos o código 302 e a url de direcionamento no cabeçalho dessa requisição.
Escrevemos var headers = new HttpHeaders()
. Abaixo, podemos passar um headers.setLocation(url)
.
Uma vez que temos o headers
e o setLocation
, podemos retornar um new ResponseEntity()
, incluindo tanto o nosso cabeçalho quanto o código específico de redirecionamento. Esse código é o HttpStatus.FOUND
, que corresponde ao status HTTP 302, utilizado para redirecionamento.
//Código omitido
@RestController
@RequestMapping("/login/github")
public class LoginGithubController {
@GetMapping
public ResponseEntity<Void> redirecionarGithub() {
// url
var headers = new HttpHeaders();
headers.setLocation(url);
return new ResponseEntity<>(headers, HttpStatus.FOUND);
}
}
Com isso, as configurações do controller estão definidas. No entanto, ainda não estabelecemos qual será essa URL que passamos como parâmetro. Essa será a URL responsável por redirecionar o usuário para o GitHub.
Esse redirecionamento, no entanto, não é um simples redirect. Ele deve seguir o protocolo OAuth, o que significa que algumas informações específicas precisam estar presentes na URL para que a autenticação funcione corretamente.
Devido à quantidade de informações, podemos encapsular esses detalhes em um service, para manter o código mais organizado. Assim, a variável URL será construída em um service.
Vamos declarar um private final service
chamado loginGitHubService
. Essa classe ainda não existe, então vamos criá-la. Para isso, clicamos com o botão direito nela e depois em "Create class loginGitHubService
", assim será criada dentro do pacote "domínio.autenticação.GitHub", que também será criado. Vamos adicionar ao Git. Essa classe será anotada com @Service
.
Escrevemos o método public String gerarUrl()
e baixo passamos o retorno return
. A url que vamos devolver tem um padrão definido pelo OAuth, que pedirá tanto uma url de direcionamento para o GitHub, quanto alguns parâmetros adicionais.
Então, começaremos pela do GitHub. Depois, definimos os parâmetros ?client_id
que geramos no registro do cliente. Além disso, teremos o &redirect_uri
de callback que configuramos.
Após precisamos parrar o parâmetro de escopo. Nesse momento, não focaremos nessa parte. O que você precisa saber é que precisa pegar as informações da pessoa usuária. Passamos então "&scope=read:user,user:email"
, pois queremos ler as informações, em específico o e-mail.
Feito isso, precisamos devolver a url como redirecionamento. Então, próximo à linha 15, em LoginGithubService
, clicamos com o botão direito e depois em "Add constructor".
Após, abaixo de Public ResponseEntity<Void>
, passamos var url = LoginGithubService.gerarUrl()
. O próximo passo é devolver a url no cabeçalho, mas, para isso, o cabeçalho pede o formato Uri
. Então, nos parênteses de setLocation()
passamos Uri.create(url)
.
package br.com.forum_hub.domain.autenticacao.github;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import java.util.Map;
@Service
public class LoginGithubService {
private final String clientId = "Ov23linqPz0cwrTV1Rau";
private final String clientSecret = "b32f75184e1e0584bb1894085d59d44990d3257d";
private final String redirectUri = "http://localhost:8080/login/github/autorizado";
private final RestClient restClient;
public LoginGithubService(RestClient.Builder restClientBuilder) {
this.restClient = restClientBuilder.build();
}
public String gerarUrl(){
return "https://github.com/login/oauth/authorize"+
"?client_id="+clientId +
"&redirect_uri="+redirectUri +
"&scope=read:user,user:email";
}
public String obterToken(String code) {
var resposta = restClient.post()
.uri("https://github.com/login/oauth/access_token")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Map.of("code", code, "client_id", clientId,
"client_secret", clientSecret, "redirect_uri", redirectUri))
.retrieve()
.body(String.class);
return resposta;
}
}
Agora, tudo está compilando. Vamos executar a aplicação e conferir o que acontece.
A aplicação foi iniciada. Vamos tentar fazer o login usando o GitHub, acessando http://localhost:8080/login/github
. O acesso ao localhost foi negado. Precisamos permitir essa URL nas configurações de segurança. Podemos adicionar a permissão para login/github
nas configurações de segurança, permitindo todas as requisições.
Na classe de configurações de segurança, temos requestMatchers("/login")
permitido. Vamos alterar para "/login/**"
, permitindo todas as URLs de login, incluindo logins externos.
//Código omitido
req.requestMatchers(...patters:"/login/**"), "/atualizar-token", "/registrar", "verificar-conta").permitAll();";
Após reiniciar a aplicação, fazemos o login novamente. Assim, somos redirecionados para uma tela de autorização, que ainda não exploramos. Em seguida, entenderemos melhor como essa tela funciona.
O curso Java e Spring Security: login com GitHub, Google e autenticação de 2 fatores possui 170 minutos de vídeos, em um total de 59 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.