Spring Security Login with Google Authenticator (Time-based One-time Password Algorithm, TOTP)
  • Java 56.2%
  • TypeScript 23.1%
  • HTML 13.4%
  • CSS 6.1%
  • JavaScript 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ralph Schaer ce2bf0dfe7 upgrade
2026-10-04 10:08:35 +02:00
client upgrade 2026-10-04 10:08:35 +02:00
server upgrade 2026-09-12 13:49:18 +02:00
.gitignore Refactor 2019-11-22 08:53:45 +01:00
LICENSE Create LICENSE 2020-06-24 15:05:41 +02:00
README.md Harden TOTP authentication and enrollment 2026-09-03 21:22:10 +02:00

Spring Security TOTP Demo

This project demonstrates form login with optional two-factor authentication using Spring Security, Angular, and time-based one-time passwords (TOTP).

Original blog post: https://blog.rasc.ch/2019/06/totp-spring-security.html

Project layout

  • server: Spring Boot 4 application with Spring Security, jOOQ, Flyway, H2, and Argon2 password hashing.
  • client: Angular 22 application using Angular template-driven forms and generated QR-code data URLs.

Requirements

  • Java 25
  • Node.js 24 or newer
  • npm

Run in development

Start the backend:

cd server
./mvnw spring-boot:run

Start the Angular dev server:

cd client
npm install
npm start

Open http://localhost:4200. The Angular dev server proxies API calls to the backend on http://localhost:8080.

Demo users

The Flyway migration creates three users:

Username Password TOTP
admin admin Enabled, QR code shown on the sign-in page
user user Enabled, QR code shown on the sign-in page
lazy lazy Disabled

Security notes

  • Passwords are stored with Argon2.
  • Signup passwords are checked against the bundled password policy.
  • Usernames are trimmed, normalized to lowercase for new accounts, and matched case-insensitively when signing in.
  • Session-backed form login uses Spring Security CSRF protection. The Angular client obtains an XSRF cookie from /csrf and sends the token on mutating requests.
  • The session ID is rotated after a successful password check, before either completing authentication or beginning TOTP verification.
  • New TOTP secrets contain 160 bits of entropy, and successfully used time intervals are recorded to prevent replaying the same code.
  • Pending TOTP enrollment is bound to the browser session. Refreshing the QR page restores it; submitting the same username and password can also resume an interrupted enrollment.
  • Malformed TOTP input is rejected by request validation instead of surfacing as a server error.
  • The H2 database is configured for local demo use in server/src/main/resources/application.properties.

Build and verify

Backend tests:

cd server
./mvnw test

Frontend checks:

cd client
npm ci
npm run lint
npm run build

Production package:

cd server
./mvnw -Pproduction package

The production Maven profile runs npm run build-prod in client and copies Angular output from client/dist/app/browser into the Spring Boot static resources.