A RESTful user management service built with Spring Boot and deployed on Azure Kubernetes Service. This service handles user authentication, profile management, and integrates with external authentication providers through an API Gateway.
- 👤 User Management (CRUD operations)
- 🔐 OAuth2 Provider Support (Google)
- 🐘 Azure PostgreSQL Database
- 🚀 Kubernetes Deployment
- 🔑 Role-based Access Control
- 📧 Email Verification Workflow
- 🎯 Event-Driven Architecture (Kafka/Azure Event Hubs)
- 🛡️ Spring Security Integration
- Java 11+
- Maven 3.6+
- Docker
- kubectl
- Azure CLI (for deployment)
The service requires the following environment variables (managed via Kubernetes Secrets):
# Database Configuration (Azure PostgreSQL)
DATABASE_URL=jdbc:postgresql://your-server.postgres.database.azure.com:5432/user_db?sslmode=require
DATABASE_USERNAME=your-username
DATABASE_PASSWORD=your-password
# Encryption Key (for AES-256)
ENCRYPTION_KEY=your-base64-encoded-key
# Azure Event Hubs Configuration
AZURE_EVENTHUBS_CONNECTION_STRING=your-connection-stringNote: OAuth2 authentication is handled by the API Gateway, not directly by this service.
# Clone repository
git clone <your-repo-url>
cd user-service
# Install dependencies
mvn clean install
# Run PostgreSQL with Docker Compose
docker-compose up -d postgres
# Run application
mvn spring-boot:runGET /api/users/health- Service health statusPOST /api/users- Create new user (Registration)POST /api/users/authenticate- Authenticate user credentials (Login)POST /api/users/oauth2- Create/update OAuth2 user (called by Gateway after OAuth2 flow)PUT /api/users/verify-email- Mark user's email as verified (called by Gateway after KeyCloak verification)
GET /api/users- List all users with paginationGET /api/users/{id}- Get user by IDGET /api/users/email/{email}- Get user by emailPUT /api/users/{id}- Update user profileDELETE /api/users/{id}- Delete user account
PUT /api/users/{id}/suspend- Suspend a user accountPUT /api/users/{id}/activate- Activate a suspended user accountPOST /api/users/test-event- Test event publishing (for debugging)
POST /api/users/oauth2
Content-Type: application/json
{
"email": "user@gmail.com",
"name": "User Name",
"provider": "GOOGLE"
}Response: User profile data Note: Called by Gateway after successful OAuth2 authentication. Creates new user or logs in existing user.
PUT /api/users/verify-email
Content-Type: application/json
{
"email": "user@example.com"
}Response:
{
"message": "Email verified successfully",
"email": "user@example.com"
}Note: Called by Gateway after KeyCloak email verification success.
GET http://user-service.user-service:80/api/healthResponse:
{
"status": "OK",
"service": "User Service"
}GET http://user-service.user-service:80/api/users?page=0&size=10Response:
[
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"profilePicture": null
}
]GET http://user-service.user-service:80/api/users/1Response:
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"role": "USER",
"provider": "LOCAL"
}GET http://user-service.user-service:80/api/users/email/user@example.comPOST http://user-service.user-service:80/api/users
Content-Type: application/json
{
"email": "newuser@example.com",
"name": "New User",
"password": "password123"
}Response:
{
"id": 2,
"email": "newuser@example.com",
"name": "New User",
"role": "USER",
"provider": "LOCAL",
"profilePicture": null
}PUT http://user-service.user-service:80/api/users/1
Content-Type: application/json
{
"name": "Updated Name",
"email": "updated@example.com"
}DELETE http://user-service.user-service:80/api/users/1Response:
{
"message": "User deleted successfully"
}POST http://user-service.user-service:80/api/users/authenticate
Content-Type: application/json
{
"email": "user@example.com",
"password": "password123"
}Response (Success):
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"role": "USER",
"provider": "LOCAL",
"profilePicture": null
}Response (Error):
{
"error": "Invalid credentials"
}POST http://user-service.user-service:80/api/users/oauth2
Content-Type: application/json
{
"email": "oauth.user@gmail.com",
"name": "OAuth User",
"provider": "GOOGLE"
}Response:
{
"id": 3,
"email": "oauth.user@gmail.com",
"name": "OAuth User",
"role": "USER",
"provider": "GOOGLE",
"profilePicture": null
}For API Gateway routing configuration:
# Example gateway route
routes:
- id: user-service
uri: http://user-service.user-service:80
predicates:
- Path=/api/users/**
filters:
- StripPrefix=0# Build application
mvn clean package
# Build Docker image
docker build -t user-service:latest .
# Run with Docker Compose
docker-compose up- Kubernetes cluster (AKS recommended)
- kubectl configured with proper permissions
- Docker image:
buildingbite/sangsangplus-user:latest - Azure PostgreSQL server already provisioned
- Azure Event Hubs connection string
Before deployment, create the following Kubernetes secrets:
# Azure PostgreSQL connection
kubectl create secret generic azure-postgres-secret \
--from-literal=DATABASE_URL="jdbc:postgresql://your-server.postgres.database.azure.com:5432/user_db?sslmode=require" \
--from-literal=DATABASE_USERNAME="your-username" \
--from-literal=DATABASE_PASSWORD="your-password" \
-n user-service
# Encryption key for AES-256
kubectl create secret generic encryption-secret \
--from-literal=encryption.key="your-base64-encoded-key" \
-n user-service-
Create Namespace
kubectl create namespace user-service
-
Setup Azure PostgreSQL Database
# Run the setup script to create database ./scripts/setup-azure-db.sh -
Deploy Secrets (if not created above)
kubectl apply -f k8s/azure-postgres-secret.yaml kubectl apply -f k8s/encryption-secret.yaml
-
Create ConfigMap
kubectl apply -f k8s/configmap.yaml
-
Deploy User Service
kubectl apply -f k8s-deployment.yaml
-
Create Service (ClusterIP for internal access)
kubectl apply -f k8s/service.yaml
# Deploy all resources at once
kubectl apply -f k8s/
# Check deployment status
kubectl get all -n user-service
# Check pod logs
kubectl logs -f deployment/user-service -n user-serviceThe User Service is deployed as ClusterIP and accessible within the cluster at:
http://user-service.user-service.svc.cluster.local:8081
For API Gateway integration:
# Gateway environment variable
- name: USER_SERVICE_URL
value: "http://user-service.user-service.svc.cluster.local:8081"When deploying in different clusters or environments:
-
Database Configuration
- Update
DATABASE_URLin secrets to point to your Azure PostgreSQL server - Ensure database
user_dbexists on your PostgreSQL server - Verify SSL connection requirements (
sslmode=require)
- Update
-
Network Connectivity
- Ensure Kubernetes cluster can reach Azure PostgreSQL (firewall rules)
- For private endpoints, configure VNet peering or private DNS zones
-
Event Hubs Configuration
- Update
AZURE_EVENTHUBS_CONNECTION_STRINGin ConfigMap - Ensure Event Hubs topic exists for user events
- Update
-
Image Registry Access
- Ensure cluster can pull from
buildingbite/sangsangplus-user:latest - Or push image to your own registry and update deployment
- Ensure cluster can pull from
-
Service Discovery
- Update Gateway service URL to match your namespace/cluster FQDN
- Consider using Ingress for external access if needed
# Check all resources in user-service namespace
kubectl get all -n user-service
# Check service endpoints
kubectl get endpoints -n user-service
# Test connectivity from another pod
kubectl run test-pod --image=curlimages/curl -it --rm -- /bin/sh
# Inside the pod:
curl http://user-service.user-service:80/api/healthFor production deployment:
- Use Kubernetes Secrets for sensitive data:
kubectl create secret generic user-service-secrets \
--from-literal=google-client-secret=your-secret \
--from-literal=jwt-secret=your-jwt-secret \
--from-literal=db-password=your-db-password \
-n user-service- Update ConfigMap to reference secrets
- Use proper SSL certificates
- Configure ingress with proper domains
- Set up monitoring and logging
The User Service implements endpoint-level security with the following rules:
Public Endpoints (No authentication required):
- Health check
- User registration (
POST /api/users) - User login (
POST /api/users/authenticate) - OAuth2 user creation (
POST /api/users/oauth2)
Authenticated Endpoints (Requires valid JWT token):
- User profile operations (GET, PUT, DELETE)
- User search operations
Admin-Only Endpoints (Requires ADMIN role):
- User suspension/activation
- Test event publishing
Architecture Note: This service operates in a microservices architecture where:
- API Gateway handles OAuth2 authentication, JWT validation, and request routing
- User Service manages user data and provides endpoints for Gateway integration
- KeyCloak (external) handles email verification workflow
- Authentication flow: Client → Gateway → User Service
client-secret.jsonfiles- Database passwords
- JWT secrets
- SSL private keys
- Environment files with secrets
All sensitive data should be:
- Added to
.gitignore - Stored in environment variables
- Managed via Kubernetes Secrets in production
- ✅ JWT Authentication with HttpOnly Cookies
- ✅ OAuth2 Integration (Google)
- ✅ CSRF Protection
- ✅ Role-based Access Control
- ✅ Environment-based Configuration
- ✅ Password Hashing (BCrypt)
-
Password Strength Validation
- Minimum 8 characters with complexity requirements
- Password history tracking
- Common password blacklist validation
-
Account Security
- Account lockout after failed login attempts
- Login attempt rate limiting
- Suspicious activity detection
-
Token Management
- Token blacklisting for logout
- Refresh token rotation
- Token revocation endpoint
-
API Rate Limiting
- Request rate limiting per IP/user
- Brute force attack prevention
- API quota management
-
Audit & Monitoring
- Authentication event logging
- Failed login attempt tracking
- User activity audit trail
-
Advanced Security
- Multi-factor authentication (MFA)
- Email verification workflow
- Password reset functionality
-
Session Management
- Concurrent session limiting
- Session timeout configuration
- Active session monitoring
-
Data Protection
- Data encryption at rest
- PII data masking in logs
- GDPR compliance features
Password Strength Validation
// Planned implementation location:
// src/main/java/com/example/userservice/validation/PasswordValidator.javaAccount Lockout
// Planned implementation location:
// src/main/java/com/example/userservice/security/AccountLockoutService.javaRate Limiting
// Planned implementation location:
// src/main/java/com/example/userservice/security/RateLimitingFilter.javaToken Blacklist
// Planned implementation location:
// src/main/java/com/example/userservice/security/TokenBlacklistService.java- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
This project is licensed under the MIT License.