https://a.storyblok.com/f/270183/45323/1f57166263/blog_2fa_sparkjava_1200x600.png

Como adicionar a autenticação de dois fatores (2FA) usando Java e Spark

Publicado em April 27, 2023

Tempo de leitura: 9 minutos

Este artigo foi atualizado em abril de 2025

Com o número crescente de ameaças cibernéticas, está se tornando cada vez mais importante proteger seus aplicativos e serviços web contra cadastros fraudulentos. Felizmente, a autenticação de dois fatores (2FA) pode adicionar uma camada de proteção ao exigir um código de verificação enviado para o celular do usuário.

Neste tutorial, vamos orientá-lo no processo de implementação da autenticação de dois fatores (2FA) em suas aplicações e serviços web. Começaremos criando uma página da web de fácil uso que solicite aos usuários que se cadastrem com seu número de celular. Para enviar um código de confirmação por SMS para o número do usuário, usaremos a Verify API.

Assim que o usuário receber o código, basta inseri-lo em nosso aplicativo para concluir o processo de cadastro.

A autenticação de dois fatores (2FA) é o tipo mais básico e mais comum de autenticação multifatorial (MFA). Ao implementar a MFA com Java, você pode reduzir significativamente as chances de cadastros fraudulentos e aumentar a segurança geral dos dados dos seus usuários.

Vamos começar a criar um aplicativo mais seguro!

Pré-requisitos

Para desenvolver nosso aplicativo, usaremos o Java 8 e a framework web Spark. Também criaremos algumas visualizações básicas para os elementos da interface do usuário, utilizando o mecanismo de modelos Handlebars.

Antes de começarmos, certifique-se de ter o seguinte:

  • A Account da API da Vonage

    Abra sua página de configurações da API para acessar sua chave e seu segredo da API da Vonage, ambos exibidos conforme mostrado na captura de tela abaixo. A chave da API está localizada na parte superior da página e, para acessar seu segredo da API, consulte a subseção “Segredo da Account”. 

    Observação: caso você não se lembre do seu segredo de API criado anteriormente, clique em “+ Criar novo segredo” e guarde-o em um local seguro.

  • JDK ou seu equivalente de código aberto OpenJDK

  • Gradle (versão 3.4 ou mais recente) para gerenciar dependências e compilar seu projeto

Se precisar de ajuda para começar, não se preocupe! Nós podemos ajudar. Você pode encontrar o código-fonte de Mark Lewin para este tutorial no GitHub.

Instruções

A seguir, apresentamos instruções passo a passo para adicionar a autenticação multifatorial com Java, incluindo um exemplo prático. Este tutorial utiliza a autenticação de duas etapas por SMS (2FA), que envia uma mensagem de texto com um código de verificação para o celular do usuário. O código de verificação terá um prazo de validade integrado, o que torna esse método semelhante à autenticação por senha de uso único baseada em tempo (TOTP).

Aqui estão as etapas que você precisará seguir para implementar a autenticação de duas etapas (2FA) usando Java:

  1. Crie seu produto

  2. Criar um aplicativo web no Spark

  3. Inicializar a biblioteca do cliente Java

  4. Criar as visualizações

  5. Exibir a página de cadastro inicial

  6. Enviar a solicitação de verificação

  7. Verifique o código de confirmação

  8. Experimente!

Crie seu projeto

Primeiro, crie uma pasta chamada “two-factor-auth" para o seu projeto. Em seguida, acesse esse diretório e use o Gradle para inicializar o projeto. Aceite todas as configurações padrão e, depois, abra o projeto gerado no seu IDE.

Localize o build.gradle arquivo e substitua a dependencies seção pelo seguinte:

dependencies {
    // This dependency is used by the application.
    //implementation 'com.google.guava:guava:27.1-jre'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.13.2'

    // Javalin framework
    //implementation 'io.javalin:javalin:5.4.2'

    // Spark framework
    implementation 'com.sparkjava:spark-core:2.9.4'

    // Vonage client library
    implementation 'com.vonage:client:7.2.0'

    // Templating engine
    implementation 'com.sparkjava:spark-template-handlebars:2.7.1'
}

Não vamos escrever nenhum teste de unidade neste exemplo, mas você pode deixar JUnit isso lá por enquanto. No entanto, para evitar que o sistema reclame mais tarde por falta de um método de saudação, coloque o teste entre comentários src/test/java/two/factor/auth/AppTest.java da seguinte maneira:

public class AppTest {
  /*
   * @Test public void testAppHasAGreeting() { App classUnderTest = new App();
   * assertNotNull("app should have a greeting", classUnderTest.getGreeting()); }
   */
}

Criar um aplicativo web no Spark

O Gradle criou a App classe na src/main/java/two/factor/auth/App.java pasta.

Abra App.java no seu IDE. Remova o getGreeting() método que gradle foi criado para você e adicione as import instruções necessárias para o spark pacote.

Em seguida, chame o método port para indicar que seu aplicativo está à espera de solicitações na porta 3000.

O seu App.java deveria ficar assim:

package two.factor.auth;

import static spark.Spark.*;

public class App {

  public static void main(String[] args) {
    port(3000);

    // Your code goes here
  }
}

Inicializar a biblioteca do cliente Java

Para acessar a Verify API, você vai precisar usar a Biblioteca de Cliente da API REST para Java.

Instancie-o conforme mostrado abaixo, substituindo YOUR_API_KEY e YOUR_API_SECRET pela sua chave e segredo da API do painel do desenvolvedor. Certifique-se de incluir as instruções import necessárias para trabalhar com a Verify API:

package two.factor.auth;

import static spark.Spark.*;
// REST API Client Library for Java imports
import com.vonage.client.VonageClient;
import com.vonage.client.verify.*;

public class App {

  static String API_KEY = "YOUR_API_KEY";
  static String API_SECRET = "YOUR_API_SECRET";

  public static void main(String[] args) {
    port(3000);

    VonageClient client = VonageClient.builder().apiKey(API_KEY).apiSecret(API_SECRET).build();

  }
}

Criar as visualizações

Sua aplicação terá três páginas:

  • Uma página de cadastro, na qual seus usuários se cadastrarão no seu serviço inserindo o número do celular.

  • Uma página de confirmação, na qual será solicitado que insiram o código de confirmação enviado ao celular deles pela Verify API.

  • A página de resultados, na qual o aplicativo informará se o cadastro foi realizado com sucesso (caso o código de confirmação inserido esteja correto) ou se houve falha no cadastro (caso não esteja).

O Spark oferece suporte a diversos mecanismos de modelagem, o que permite inserir conteúdo em suas páginas HTML dinamicamente e também reutilizar blocos de HTML. Neste tutorial, usaremos o Handlebars.

Como queremos nos concentrar em ensinar a você como usar a Verify API aqui, não descreveremos como isso funciona neste artigo; em vez disso, pedimos que você baixe o conteúdo necessário do nosso repositório no GitHub.

Primeiro, inclua as seguintes importações no seu App.java arquivo, o que permitirá que você trabalhe com o Handlebars:

import spark.template.handlebars.HandlebarsTemplateEngine;
import spark.ModelAndView;

Em seguida, crie o src/main/resources/public e src/main/resources/templates diretórios.

Copie o conteúdo do arquivo arquivo styles.css no arquivo src/main/resources/public/styles.css.

Em seguida, copie os *.hbs arquivos de modelo na pasta “resources” no GitHub para src/main/resources/templates.

Certifique-se de que seu aplicativo reconheça o styles.css arquivo CSS estático, especificando a localização da pasta pai (public) no main método em App.java:

public static void main(String[] args) {
  port(3000);
  staticFiles.location("/public");

  VonageClient client = VonageClient.builder().apiKey(API_KEY).apiSecret(API_SECRET).build();

Exibir a página de cadastro inicial

Quando o usuário acessar seu site pela primeira vez, você deseja exibir a página de cadastro. Para isso, defina a rota padrão (/) usando spark e renderizando o register.hbs modelo conforme mostrado:

public static void main(String[] args) {
  port(3000);
  staticFiles.location("/public");

  VonageClient client = VonageClient.builder().apiKey(API_KEY).apiSecret(API_SECRET).build();

  get("/", (request, response) -> {
    return new ModelAndView(null, "register.hbs");
  }, new HandlebarsTemplateEngine());

Teste seu aplicativo executando gradle run e, em seguida, acessando http://localhost:3000 no seu navegador. Se você tiver configurado tudo corretamente, verá a seguinte página:

Two-factor authentication page prompting user to register to access this device2FA Registration Page

Enviar a solicitação de verificação

O usuário deve inserir seu número de celular na caixa de texto da página de cadastro e, em seguida, clicar em “Registrar-se” para iniciar o processo de verificação.

A Verify API espera que esse número inclua o código de discagem internacional, mas omita quaisquer zeros à esquerda. Por exemplo, o número do Reino Unido 07700 900001 deve ser representado como 447700900001.

Em um aplicativo de produção, talvez você queira determinar a localidade e o código do país corretos por meio de programação, e nós temos uma API para isso! Confira a Number Insight API. Por enquanto, porém, vamos manter as coisas simples.

Quando o usuário clicar “Registrar” , queremos capturar o número que ele digitou e enviar a solicitação de verificação.

Cada solicitação de verificação está associada a um ID de verificação. Precisamos manter um registro disso também, para que possamos usá-lo posteriormente para verificar se o usuário inseriu o código de confirmação correto.

Então, adicione duas variáveis de nível de classe para armazenar essas informações, abaixo do API_KEY e API_SECRET que você definiu anteriormente:

static String number, requestId;

Vamos enviar a solicitação de verificação a partir da /register rota; portanto, defina a rota da seguinte forma:

post("/register", (request, response) -> {
    number = request.queryParams("number");

    VerifyResponse verifyResponse = client.getVerifyClient().verify(number, "VONAGE");
    if (verifyResponse.getStatus() == VerifyStatus.OK) {
      requestId = verifyResponse.getRequestId();
      System.out.printf("RequestID: %s", requestId);
    }
    else {
      System.out.printf("ERROR! %s: %s", verifyResponse.getStatus(), verifyResponse.getErrorText());
    }

    return new ModelAndView(null, "verify.hbs");
  }, new HandlebarsTemplateEngine());

Esse código aciona a solicitação de verificação, primeiro recuperando uma instância de VerifyClient e, em seguida, chamando seu verify método, passando o número que queremos verificar e uma sequência alfanumérica usada para identificar o remetente no corpo da mensagem SMS.

Ele retorna um VerifyResponse objeto que podemos usar para verificar se a solicitação foi enviada com sucesso. Se for o caso, recuperamos o ID da solicitação de verificação e o usamos para conferir o código enviado ao usuário para essa tentativa específica de verificação na próxima etapa.

Assim que enviarmos a solicitação de verificação, o usuário receberá um código de verificação por SMS:

Text message with verification code for two-factor authentication2FA Verification SMS Shown in iPhone

Exibimos a verify.hbs visualização, para permitir que eles insiram o código que receberam:

Two-factor authentication page prompting user to enter verification code2FA Check Verification

Por padrão, após enviar o SMS, a Verify API aguarda o código por 125 segundos. Se não o receber dentro desse período, ela realiza duas chamadas telefônicas com sintetizador de voz antes de, finalmente, desistir e considerar a tentativa de verificação malsucedida. Você pode saber mais sobre o fluxo de trabalho padrão e como habilitar diferentes fluxos de trabalho ler a documentação.

Verifique o código de confirmação

Agora precisamos implementar a lógica necessária para verificar o código que eles digitaram. Crie a /check rota para isso:

  post("/check", (request, response) -> {
    String code = request.queryParams("code");
    CheckResponse checkResponse = client.getVerifyClient().check(requestId, code);
    return new ModelAndView(null, checkResponse.getStatus() == VerifyStatus.OK ? "success.hbs" : "failed.hbs");

  }, new HandlebarsTemplateEngine());

Este código utiliza o VerifyClient.check método, passando a ele o ID da solicitação que armazenamos na etapa de verificação e o código que o usuário digitou na verify.hbs visualização.

O check método retorna um CheckResponse objeto. Usamos seu getStatus para determinar se o usuário digitou o código correto e exibir a resposta apropriada na result.hbs visualização. Se o usuário digitou o código corretamente, recebemos a seguinte mensagem:

Two-factor authentication page with verification success messageVerification Success

Se o usuário digitar o código incorretamente, receberemos a seguinte mensagem.

Two-factor authentication page with verification failed messageVerification Failed

Experimente!

  1. Execute gradle run no seu terminal.

  2. Acesse http://localhost:3000 no seu navegador.

  3. Digite seu número de celular e clique em Registrar. Em alguns instantes, você receberá um SMS contendo um código de verificação.

  4. Digite o código de verificação e clique em Verificar.

  5. Se você digitou o código corretamente, receberá uma mensagem informando “Registro concluído com sucesso”.

Conclusão

Essas são as etapas fundamentais para implementar a autenticação de dois fatores em suas aplicações web em Java usando a Verify API. Para obter mais informações, consulte os links da documentação fornecidos abaixo.

Tem alguma dúvida ou quer compartilhar o que está criando?

Fique conectado e acompanhe as últimas notícias, dicas e eventos para desenvolvedores.

Leitura complementar

Compartilhar:

https://a.storyblok.com/f/270183/384x384/b68093ec17/diana-pham.png
Diana PhamRepresentante de Desenvolvedores

Diana é defensora de desenvolvedores na Vonage. Ela gosta de comer ostras frescas.