Skip to content

tts-desktop2/spring-security

Repository files navigation

TTS Security API

Enterprise-grade Spring Boot REST API demonstrating JWT authentication with custom security filter chain, role-based authorization, and permission-based access control.

Table of Contents

Features

  • JWT-based stateless authentication (HS512 algorithm)
  • Two-level authentication system (Level 1: username/password, Level 2: MFA with encrypted token)
  • Six custom security filters executing in a defined order
  • Role-based access control (RBAC)
  • Permission-based authorization
  • Rate limiting by IP address
  • IP blacklisting
  • Country code validation
  • Custom JWT claims support
  • BCrypt password encryption
  • AES token encryption for MFA
  • Comprehensive error handling
  • MySQL database with JPA/Hibernate
  • RESTful API design

Technology Stack

  • Java: 8+
  • Spring Boot: 2.7.18
  • Spring Security: Custom filter chain
  • Spring Data JPA: Database operations
  • Hibernate: ORM
  • MySQL: 8.0+ database
  • JWT (JJWT): 0.11.5 with HS512 algorithm
  • BCrypt: Password encryption
  • Maven: Build tool
  • Lombok: Reducing boilerplate code

Architecture

Security Filter Chain

The application implements 6 custom security filters that execute in this exact order:

  1. IpShunFilter: Blocks blacklisted IP addresses
  2. TokenVerifierFilter: Validates JWT tokens and populates security context
  3. RateLimitFilter: Implements rate limiting per IP address
  4. AuthorizationFilter: Enforces role-based access control
  5. PermissionsFilter: Enforces permission-based access control
  6. CountryCodeValidatorFilter: Validates X-Country-Code header

Database Schema

  • users: User accounts with authentication details
  • roles: Role definitions (USER, ADMIN)
  • permissions: Permission definitions (READ_USER, WRITE_ADMIN, etc.)
  • auth_tokens: Issued JWT tokens for tracking
  • user_roles: Many-to-many relationship between users and roles
  • role_permissions: Many-to-many relationship between roles and permissions

Package Structure

com.tts.security
├── config              # Security and application configuration
├── controller          # REST API controllers
├── dto                 # Data Transfer Objects
├── entity              # JPA entities
├── exception           # Exception handlers
├── filter              # Custom security filters
├── repository          # JPA repositories
├── service             # Business logic
└── util                # Utility classes (JWT, Encryption)

Prerequisites

  • Java JDK 8 or higher
  • Maven 3.6+
  • MySQL 8.0+
  • Postman or curl (for testing)

Installation

1. Clone or Extract the Project

cd tts-security-api

2. Set Up MySQL Database

Create a new MySQL database:

CREATE DATABASE tts_security_db;

3. Configure Database Connection

Edit src/main/resources/application.yml or set environment variables:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/tts_security_db?useSSL=false&serverTimezone=UTC
    username: root
    password: your_password

Or use environment variables:

export DB_HOST=localhost
export DB_PORT=3306
export DB_NAME=tts_security_db
export DB_USER=root
export DB_PASSWORD=your_password

4. Build the Project

mvn clean package

Configuration

Key configuration properties in application.yml:

server:
  port: 8080

jwt:
  secret: MyVerySecretKeyForJWTTokenGenerationThatIsAtLeast256BitsLong12345
  expiration: 86400000  # 24 hours in milliseconds

security:
  blacklisted-ips: 192.168.1.100,10.0.0.50
  rate-limit:
    max-requests: 100
    window-seconds: 60
  allowed-countries: US,IN,GB,CA,AU

Running the Application

Using Maven

mvn spring-boot:run

Using Java

java -jar target/tts-security-api-1.0.0.jar

The application will start on http://localhost:8080

API Endpoints

Authentication Endpoints (Public)

1. Issue Token

POST /api/token/issue

Issues a JWT token after validating credentials.

Request Body:

{
  "userid": "john",
  "password": "password123",
  "encryptedToken": "optional-for-level-2",
  "customClaims": {
    "sessionType": "web",
    "deviceId": "abc123"
  }
}

Response (200 OK):

{
  "token": "eyJhbGciOiJIUzUxMiJ9...",
  "type": "Bearer",
  "userId": 1,
  "username": "john",
  "roles": ["USER"],
  "permissions": ["READ_USER"],
  "expiresIn": 86400000
}

2. Introspect Token

POST /api/token/introspect

Validates and introspects a JWT token.

Request Body:

{
  "token": "eyJhbGciOiJIUzUxMiJ9..."
}

Response (200 OK):

{
  "active": true,
  "username": "john",
  "userId": 1,
  "issuedAt": "2026-02-14T10:30:00",
  "expiresAt": "2026-02-15T10:30:00",
  "message": "Token is valid"
}

Protected Endpoints

All protected endpoints require:

  • Authorization: Bearer <token> header
  • X-Country-Code header (e.g., US, IN, GB, CA, AU)

3. Get User Info

GET /api/userinfo

Returns authenticated user information.

Required: USER role, READ_USER permission

Response (200 OK):

{
  "userId": 1,
  "username": "john",
  "roles": ["USER"],
  "permissions": ["READ_USER"]
}

4. Get All Users

GET /api/users

Returns all users in the system.

Required: USER role

Response (200 OK):

[
  {
    "id": 1,
    "username": "john",
    "authLevel": 1,
    "enabled": true,
    "roles": ["USER"]
  }
]

5. Get User by ID

GET /api/users/{id}

Returns a specific user by ID.

Required: USER role

Response (200 OK):

{
  "id": 1,
  "username": "john",
  "authLevel": 1,
  "enabled": true,
  "roles": ["USER"]
}

6. Create User

POST /api/users

Creates a new user.

Required: ADMIN role, WRITE_ADMIN permission

Request Body:

{
  "username": "newuser",
  "password": "password123",
  "authLevel": 1,
  "enabled": true,
  "roles": ["USER"],
  "customClaims": {
    "department": "Engineering"
  }
}

Response (201 Created):

{
  "id": 4,
  "username": "newuser",
  "authLevel": 1,
  "enabled": true,
  "roles": ["USER"]
}

7. Update User

PUT /api/users/{id}

Updates an existing user.

Required: ADMIN role, WRITE_ADMIN permission

Request Body:

{
  "username": "updateduser",
  "password": "newpassword",
  "authLevel": 1,
  "enabled": true,
  "roles": ["USER", "ADMIN"]
}

Response (200 OK):

{
  "id": 4,
  "username": "updateduser",
  "authLevel": 1,
  "enabled": true,
  "roles": ["USER", "ADMIN"]
}

8. Delete User

DELETE /api/users/{id}

Deletes a user.

Required: ADMIN role, WRITE_ADMIN permission

Response (204 No Content)

Authentication

Level 1 Authentication (Username + Password)

Standard authentication for regular users.

Example:

{
  "userid": "john",
  "password": "password123"
}

Level 2 Authentication (Username + Password + Encrypted Token)

Enhanced security with MFA for sensitive accounts.

Example:

{
  "userid": "jane",
  "password": "password123",
  "encryptedToken": "<encrypted-token-from-startup-logs>"
}

JWT Token Structure

The JWT token includes:

  • userId: User ID
  • username: Username
  • roles: Array of role names
  • permissions: Array of permission names
  • sub: Subject (username)
  • iat: Issued at timestamp
  • exp: Expiration timestamp
  • Custom claims (optional)

Security Filters

Filter Execution Order

  1. IpShunFilter: Blocks requests from blacklisted IPs (403 Forbidden)
  2. TokenVerifierFilter: Validates JWT and sets security context (401 Unauthorized)
  3. RateLimitFilter: Enforces rate limits (429 Too Many Requests)
  4. AuthorizationFilter: Checks role requirements (403 Forbidden)
  5. PermissionsFilter: Checks permission requirements (403 Forbidden)
  6. CountryCodeValidatorFilter: Validates country code (400/403)

Note: Public endpoints (/api/token/issue and /api/token/introspect) bypass all filters except IpShunFilter.

Sample Users

The application loads sample data on startup:

Username Password Auth Level Roles Permissions
john password123 1 USER READ_USER
admin admin123 1 USER, ADMIN All permissions
jane password123 2 (MFA) USER READ_USER

Note: Jane's encrypted token is printed in the console logs on application startup.

Testing

Using Postman

Import the provided TTS-Security-API.postman_collection.json file into Postman.

Using curl

1. Issue Token:

curl -X POST http://localhost:8080/api/token/issue \
  -H "Content-Type: application/json" \
  -d '{
    "userid": "john",
    "password": "password123"
  }'

2. Get User Info:

curl -X GET http://localhost:8080/api/userinfo \
  -H "Authorization: Bearer <your-token>" \
  -H "X-Country-Code: US"

3. Get All Users:

curl -X GET http://localhost:8080/api/users \
  -H "Authorization: Bearer <your-token>" \
  -H "X-Country-Code: US"

4. Create User (Admin only):

curl -X POST http://localhost:8080/api/users \
  -H "Authorization: Bearer <admin-token>" \
  -H "X-Country-Code: US" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "newuser",
    "password": "password123",
    "authLevel": 1,
    "enabled": true,
    "roles": ["USER"]
  }'

Error Responses

All errors follow this format:

{
  "status": 401,
  "error": "Unauthorized",
  "message": "Invalid or expired JWT token",
  "timestamp": "2026-02-14T10:30:00"
}

Common HTTP Status Codes

  • 200 OK: Successful GET/PUT request
  • 201 Created: Successful POST request
  • 204 No Content: Successful DELETE request
  • 400 Bad Request: Invalid input or missing required header
  • 401 Unauthorized: Authentication required or invalid token
  • 403 Forbidden: Insufficient permissions or blocked
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Internal Server Error: Server error

Custom Claims

You can add custom claims to JWT tokens in two ways:

  1. Persistent Claims: Store in user's customClaims field in the database
  2. Request-Time Claims: Pass in the customClaims field during token issuance

See CUSTOM-CLAIMS.md for detailed guide.

License

This project is provided as-is for educational and demonstration purposes.

Support

For issues or questions, please refer to the documentation files:

  • QUICKSTART.md - Quick setup guide
  • USER-MANAGEMENT-API.md - User management endpoints
  • CUSTOM-CLAIMS.md - Custom JWT claims guide
  • database-schema.sql - Database schema reference

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages