Multi-Factor Authentication (MFA)

About

Multi-Factor Authentication (MFA) is an authentication mechanism that requires users to provide two or more verification factors to gain access to an application or system. It enhances security by reducing the risk of unauthorized access even if one factor (like a password) is compromised.

MFA is widely used in modern security systems, including banking, enterprise applications, and cloud services.

How MFA Works (Step-by-Step Flow)

  1. User Enters Credentials

    • The user provides a username and password (something they know).

  2. First-Factor Authentication

    • The system verifies the password and checks if MFA is enabled for the user.

  3. Second-Factor Authentication Prompt

    • If MFA is enabled, the system requests a second authentication factor (e.g., OTP, biometric scan).

  4. User Provides Second Factor

    • The user enters an OTP (One-Time Password) sent via SMS, email, or authenticator app.

    • Alternatively, the user may perform biometric authentication (fingerprint, facial recognition).

  5. Authentication Verification

    • The system verifies the second factor.

    • If valid, access is granted; otherwise, the authentication fails.

Types of Authentication Factors in MFA

MFA requires at least two different types of authentication factors:

Factor Type

Description

Examples

Something You Know

A secret only the user knows.

Passwords, PINs, Security Questions

Something You Have

A physical object the user possesses.

Mobile phone, Smart Card, Security Token

Something You Are

Biometric characteristics.

Fingerprint, Face ID, Retina Scan

Somewhere You Are

Location-based authentication.

IP address, GPS location

Something You Do

Behavioral patterns.

Typing speed, Mouse movements

MFA Methods & Examples

MFA Method

Description

Example Services

SMS/Email OTP

A one-time password is sent via SMS or email.

Google, Microsoft, Banks

Authenticator App (TOTP)

Uses a time-based one-time password (TOTP) generated by an app.

Google Authenticator, Authy

Hardware Token (HOTP)

A physical device generates a one-time password.

YubiKey, RSA SecurID

Biometric Authentication

Uses fingerprint, facial recognition, or retina scan.

Apple Face ID, Windows Hello

Push Notification

Sends a push notification to a trusted device for approval.

Microsoft Authenticator, Duo Security

Security Questions

The user answers pre-configured questions.

Online Banking

MFA Workflow with Spring Security

1. Dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>com.github.bastiaanjansen</groupId>
    <artifactId>otp-java</artifactId>
    <version>2.0.0</version>
</dependency>

2. Generate TOTP Secret Key

Users must register their device by scanning a QR code linked to a TOTP secret key.

import dev.samstevens.totp.secret.DefaultSecretGenerator;
import dev.samstevens.totp.secret.SecretGenerator;

public class MFAService {
    public String generateSecretKey() {
        SecretGenerator generator = new DefaultSecretGenerator();
        return generator.generate();
    }
}

3. Verify OTP During Login

After password authentication, verify the TOTP code:

import dev.samstevens.totp.code.CodeVerifier;
import dev.samstevens.totp.code.DefaultCodeVerifier;
import dev.samstevens.totp.time.SystemTimeProvider;

public class MFAService {
    private final CodeVerifier verifier = new DefaultCodeVerifier(new SystemTimeProvider());

    public boolean verifyCode(String secret, String otp) {
        return verifier.isValidCode(secret, otp);
    }
}

4. Integrate MFA with Spring Security

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/login").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(login -> login
                .loginPage("/login")
                .defaultSuccessUrl("/mfa", true) // Redirect to MFA verification page
            );

        return http.build();
    }
}

5. MFA Verification Endpoint

@RestController
@RequestMapping("/mfa")
public class MFAController {
    private final MFAService mfaService;

    @PostMapping("/verify")
    public ResponseEntity<String> verify(@RequestParam String secret, @RequestParam String otp) {
        if (mfaService.verifyCode(secret, otp)) {
            return ResponseEntity.ok("MFA Verified");
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid MFA Code");
    }
}

Last updated

Was this helpful?