mirror of
https://github.com/ralscha/springsecuritytotp.git
synced 2026-10-09 11:18:27 +02:00
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%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| client | ||
| server | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
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
/csrfand 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.