- Updated README and architecture documentation to reflect the new authentication flow, including user registration, login, token management, and logout processes. - Enhanced API documentation with detailed examples for each step of the authentication process, including curl commands and expected responses. - Improved clarity in the architecture diagrams, outlining the interaction between clients, API, application, and infrastructure layers. - Added sections on OAuth2 grant types and user management functionalities to provide comprehensive guidance for developers. - Streamlined Vietnamese documentation to ensure consistency with English updates and improve accessibility for users.
6.6 KiB
6.6 KiB
IAM Service .NET 10
Identity and Access Management Service built with .NET 10, ASP.NET Core Identity, and OpenIddict following DDD, CQRS, and Clean Architecture patterns.
Overview
This service provides OAuth2/OpenID Connect authentication and authorization:
- OAuth2/OIDC Server - OpenIddict for token management
- User Management - Registration, profile, soft-delete
- Role-Based Access Control - User roles and permissions
- Token Management - Access (15 min), Refresh (7 days) tokens
- CQRS Pattern - MediatR for Commands/Queries
- Clean Architecture - Domain, Infrastructure, API layers
Tech Stack
| Technology | Purpose |
|---|---|
| .NET 10 | Runtime |
| ASP.NET Core Identity | User/Role management |
| OpenIddict | OAuth2/OIDC server |
| EF Core + PostgreSQL | Data persistence |
| MediatR | CQRS pattern |
| FluentValidation | Request validation |
| Serilog | Structured logging |
Quick Start
1. Prerequisites
- .NET SDK 10.0.101+
- Docker (for PostgreSQL)
2. Configure Environment
cp .env.example .env
# Edit DATABASE_URL, JWT_SECRET in .env
3. Run with Docker
docker-compose up -d
Service available at: http://localhost:5001
4. Run Locally
dotnet restore
dotnet build
dotnet run --project src/IamService.API
API Endpoints
Authentication (/api/v1/auth)
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/api/v1/auth/register |
Register new user | ❌ |
POST |
/connect/token |
OAuth2 token endpoint | ❌ |
POST |
/api/v1/auth/change-password |
Change password | ✅ |
POST |
/api/v1/auth/logout |
Logout (revoke tokens) | ✅ |
User Management (/api/v1/users)
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/api/v1/users |
List users (paginated) | ✅ |
GET |
/api/v1/users/me |
Get current user | ✅ |
GET |
/api/v1/users/{id} |
Get user by ID | ✅ |
PUT |
/api/v1/users/{id} |
Update user | ✅ |
DELETE |
/api/v1/users/{id} |
Delete user (soft) | ✅ |
Health Endpoints
| Endpoint | Purpose |
|---|---|
/health |
Full health status |
/health/live |
Liveness probe |
/health/ready |
Readiness probe |
Authentication Flow
Step 1: Register a New User
curl -X POST http://localhost:5001/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "Password123!",
"firstName": "John",
"lastName": "Doe"
}'
Step 2: Login (Password Grant)
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=user@example.com" \
-d "password=Password123!" \
-d "scope=openid profile email offline_access"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "eyJhbGciOiJSUzI1NiIs...",
"scope": "openid profile email offline_access"
}
Step 3: Use Access Token
curl http://localhost:5001/api/v1/users/me \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."
Step 4: Refresh Token
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=eyJhbGciOiJSUzI1NiIs..."
Step 5: Logout
curl -X POST http://localhost:5001/api/v1/auth/logout \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Client Credentials (Service-to-Service)
For service-to-service authentication without user context:
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=goodgo-service" \
-d "client_secret=service-secret" \
-d "scope=api"
Supported OAuth2 Grant Types
| Grant Type | Use Case | Requires User |
|---|---|---|
password |
User login from trusted apps | Yes |
refresh_token |
Token renewal | No (uses refresh token) |
client_credentials |
Service-to-service | No |
Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
ASPNETCORE_ENVIRONMENT |
Environment | No (default: Development) |
DATABASE_URL |
PostgreSQL connection | Yes |
JWT_SECRET |
JWT signing secret (32+ chars) | Yes |
REDIS_URL |
Redis connection | No |
Token Lifetimes
| Token | Lifetime |
|---|---|
| Access Token | 15 minutes |
| Refresh Token | 7 days |
Password Policy
- Minimum 8 characters
- Requires: uppercase, lowercase, digit, special character
Project Structure
iam-service-net/
├── src/
│ ├── IamService.API/ # Controllers, CQRS
│ │ ├── Controllers/ # AuthController, UsersController
│ │ └── Application/ # Commands, Queries, Validations
│ ├── IamService.Domain/ # Domain entities
│ │ ├── AggregatesModel/ # UserAggregate, RoleAggregate
│ │ ├── Events/ # Domain events
│ │ └── Exceptions/ # Domain exceptions
│ └── IamService.Infrastructure/ # Data access
│ ├── IamServiceContext.cs # DbContext with Identity
│ └── Repositories/ # Repository implementations
├── tests/
│ ├── IamService.UnitTests/
│ └── IamService.FunctionalTests/
├── docs/
│ ├── en/ # English documentation
│ └── vi/ # Vietnamese documentation
├── Dockerfile
└── docker-compose.yml
Swagger UI
After running the service, access Swagger UI at:
- Local: http://localhost:5001/swagger
- Docker: http://localhost/api/v1/iam/swagger
Testing
# Run all tests
dotnet test
# Run with coverage
dotnet test /p:CollectCoverage=true
Docker
# Build image
docker build -t goodgo/iam-service:latest .
# Run container
docker run -p 5001:8080 --env-file .env goodgo/iam-service:latest
Resources
License
Proprietary - GoodGo Platform