A demo full-stack application with two-factor authentication to protect endpoints using a Spring Boot + Spring Security backend and a React frontend.
- Backend: Spring Boot, Spring Security
- Frontend: React, TypeScript, Vite
This application uses Spring Security with a custom authorization manager to protect endpoints with two-factor authentication (2FA). The two factors of authentication are:
- Social Login (OAuth) with Google or Github
- Time-based One-time Password (TOTP) with the algorithm specified in RFC 6238, implemented using GoogleAuth.
-
Security Configuration (
SecurityConfig.java
)- The
SecurityConfig
class configures web security for specific HTTP requests. - It sets up a
SecurityFilterChain
that includes a custom CSRF token repository and a custom authorization manager (MfaAuthorizationManager
). - The
MfaAuthorizationManager
ensures that only users who have passed the 2FA check can access protected endpoints.
- The
-
MfaAuthorizationManager
- The
MfaAuthorizationManager
class checks if the user has been authenticated with MFA. - This manager ensures that users who have not completed the 2FA process are blocked from accessing protected resources.
- It bypasses the MFA check if the user does not have MFA enabled and enforces MFA by checking a session attribute
"isTwoFactorAuthenticated"
to determine if the user has completed the 2FA process.
- The
-
Credential Repository (
TotpCredentialRepository.java
)- This class implements the
ICredentialRepository
interface to store and retrieve TOTP (Time-based One-Time Password) credentials. - It manages user secret keys and is responsible for storing and retrieving these keys required for generating TOTP codes.
- This class implements the
- Java (21 or higher recommended)
- Node.js (22.11.0 or higher recommended)
- npm
- Google Authenticator app for scanning QR codes and generating TOTP codes.
-
Clone the repository:
git clone https://github.com/brandonxu360/two-factor-auth-demo.git cd two-factor-auth-demo
-
Navigate to the backend directory:
cd backend
-
Build the project:
./gradlew clean build
-
Run the Spring Boot application:
./gradlew bootRun
-
Navigate to the frontend directory:
cd frontend
-
Install dependencies:
npm install
-
Start the development server:
npm run dev