Skip to content

noel-mugisha/Spring-Auth-Service

Repository files navigation

Enterprise Spring Boot Authentication Service

Java Spring Boot PostgreSQL Flyway OpenAPI Google OAuth2 MFA Docker License: MIT

A comprehensive, production-ready authentication and user management service built with Spring Boot. This service provides robust security features including JWT-based authentication, refresh token rotation with HttpOnly cookies, OAuth2 social login (Google), email verification with OTP, password reset workflows, rate limiting, and database migrations. Designed for modern web applications requiring secure, scalable user authentication and authorization.


Highlights

  • Multi-Authentication Support: JWT-based authentication with OAuth2 social login (Google)
  • Multi-Factor Authentication: TOTP-based MFA (RFC 6238) compatible with Google Authenticator, Authy, and any standard authenticator app — with QR code enrollment, manual secret entry, and 10 single-use recovery codes
  • Secure Token Management: Refresh token rotation with one-time use and server-side revocation
  • Stateless APIs: Short-lived JWT access tokens (15 min) with HttpOnly, Secure cookies for refresh tokens (XSS-safe)
  • Hashed Token Storage: SHA-256 hashed refresh tokens stored securely in database
  • Rate Limiting: Bucket4j-based rate limiting on authentication endpoints (10 requests/min per IP)
  • Email Workflows: Event-driven email OTP registration and password reset with secure links
  • Role-Based Access Control: RBAC with method-level security using @PreAuthorize annotations
  • Database Migrations: Versioned schema management with Flyway
  • API Documentation: OpenAPI/Swagger UI integration out of the box
  • Social Authentication: Seamless OAuth2 integration allowing users to authenticate via Google accounts
  • Containerized by Default: Multi-stage Docker build and a ready-to-run Docker Compose stack — no local Java or PostgreSQL installation required to run the service

Architecture & Tech Stack

  • Language: Java 21
  • Framework: Spring Boot 3.5.x, Spring Web, Spring Security, Spring OAuth2 Client
  • Database: PostgreSQL 16
  • Migrations: Flyway 10.x
  • JWT: JJWT 0.12.x
  • Rate Limiting: Bucket4j
  • MFA / TOTP: dev.samstevens.totp 1.7.1 (RFC 6238)
  • Mapping/Boilerplate: MapStruct, Lombok
  • API Docs: springdoc-openapi
  • OAuth2: Spring Security OAuth2 Client for social authentication
  • Containerization: Docker (multi-stage build) + Docker Compose

API Surface

Authentication Endpoints

Public Endpoints

  • POST /api/v1/auth/send-otp — Send registration OTP to email
  • POST /api/v1/auth/verify-otp — Verify OTP; returns a temporary preAuth token
  • POST /api/v1/auth/register — Complete registration; requires Authorization: Bearer <preAuth-token>
  • POST /api/v1/auth/login — Traditional login; returns access token (JSON) and sets refresh token cookie
  • POST /api/v1/auth/mfa/verify — Submit a TOTP code or recovery code to complete an MFA-gated login
  • POST /api/v1/auth/refresh — Rotate refresh token and return new access token
  • POST /api/v1/auth/logout — Revoke refresh token and clear cookie
  • POST /api/v1/auth/forgot-password — Request password reset link
  • POST /api/v1/auth/reset-password — Reset password using token

OAuth2 Endpoints

  • GET /oauth2/authorization/google — Initiate Google OAuth2 login flow
  • GET /login/oauth2/code/google — OAuth2 callback endpoint (handled internally)

MFA Endpoints (require a valid access token)

  • POST /api/v1/mfa/setup — Generate a TOTP secret and return it as a raw key + QR code data URI
  • POST /api/v1/mfa/enable — Confirm enrollment with a live code from the authenticator app; returns 10 single-use recovery codes
  • POST /api/v1/mfa/disable — Disable MFA; requires the account password as confirmation

Protected Endpoints

  • GET /api/v1/users/me — Get current user profile
  • GET /api/v1/users — List all users (ADMIN role required)

API Documentation

Authentication Flows

Traditional Registration Flow

  1. Send OTP → Verify OTP → Receive preAuth token → Register with preAuth token → Receive access token + refresh cookie

OAuth2 Login Flow

  1. Redirect to /oauth2/authorization/google → User authenticates with Google → Redirect back with authorization code → Service processes user info → Set refresh token cookie → Redirect to frontend dashboard

MFA Login Flow

  1. POST /auth/login with email + password → receive { mfaRequired: true, mfaToken } instead of tokens
  2. Open authenticator app → get current 6-digit code (or use a recovery code if the phone is unavailable)
  3. POST /auth/mfa/verify with { mfaToken, code } → receive access token + refresh cookie as normal

Token Management

  • Access tokens are JWTs valid for 15 minutes
  • Refresh tokens are HttpOnly cookies valid for 7 days
  • Refresh endpoint rotates tokens for enhanced security

Multi-Factor Authentication

MFA adds a mandatory second step to login for accounts that have it enabled. It is fully opt-in — existing users without MFA enabled are unaffected.

How it works behind the scenes

When a user enables MFA, the server generates a secret key (stored in the database) and returns it as both a scannable QR code and a plain text string for manual entry. The user adds it to any standard TOTP app. From that point, every login requires the user to provide a 6-digit code that both the server and the app compute independently from the same secret and the current time — no network call to the app, no email, no SMS.

On login, after the password is verified, the server issues a short-lived MFA challenge token (5 minutes) instead of real session tokens. This challenge token can only be used at /auth/mfa/verify — it cannot authenticate any other endpoint. Real tokens are only issued once a valid TOTP code (or recovery code) is submitted against it.

Recovery codes

10 single-use backup codes are generated at enrollment. Each is SHA-256 hashed before storage and burned immediately on use. They are shown once and never again — the user is responsible for saving them securely. Any recovery code is accepted in place of a TOTP code at /auth/mfa/verify.

Enrollment flow

POST /api/v1/mfa/setup              → { secret, qrCodeImageDataUri }
  ↓ scan QR in authenticator app (or enter secret manually)
POST /api/v1/mfa/enable  { code }   → { recoveryCodes: [ ... ] }   ← save these

Setup

The application is fully containerized. You do not need Java, Maven, or a local PostgreSQL installation to run it — Docker handles the entire build and runtime, including the database.

Prerequisites

That's the only requirement. Everything else — the JDK, the build, and the database — runs inside containers.

1. Clone the repository

git clone https://github.com/noel-mugisha/Spring-Auth-Service.git
cd Spring-Auth-Service

2. Configure environment variables

Copy the example environment file and fill in your own values:

cp .env.example .env
# Database configuration
DB_URL=your_database_url_here
DB_USERNAME=your_database_username_here
DB_PASSWORD=your_database_password_here

# Mail configuration
MAIL_USERNAME=your_mail_username_here
MAIL_PASSWORD=your_mail_password_here

# JWT configuration (use a strong, base64-encoded 256-bit key)
JWT_SECRET_KEY=your_very_long_random_secret_key_base64_encoded

# Frontend Configuration
FRONTEND_URL=http://localhost:3000

# OAuth2 Configuration (Google)
GOOGLE_CLIENT_ID=your_google_client_id_here
GOOGLE_CLIENT_SECRET=your_google_client_secret_here

# MFA Configuration (optional — defaults to "SpringSecurityApp")
MFA_ISSUER_NAME=YourAppName

Note: When running via Docker Compose, DB_USERNAME and DB_PASSWORD also provision the bundled PostgreSQL container, and the app connects to it automatically over the internal Docker network — you don't need to point DB_URL at localhost or run Postgres yourself.

3. Run the application

docker compose up --build

This single command will:

  1. Build the application image (multi-stage Docker build — no local Java or Maven involved)
  2. Start a PostgreSQL 16 container with a persistent named volume
  3. Wait for the database to report healthy before starting the app
  4. Run Flyway migrations automatically on startup
  5. Expose the API on http://localhost:8080

To run it normally after building the image (this is after the first time):

docker compose up -d

4. Verify it's running

OAuth2 Setup

To enable Google OAuth2 authentication:

  1. Go to the Google Cloud Console
  2. Create a new project or select an existing one
  3. Enable the Google+ API
  4. Create OAuth 2.0 credentials (Client ID and Client Secret)
  5. Add your frontend URL to authorized redirect URIs
  6. Set the redirect URI to: {your-frontend-url}/login/oauth2/code/google
  7. Add the Client ID and Client Secret to your .env file

Security Model

Authentication Methods

  • JWT Authentication: Traditional email/password with OTP verification
  • OAuth2 Social Login: Google OAuth2 integration for seamless authentication
  • Hybrid Support: Users can link OAuth2 accounts to existing profiles or create new accounts via social login

Token Security

  • Access Tokens: JWT tokens in Authorization: Bearer <token> header, expires in 15 minutes
  • Refresh Tokens: HttpOnly, Secure cookies containing opaque UUIDs, stored as SHA-256 hashes in database
  • Token Rotation: Each /refresh call invalidates the previous refresh token and issues a new one
  • Cookie Security: Refresh tokens use HttpOnly, Secure, and appropriate SameSite attributes

Protection Mechanisms

  • Rate Limiting: 10 requests per minute per IP on authentication endpoints using Bucket4j
  • CORS Configuration: Configurable allowed origins via FRONTEND_URL environment variable
  • Pre-registration Security: Short-lived preAuth tokens (10 minutes) for secure registration completion
  • Open Redirect Protection: OAuth2 redirects validated against configured frontend URL

OAuth2 Security Features

  • State Parameter: Prevents CSRF attacks during OAuth2 flow
  • PKCE Support: Proof Key for Code Exchange for enhanced security
  • Secure Redirects: Only allows redirects to pre-configured frontend URLs
  • User Info Validation: Email verification required from OAuth2 providers

Admin Seeder

An optional admin seeder can bootstrap an admin account on startup (controlled via application.yaml):

  • Email: admin@company.com
  • Password: ChangeMe123! (change immediately or disable seeding)

Development & Testing

The instructions below are for contributors actively working on the codebase and require a local Java 21 + Maven 3.9+ toolchain — they are not needed to simply run the application (see Setup above for the Docker-based quick start).

  • Build: mvnw.cmd -q -DskipTests package (Windows) or ./mvnw -q -DskipTests package (Linux/Mac)
  • Tests: mvnw.cmd test or ./mvnw test — Docker is required, since the integration test suite uses Testcontainers to run against a real PostgreSQL instance

Contributing

We welcome contributions that improve stability, performance, security, or developer experience.

  • Getting started

    • Fork the repository and create a feature branch from main.
    • Use Java 21 and Maven 3.9+.
    • Run ./mvnw test to ensure the test suite passes before committing.
  • Development standards

    • Follow idiomatic Spring Boot patterns and keep services/interface contracts clean.
    • Keep security-sensitive changes small and well-documented in PR descriptions.
    • Prefer MapStruct for mappings and avoid manual boilerplate when possible.
  • Commits & PRs

    • Use conventional commit messages (e.g., feat:, fix:, docs:, refactor:, test:).
    • Open focused PRs with a clear description, screenshots/logs when relevant, and test coverage.
    • Link related issues and update README or OpenAPI docs when behavior changes.

By contributing, you agree that your contributions will be licensed under the MIT License.


Contact

For more information or inquiries, please reach out at: noelmugisha332@gmail.com


License

This project is licensed under the MIT License — see the LICENSE file for details.

About

A comprehensive security repo for modern Java backend applications. The only authentication & authorization service you’ll ever need.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors