As of November 2022, Twilio no longer provides support for Authy SMS/Voice-only customers. Customers who were also using Authy TOTP or Push prior to March 1, 2023 are still supported. The Authy API is now closed to new customers and will be fully deprecated in the future.
For new development, we encourage you to use the Verify v2 API.
Existing customers will not be impacted at this time until Authy API has reached End of Life. For more information about migration, see Migrating from Authy to Verify for SMS.
This Java Servlets sample application demonstrates two-factor authentication (2FA) using Authy. To run this sample app yourself, download the code and follow the instructions on GitHub.
Adding two-factor authentication (2FA) to your web application increases the security of your user's data. Multi-factor authentication determines the identity of a user by validating first by logging into the app, and then through their mobile devices using Authy.
For the second factor, we will validate that the user has their mobile phone by either:
_31package com.twilio.authy2fa;_31_31import org.eclipse.jetty.server.Request;_31import org.eclipse.jetty.server.Server;_31import org.eclipse.jetty.server.handler.AbstractHandler;_31_31import javax.servlet.ServletException;_31import javax.servlet.http.HttpServletRequest;_31import javax.servlet.http.HttpServletResponse;_31import java.io.IOException;_31_31public class App extends AbstractHandler {_31_31 public static void main(String[] args) throws Exception {_31 Server server = new Server(8080);_31 server.setHandler(new App());_31_31 server.start();_31 server.join();_31 }_31_31 public void handle(String target,_31 Request baseRequest,_31 HttpServletRequest request,_31 HttpServletResponse response)_31 throws IOException, ServletException {_31 response.setContentType("text/html;charset=utf-8");_31 response.setStatus(HttpServletResponse.SC_OK);_31 baseRequest.setHandled(true);_31 }_31}
See how VMware uses Authy 2FA to secure their enterprise mobility management solution.
If you haven't already, now is the time to sign up for Authy. Create your first application, naming it as you wish. After you create your application, your production API key will be visible on your dashboard:
Once we have an Authy API key, we store it on this .env
file, which helps us set the environment variables for our app.
You'll also want to set a callback URL for your application in the OneTouch section of the Authy dashboard. See the project's README for more details.
src/main/java/com/twilio/authy2fa/servlet/RegistrationServlet.java
_101package com.twilio.authy2fa.servlet;_101_101import com.authy.AuthyApiClient;_101import com.twilio.authy2fa.exception.AuthyRequestException;_101import com.twilio.authy2fa.lib.RequestParametersValidator;_101import com.twilio.authy2fa.models.User;_101import com.twilio.authy2fa.models.UserService;_101import com.twilio.authy2fa.lib.SessionManager;_101import com.twilio.authy2fa.service.AuthyRequestService;_101import org.slf4j.Logger;_101import org.slf4j.LoggerFactory;_101_101import javax.servlet.ServletException;_101import javax.servlet.annotation.WebServlet;_101import javax.servlet.http.HttpServlet;_101import javax.servlet.http.HttpServletRequest;_101import javax.servlet.http.HttpServletResponse;_101import java.io.IOException;_101_101@WebServlet(urlPatterns = "/registration")_101public class RegistrationServlet extends HttpServlet{_101_101 private final SessionManager sessionManager;_101 private final UserService userService;_101 private final AuthyRequestService authyRequestService;_101_101 private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationServlet.class);_101_101_101 @SuppressWarnings("unused")_101 public RegistrationServlet() {_101 this(_101 new SessionManager(),_101 new UserService(),_101 new AuthyRequestService()_101 );_101 }_101_101 public RegistrationServlet(SessionManager sessionManager, UserService userService,_101 AuthyRequestService authyRequestService) {_101 this.sessionManager = sessionManager;_101 this.userService = userService;_101 this.authyRequestService = authyRequestService;_101 }_101_101 protected void doGet(HttpServletRequest request, HttpServletResponse response)_101 throws ServletException, IOException {_101_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101_101 protected void doPost(HttpServletRequest request, HttpServletResponse response)_101 throws ServletException, IOException {_101_101 String name = request.getParameter("name");_101 String email = request.getParameter("email");_101 String password = request.getParameter("password");_101 String countryCode = request.getParameter("countryCode");_101 String phoneNumber = request.getParameter("phoneNumber");_101_101 if (validateRequest(request)) {_101_101 try {_101 int authyId = authyRequestService.sendRegistrationRequest(email, phoneNumber, countryCode);_101_101 userService.create(new User(name, email, password, countryCode, phoneNumber, authyId));_101_101 response.sendRedirect("/login.jsp");_101 } catch (AuthyRequestException e) {_101_101 LOGGER.error(e.getMessage());_101_101 request.setAttribute("data", "Registration failed");_101 preserveStatusRequest(request, name, email, countryCode, phoneNumber);_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101 } else {_101 preserveStatusRequest(request, name, email, countryCode, phoneNumber);_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101 }_101_101 private boolean validateRequest(HttpServletRequest request) {_101 RequestParametersValidator validator = new RequestParametersValidator(request);_101_101 return validator.validatePresence("name", "email", "password", "countryCode", "phoneNumber")_101 && validator.validateEmail("email");_101 }_101_101 private void preserveStatusRequest(_101 HttpServletRequest request,_101 String name,_101 String email,_101 String countryCode,_101 String phoneNumber) {_101 request.setAttribute("name", name);_101 request.setAttribute("email", email);_101 request.setAttribute("countryCode", countryCode);_101 request.setAttribute("phoneNumber", phoneNumber);_101 }_101}
Let's take a look at how we register a user with Authy.
When a new user signs up for our website, we call this controller, which handles saving our new user to the database as well as registering the user with Authy.
All Authy needs to get a user set up for your application is the email, phone number and country code. In order to do two-factor authentication, we need to make sure we ask for these things at the point of sign up.
Once we register the user with Authy we can get the user's authy_id
back. This is very important since it's how we will verify the identity of our User with Authy.
src/main/java/com/twilio/authy2fa/servlet/RegistrationServlet.java
_101package com.twilio.authy2fa.servlet;_101_101import com.authy.AuthyApiClient;_101import com.twilio.authy2fa.exception.AuthyRequestException;_101import com.twilio.authy2fa.lib.RequestParametersValidator;_101import com.twilio.authy2fa.models.User;_101import com.twilio.authy2fa.models.UserService;_101import com.twilio.authy2fa.lib.SessionManager;_101import com.twilio.authy2fa.service.AuthyRequestService;_101import org.slf4j.Logger;_101import org.slf4j.LoggerFactory;_101_101import javax.servlet.ServletException;_101import javax.servlet.annotation.WebServlet;_101import javax.servlet.http.HttpServlet;_101import javax.servlet.http.HttpServletRequest;_101import javax.servlet.http.HttpServletResponse;_101import java.io.IOException;_101_101@WebServlet(urlPatterns = "/registration")_101public class RegistrationServlet extends HttpServlet{_101_101 private final SessionManager sessionManager;_101 private final UserService userService;_101 private final AuthyRequestService authyRequestService;_101_101 private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationServlet.class);_101_101_101 @SuppressWarnings("unused")_101 public RegistrationServlet() {_101 this(_101 new SessionManager(),_101 new UserService(),_101 new AuthyRequestService()_101 );_101 }_101_101 public RegistrationServlet(SessionManager sessionManager, UserService userService,_101 AuthyRequestService authyRequestService) {_101 this.sessionManager = sessionManager;_101 this.userService = userService;_101 this.authyRequestService = authyRequestService;_101 }_101_101 protected void doGet(HttpServletRequest request, HttpServletResponse response)_101 throws ServletException, IOException {_101_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101_101 protected void doPost(HttpServletRequest request, HttpServletResponse response)_101 throws ServletException, IOException {_101_101 String name = request.getParameter("name");_101 String email = request.getParameter("email");_101 String password = request.getParameter("password");_101 String countryCode = request.getParameter("countryCode");_101 String phoneNumber = request.getParameter("phoneNumber");_101_101 if (validateRequest(request)) {_101_101 try {_101 int authyId = authyRequestService.sendRegistrationRequest(email, phoneNumber, countryCode);_101_101 userService.create(new User(name, email, password, countryCode, phoneNumber, authyId));_101_101 response.sendRedirect("/login.jsp");_101 } catch (AuthyRequestException e) {_101_101 LOGGER.error(e.getMessage());_101_101 request.setAttribute("data", "Registration failed");_101 preserveStatusRequest(request, name, email, countryCode, phoneNumber);_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101 } else {_101 preserveStatusRequest(request, name, email, countryCode, phoneNumber);_101 request.getRequestDispatcher("/registration.jsp").forward(request, response);_101 }_101 }_101_101 private boolean validateRequest(HttpServletRequest request) {_101 RequestParametersValidator validator = new RequestParametersValidator(request);_101_101 return validator.validatePresence("name", "email", "password", "countryCode", "phoneNumber")_101 && validator.validateEmail("email");_101 }_101_101 private void preserveStatusRequest(_101 HttpServletRequest request,_101 String name,_101 String email,_101 String countryCode,_101 String phoneNumber) {_101 request.setAttribute("name", name);_101 request.setAttribute("email", email);_101 request.setAttribute("countryCode", countryCode);_101 request.setAttribute("phoneNumber", phoneNumber);_101 }_101}
Having registered our user with Authy, we then can use Authy's OneTouch feature to log them in.
When a User attempts to log in to our website, we will ask them for a second form of identification. Let's take a look at OneTouch verification first.
OneTouch works as follows:
approved
status.
TwilioDevEd/authy2fa-servlets/src/main/java/com/twilio/authy2fa/service/ApprovalRequestService.java
_94package com.twilio.authy2fa.service;_94_94import com.authy.AuthyApiClient;_94import com.authy.OneTouchException;_94import com.authy.api.ApprovalRequestParams;_94import com.authy.api.Hash;_94import com.authy.api.OneTouchResponse;_94import com.fasterxml.jackson.core.type.TypeReference;_94import com.fasterxml.jackson.databind.ObjectMapper;_94import com.twilio.authy2fa.exception.ApprovalRequestException;_94import com.twilio.authy2fa.models.User;_94import org.apache.http.client.fluent.Request;_94_94import java.io.IOException;_94import java.util.HashMap;_94import java.util.Map;_94_94public class ApprovalRequestService {_94_94 private static final String AUTHY_USERS_URI_TEMPLATE = "%s/protected/json/users/%s/status?api_key=%s";_94 private final String authyBaseURL;_94_94 private final ConfigurationService configuration;_94 private final AuthyApiClient client;_94_94 public ApprovalRequestService() {_94 this.authyBaseURL = "https://api.authy.com";_94 this.configuration = new ConfigurationService();_94 this.client = new AuthyApiClient(configuration.authyApiKey());_94 }_94_94 public ApprovalRequestService(String authyBaseURL, ConfigurationService configuration, AuthyApiClient client) {_94 this.authyBaseURL = authyBaseURL;_94 this.configuration = configuration;_94 this.client = client;_94 }_94_94 public String sendApprovalRequest(User user) {_94 if(hasAuthyApp(user)){_94 try {_94 OneTouchResponse result = sendOneTouchApprovalRequest(user);_94 if(!result.isSuccess()) {_94 throw new ApprovalRequestException(result.getMessage());_94 }_94 return "onetouch";_94 } catch (IOException | OneTouchException e) {_94 throw new ApprovalRequestException(e.getMessage());_94 }_94 } else {_94 Hash result = sendSMSToken(user);_94 if(!result.isSuccess()) {_94 throw new ApprovalRequestException(result.getMessage());_94 }_94 return "sms";_94 }_94 }_94_94 private boolean hasAuthyApp(User user) {_94 ObjectMapper objectMapper = new ObjectMapper();_94 String url = String.format(AUTHY_USERS_URI_TEMPLATE,_94 authyBaseURL,_94 user.getAuthyId(),_94 configuration.authyApiKey()_94 );_94 try {_94 String responseBody = Request.Get(url)_94 .connectTimeout(10000)_94 .socketTimeout(10000)_94 .execute().returnContent().asString();_94 TypeReference<HashMap<String,Object>> typeRef_94 = new TypeReference<HashMap<String,Object>>() {};_94 HashMap<String,HashMap> o = objectMapper.readValue(responseBody, typeRef);_94_94 return (Boolean) ((Map<String, Object>)o.get("status")).get("registered");_94 } catch (IOException e) {_94 throw new ApprovalRequestException(e.getMessage());_94 }_94 }_94_94 private OneTouchResponse sendOneTouchApprovalRequest(User user)_94 throws IOException, OneTouchException {_94 ApprovalRequestParams parameters = new ApprovalRequestParams.Builder(_94 Integer.valueOf(user.getAuthyId()),_94 "Request login to Twilio demo app")_94 .addDetail("email", user.getEmail())_94 .build();_94_94 return client.getOneTouch().sendApprovalRequest(parameters);_94 }_94_94 private Hash sendSMSToken(User user){_94 return client.getUsers().requestSms(Integer.valueOf(user.getAuthyId()));_94 }_94}
Now let's look at how to send a OneTouch request.
When our user logs in, our app decides which two-factor authentication provider will be used. It can be Authy OneTouch or an SMS token.
Authy OneTouch will be used when the user has a registered OneTouch device.
We use the sendApprovalRequest
method to create an approval request. It takes an ApprovalRequestParamater
object with at least the following properties configured:
Here is an example about how to build the parameters object.
_10ApprovalRequestParams parameters = new ApprovalRequestParams.Builder(_10 Integer.valueOf(user.getAuthyId()),_10 "Request login to Twilio demo app")_10 .addDetail("email", "alice@example.com")_10 .addDetail("name", "Alice")_10 .addHiddenDetail("phoneNumber", "555-5555")_10 .build();
TwilioDevEd/authy2fa-servlets/src/main/java/com/twilio/authy2fa/service/ApprovalRequestService.java
_94package com.twilio.authy2fa.service;_94_94import com.authy.AuthyApiClient;_94import com.authy.OneTouchException;_94import com.authy.api.ApprovalRequestParams;_94import com.authy.api.Hash;_94import com.authy.api.OneTouchResponse;_94import com.fasterxml.jackson.core.type.TypeReference;_94import com.fasterxml.jackson.databind.ObjectMapper;_94import com.twilio.authy2fa.exception.ApprovalRequestException;_94import com.twilio.authy2fa.models.User;_94import org.apache.http.client.fluent.Request;_94_94import java.io.IOException;_94import java.util.HashMap;_94import java.util.Map;_94_94public class ApprovalRequestService {_94_94 private static final String AUTHY_USERS_URI_TEMPLATE = "%s/protected/json/users/%s/status?api_key=%s";_94 private final String authyBaseURL;_94_94 private final ConfigurationService configuration;_94 private final AuthyApiClient client;_94_94 public ApprovalRequestService() {_94 this.authyBaseURL = "https://api.authy.com";_94 this.configuration = new ConfigurationService();_94 this.client = new AuthyApiClient(configuration.authyApiKey());_94 }_94_94 public ApprovalRequestService(String authyBaseURL, ConfigurationService configuration, AuthyApiClient client) {_94 this.authyBaseURL = authyBaseURL;_94 this.configuration = configuration;_94 this.client = client;_94 }_94_94 public String sendApprovalRequest(User user) {_94 if(hasAuthyApp(user)){_94 try {_94 OneTouchResponse result = sendOneTouchApprovalRequest(user);_94 if(!result.isSuccess()) {_94 throw new ApprovalRequestException(result.getMessage());_94 }_94 return "onetouch";_94 } catch (IOException | OneTouchException e) {_94 throw new ApprovalRequestException(e.getMessage());_94 }_94 } else {_94 Hash result = sendSMSToken(user);_94 if(!result.isSuccess()) {_94 throw new ApprovalRequestException(result.getMessage());_94 }_94 return "sms";_94 }_94 }_94_94 private boolean hasAuthyApp(User user) {_94 ObjectMapper objectMapper = new ObjectMapper();_94 String url = String.format(AUTHY_USERS_URI_TEMPLATE,_94 authyBaseURL,_94 user.getAuthyId(),_94 configuration.authyApiKey()_94 );_94 try {_94 String responseBody = Request.Get(url)_94 .connectTimeout(10000)_94 .socketTimeout(10000)_94 .execute().returnContent().asString();_94 TypeReference<HashMap<String,Object>> typeRef_94 = new TypeReference<HashMap<String,Object>>() {};_94 HashMap<String,HashMap> o = objectMapper.readValue(responseBody, typeRef);_94_94 return (Boolean) ((Map<String, Object>)o.get("status")).get("registered");_94 } catch (IOException e) {_94 throw new ApprovalRequestException(e.getMessage());_94 }_94 }_94_94 private OneTouchResponse sendOneTouchApprovalRequest(User user)_94 throws IOException, OneTouchException {_94 ApprovalRequestParams parameters = new ApprovalRequestParams.Builder(_94 Integer.valueOf(user.getAuthyId()),_94 "Request login to Twilio demo app")_94 .addDetail("email", user.getEmail())_94 .build();_94_94 return client.getOneTouch().sendApprovalRequest(parameters);_94 }_94_94 private Hash sendSMSToken(User user){_94 return client.getUsers().requestSms(Integer.valueOf(user.getAuthyId()));_94 }_94}
Once we send the request we need to update our user's AuthyStatus
based on the response. But first we have to register a OneTouch callback endpoint.
In order for our app to know what the user did after we sent the OneTouch request, we need to register a callback endpoint with Authy.
Note: In order to verify that the request is coming from Authy, we've written the helper method validate
that will halt the request if it appears that it isn't coming from Authy.
Here in our callback, we look up the user using the Authy ID sent with the Authy POST request. Ideally at this point we would probably use a websocket to let our client know that we received a response from Authy. However for this version we're going to keep it simple and just update the AuthyStatus
on the User. What our client-side code needs to do is to check for user.AuthyStatus == "approved"
before logging him/her in.
src/main/java/com/twilio/authy2fa/servlet/authy/CallbackServlet.java
_55package com.twilio.authy2fa.servlet.authy;_55_55import com.twilio.authy2fa.models.User;_55import com.twilio.authy2fa.models.UserService;_55import com.twilio.authy2fa.servlet.requestvalidation.AuthyRequestValidator;_55import com.twilio.authy2fa.servlet.requestvalidation.RequestValidationResult;_55import org.slf4j.Logger;_55import org.slf4j.LoggerFactory;_55_55import javax.servlet.ServletException;_55import javax.servlet.annotation.WebServlet;_55import javax.servlet.http.HttpServlet;_55import javax.servlet.http.HttpServletRequest;_55import javax.servlet.http.HttpServletResponse;_55import java.io.IOException;_55_55@WebServlet(urlPatterns = {"/authy/callback"})_55public class CallbackServlet extends HttpServlet {_55_55 private static final Logger LOGGER = LoggerFactory.getLogger(CallbackServlet.class);_55_55 private final UserService userService;_55_55_55 @SuppressWarnings("unused")_55 public CallbackServlet() {_55 this(new UserService());_55 }_55_55 public CallbackServlet(UserService userService) {_55 this.userService = userService;_55 }_55_55 protected void doPost(HttpServletRequest request, HttpServletResponse response)_55 throws ServletException, IOException {_55_55 AuthyRequestValidator validator = new AuthyRequestValidator(_55 System.getenv("AUTHY_API_KEY"), request);_55 RequestValidationResult validationResult = validator.validate();_55_55 if (validationResult.isValidSignature()) {_55 // Handle approved, denied, unauthorized_55 User user = userService.findByAuthyId(validationResult.getAuthyId());_55 if(user != null) {_55 user.setAuthyStatus(validationResult.getStatus());_55 userService.update(user);_55 }_55 } else {_55_55 LOGGER.error("Received Authy callback but couldn't verify the signature");_55_55 response.sendError(403, "Invalid signature");_55 }_55 }_55}
Our application is now capable of using Authy for two-factor authentication. However, we are still missing an important part: the client-side code that will handle it.
Scenario: The OneTouch callback URL provided by you is no longer active.
Action: We will disable the OneTouch callback after 3 consecutive HTTP error responses. We will also
How to enable OneTouch callback? You need to update the OneTouch callback endpoint, which will allow the OneTouch callback.
Visit the Twilio Console: Console > Authy > Applications > {ApplicationName} > Push Authentication > Webhooks > Endpoint/URL to update the Endpoint/URL with a valid OneTouch callback URL.
We've already taken a look at what's happening on the server side, so let's step in front of the cameras and see how our JavaScript is interacting with those server endpoints.
When we expect a OneTouch response, we will begin polling /authy/status
until we see Authy status is not empty.
src/main/webapp/javascript/application.js
_60$(document).ready(function() {_60 $("#login-form").submit(function(event) {_60 event.preventDefault();_60_60 var data = $(event.currentTarget).serialize();_60 authyVerification(data);_60 });_60_60 var authyVerification = function (data) {_60 $.post("/login", data, function (result) {_60 resultActions[result]();_60 });_60 };_60_60 var resultActions = {_60 onetouch: function() {_60 $("#authy-modal").modal({ backdrop: "static" }, "show");_60 $(".auth-token").hide();_60 $(".auth-onetouch").fadeIn();_60 monitorOneTouchStatus();_60 },_60_60 sms: function () {_60 $("#authy-modal").modal({ backdrop: "static" }, "show");_60 $(".auth-onetouch").hide();_60 $(".auth-token").fadeIn();_60 requestAuthyToken();_60 },_60_60 unauthorized: function () {_60 $("#error-message").text("Invalid credentials");_60 },_60_60 unexpectedError: function () {_60 $("#error-message").text("Unexpected error. Check the logs");_60 }_60 };_60_60 var monitorOneTouchStatus = function () {_60 $.post("/authy/status")_60 .done(function (data) {_60 if (data === "") {_60 setTimeout(monitorOneTouchStatus, 2000);_60 } else {_60 $("#confirm-login").submit();_60 }_60 });_60 }_60_60 var requestAuthyToken = function () {_60 $.post("/authy/request-token")_60 .done(function (data) {_60 $("#authy-token-label").text(data);_60 });_60 }_60_60 $("#logout").click(function() {_60 $("#logout-form").submit();_60 });_60});
Let's take a closer look at how we check the login status on the server.
This is the endpoint that our JavaScript is polling. It is waiting for the user Authy status.
src/main/java/com/twilio/authy2fa/servlet/authy/OneTouchStatusServlet.java
_38package com.twilio.authy2fa.servlet.authy;_38_38import com.twilio.authy2fa.lib.SessionManager;_38import com.twilio.authy2fa.models.User;_38import com.twilio.authy2fa.models.UserService;_38_38import javax.servlet.ServletException;_38import javax.servlet.annotation.WebServlet;_38import javax.servlet.http.HttpServlet;_38import javax.servlet.http.HttpServletRequest;_38import javax.servlet.http.HttpServletResponse;_38import java.io.IOException;_38_38@WebServlet(urlPatterns = {"/authy/status"})_38public class OneTouchStatusServlet extends HttpServlet {_38_38 private final SessionManager sessionManager;_38 private final UserService userService;_38_38 @SuppressWarnings("unused")_38 public OneTouchStatusServlet() {_38 this(new SessionManager(), new UserService());_38 }_38_38 public OneTouchStatusServlet(SessionManager sessionManager, UserService userService) {_38 this.sessionManager = sessionManager;_38 this.userService = userService;_38 }_38_38 protected void doPost(HttpServletRequest request, HttpServletResponse response)_38 throws ServletException, IOException {_38_38 long userId = sessionManager.getLoggedUserId(request);_38 User user = userService.find(userId);_38_38 response.getOutputStream().write(user.getAuthyStatus().getBytes());_38 }_38}
Finally, we can confirm the login.
If the AuthyStatus
is approved , the user will be redirected to the account page, otherwise we'll show the login form with a message that indicates if the request was denied or unauthorized.
src/main/java/com/twilio/authy2fa/servlet/authentication/ConfirmLogInServlet.java
_59package com.twilio.authy2fa.servlet.authentication;_59_59import com.twilio.authy2fa.lib.SessionManager;_59import com.twilio.authy2fa.models.User;_59import com.twilio.authy2fa.models.UserService;_59_59import javax.servlet.ServletException;_59import javax.servlet.annotation.WebServlet;_59import javax.servlet.http.HttpServlet;_59import javax.servlet.http.HttpServletRequest;_59import javax.servlet.http.HttpServletResponse;_59import java.io.IOException;_59_59@WebServlet(urlPatterns = {"/confirm-login"})_59public class ConfirmLogInServlet extends HttpServlet {_59_59 private final SessionManager sessionManager;_59 private final UserService userService;_59_59 @SuppressWarnings("unused")_59 public ConfirmLogInServlet() {_59 this(new SessionManager(), new UserService());_59 }_59_59 public ConfirmLogInServlet(SessionManager sessionManager, UserService userService) {_59 this.sessionManager = sessionManager;_59 this.userService = userService;_59 }_59_59 protected void doPost(HttpServletRequest request, HttpServletResponse response)_59 throws ServletException, IOException {_59_59 long userId = sessionManager.getLoggedUserId(request);_59 User user = userService.find(userId);_59_59 String authyStatus = user.getAuthyStatus();_59_59 // Reset the Authy status_59 user.setAuthyStatus("");_59 userService.update(user);_59_59 switch (authyStatus) {_59 case "approved":_59 sessionManager.logIn(request, user.getId());_59 response.sendRedirect("/account");_59 break;_59 case "denied":_59 sessionManager.logOut(request);_59 request.setAttribute("data", "You have declined the request");_59 request.getRequestDispatcher("/login.jsp").forward(request, response);_59 break;_59 default:_59 sessionManager.logOut(request);_59 request.setAttribute("data", "Unauthorized access");_59 request.getRequestDispatcher("/login.jsp").forward(request, response);_59 break;_59 }_59 }_59}
That's it! We've just implemented two-factor auth using three different methods and the latest in Authy technology.
If you're a Java developer working with Twilio, you might enjoy these other tutorials:
Click-to-call enables your company to convert web traffic into phone calls with the click of a button
Thanks for checking out this tutorial! If you have any feedback to share with us, we'd love to hear it. Connect with us on Twitter and let us know what you build!