How to Implement Two-Factor Authentication in Spring Boot

Alexander Obregon
7 min readApr 21, 2024

--

Image Source

Introduction

Two-factor authentication (2FA) is a security process that requires users to verify their identity using two different authentication factors before gaining access to an online account. This additional layer of security helps protect against unauthorized access resulting from compromised credentials. In this article, we will explore how to implement two-factor authentication in a Spring Boot application, specifically focusing on integration with SMS and email verification systems.

Two-Factor Authentication Basics

Two-Factor Authentication (2FA) is an enhanced security process that requires two different forms of identification from the user to grant access to an online account or application. This method is designed to protect against unauthorized access that can occur if user passwords are compromised. By requiring a second form of verification, 2FA significantly lowers the risk of potential security breaches.

The Necessity of Two-Factor Authentication

Data breaches and security threats are becoming more sophisticated, traditional username and password combinations often do not provide sufficient protection. Passwords can be weak, reused across multiple sites, or stolen through phishing attacks and data breaches. Two-Factor Authentication adds an extra layer of security by combining something the user knows (like a password) with something the user possesses (such as a code sent to a smartphone or an email), or in some cases, something inherent to the user (like a fingerprint or face ID).

How Two-Factor Authentication Works

Two-Factor Authentication works by integrating two of the following three authentication factors:

  1. Knowledge Factors: Something the user knows, such as a password, PIN, or another type of shared secret.
  2. Possession Factors: Something the user has, like a security token, a smartphone app that generates time-limited codes, or a smart card.
  3. Inherence Factors: Something the user is, typically involving biometrics, such as fingerprints, facial recognition, or voice patterns.

In the context of web applications, 2FA most commonly involves the user first entering a password followed by a verification code. This code can be delivered in several ways:

  • SMS-based Verification: Upon successful entry of their password, the user receives a code via text message that they must enter to gain access.
  • Email-based Verification: Similar to SMS, a code is sent to the user’s email address and must be entered on the site to complete the authentication process.
  • Authenticator Apps: Applications like Google Authenticator or Authy generate time-limited codes that sync with the server time to provide a code that can be used for the second factor.

Advantages of Implementing Two-Factor Authentication

The implementation of 2FA provides numerous benefits, the foremost being enhanced security. By requiring a second piece of evidence to verify user identity, 2FA reduces the risk of unauthorized access, even if the user’s password is known by someone else. This is particularly important for protecting sensitive data in sectors like finance, healthcare, and public services.

Also, 2FA can help in regulatory compliance as many industry guidelines and government regulations recommend or require enhanced security measures, including multifactor authentication. This can help organizations in meeting legal obligations and avoiding potential penalties.

Common Challenges with Two-Factor Authentication

While 2FA significantly increases security, it is not without challenges. For instance, it can introduce additional steps in the user experience, potentially leading to a slight delay or inconvenience. There is also the possibility of losing access to the second factor, such as not having a phone available for SMS or losing access to the registered email account.

Despite these challenges, the benefits of implementing Two-Factor Authentication far outweigh the potential drawbacks, especially in an environment where digital security threats are ever-increasing.

Implementing SMS-Based 2FA in Spring Boot

Implementing SMS-based Two-Factor Authentication (2FA) in a Spring Boot application involves using an SMS gateway to send verification codes. Twilio is a popular choice for this purpose due to its strong API and global reach. Here’s how you can set up and integrate Twilio for SMS-based 2FA in your Spring Boot project.

Setting Up Twilio

To begin, you need to create a Twilio account and set up your development environment:

  1. Sign up for a free Twilio account at the Twilio website.
  2. Once logged in, navigate to the dashboard to retrieve your Account SID and Auth Token. These credentials are needed for your application to communicate securely with Twilio.
  3. Obtain a Twilio phone number through the console. This number will be used to send SMS messages to your users.

Adding Twilio Dependencies

Incorporate Twilio’s Java SDK into your Spring Boot project to enable API calls for sending SMS messages. You can do this by adding the Twilio SDK dependency to your Maven pom.xml file:

<dependency>
<groupId>com.twilio.sdk</groupId>
<artifactId>twilio</artifactId>
<version>8.25.0</version>
</dependency>

Configuring the SMS Service

Create a service class in your Spring Boot application that will handle SMS operations:

import com.twilio.Twilio;
import com.twilio.rest.api.v2010.account.Message;
import com.twilio.type.PhoneNumber;

@Service
public class SmsService {
private static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID";
private static final String AUTH_TOKEN = "YOUR_AUTH_TOKEN";
private static final String FROM_NUMBER = "YOUR_TWILIO_PHONE_NUMBER";

@PostConstruct
public void init() {
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
}

public void sendSms(String to, String body) {
Message.creator(new PhoneNumber(to), new PhoneNumber(FROM_NUMBER), body).create();
}
}

Handling the Verification Process

To manage the 2FA process, you need a mechanism to generate a verification code, send it via SMS, and verify it against the user’s input:

  1. Code Generation: Implement a method to generate a random 6-digit code. This code will be sent as the second factor during the login process.
  2. Code Transmission: Use the SmsService to send this code to the user's mobile number.
  3. Code Verification: Store the generated code temporarily, often in the session or a temporary datastore, and compare it with the user’s input to verify.

Here’s an example of how you could manage this process:

import java.util.Random;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TwoFactorAuthenticationService {
@Autowired
private SmsService smsService;

public String generateVerificationCode() {
return String.format("%06d", new Random().nextInt(999999));
}

public void sendVerificationCode(String phoneNumber) {
String code = generateVerificationCode();
smsService.sendSms(phoneNumber, "Your verification code is: " + code);
}

public boolean verifyCode(String phoneNumber, String inputCode, String actualCode) {
return actualCode.equals(inputCode);
}
}

This setup effectively integrates SMS-based 2FA in your Spring Boot application, using Twilio to send verification codes and improving the security of user authentication processes.

Implementing Email-Based 2FA in Spring Boot

For email-based Two-Factor Authentication (2FA), you can use Spring Boot’s integrated support for JavaMail to send verification codes via email. This method involves configuring a mail server, implementing the email sending service, and handling the verification process.

Configuring JavaMail with Spring Boot

Spring Boot simplifies mail integration through the spring-boot-starter-mail dependency, which abstracts much of the boilerplate needed to send emails. Here's how you set it up:

  • Add the Mail Dependency: Include the Spring Boot Starter Mail dependency in your project’s Maven pom.xml file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>3.0.3</version> <!-- Make sure this matches your Spring Boot version -->
</dependency>
  • Configure Mail Properties: In your application.properties or application.yml, set up the properties to connect to your email server. Here’s an example using Gmail:
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your.email@gmail.com
spring.mail.password=your-email-password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
  • Replace your.email@gmail.com and your-email-password with your actual Gmail credentials. Note that for Gmail, you might need to enable "Access for less secure apps" or set up an "App Password" if you use two-step verification.

Implementing the Email Service

Create a service in Spring Boot to handle the sending of emails:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;

public void sendEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setSubject(subject);
message.setText(text);
mailSender.send(message);
}
}

This service utilizes JavaMailSender to send simple text emails. You can extend this to send HTML emails or include attachments as needed.

Managing the Verification Process

Similar to SMS-based verification, you will need to generate a code, send it via email, and verify it:

  1. Code Generation: Use a secure method to generate a temporary, unique verification code.
  2. Code Transmission: Send this code to the user’s registered email address using the EmailService.
  3. Code Verification: Compare the user-submitted code with the one you sent to authenticate the user.

Here’s an implementation example:

import java.util.Random;

@Service
public class EmailVerificationService {
@Autowired
private EmailService emailService;

public String generateVerificationCode() {
return String.format("%06d", new Random().nextInt(999999));
}

public void sendVerificationCode(String email) {
String code = generateVerificationCode();
emailService.sendEmail(email, "Verification Code", "Please use the following code to complete your login: " + code);
}

public boolean verifyCode(String userEmail, String userEnteredCode, String sentCode) {
return sentCode.equals(userEnteredCode);
}
}

This setup allows you to integrate email-based 2FA into your Spring Boot application efficiently, utilizing Spring’s strong email support to improve security through a secondary verification process.

Conclusion

Implementing Two-Factor Authentication (2FA) in Spring Boot significantly increases the security of applications by adding a crucial layer of protection against unauthorized access. By integrating SMS and email verification systems, developers can provide a strong security mechanism that complements traditional password-based authentication. Whether through SMS codes sent via Twilio or email verification handled by JavaMail, each method provides reliable ways to verify user identities and secure user interactions within applications.

While incorporating 2FA can introduce additional complexity and potential user inconvenience, the security benefits it brings are invaluable, especially in protecting sensitive data and complying with regulatory requirements. With the steps outlined in this article, developers can effectively implement 2FA in their Spring Boot applications, making sure both security and compliance are upheld to the highest standards.

Thank you for reading! If you find this article helpful, please consider highlighting, clapping, responding or connecting with me on Twitter/X as it’s very appreciated and helps keeps content like this free!

Spring Boot icon by Icons8

--

--

Alexander Obregon

Software Engineer, fervent coder & writer. Devoted to learning & assisting others. Connect on LinkedIn: https://www.linkedin.com/in/alexander-obregon-97849b229/