- 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.
384 lines
8.6 KiB
Markdown
384 lines
8.6 KiB
Markdown
# Kiến Trúc IAM Service
|
|
|
|
> Tài liệu kiến trúc cho IAM Service (Quản lý Danh tính và Truy cập) xây dựng với .NET 10, OpenIddict, và Clean Architecture.
|
|
|
|
## Tổng Quan Kiến Trúc
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph "Clients"
|
|
WEB[Web App]
|
|
MOB[Mobile App]
|
|
SVC[Các Services khác]
|
|
end
|
|
|
|
subgraph "Lớp API"
|
|
AUTH[AuthController]
|
|
USR[UsersController]
|
|
TOK[Token Endpoint]
|
|
end
|
|
|
|
subgraph "Lớp Application - CQRS"
|
|
CMD[Commands]
|
|
QRY[Queries]
|
|
VAL[Validators]
|
|
BHV[Behaviors]
|
|
end
|
|
|
|
subgraph "Lớp Domain"
|
|
USER[User Aggregate]
|
|
ROLE[Role Aggregate]
|
|
EVT[Domain Events]
|
|
end
|
|
|
|
subgraph "Infrastructure"
|
|
CTX[Identity DbContext]
|
|
REPO[Repositories]
|
|
OIDDICT[OpenIddict]
|
|
end
|
|
|
|
subgraph "External"
|
|
DB[(PostgreSQL)]
|
|
REDIS[(Redis)]
|
|
end
|
|
|
|
WEB --> AUTH
|
|
MOB --> AUTH
|
|
SVC --> TOK
|
|
AUTH --> CMD
|
|
AUTH --> QRY
|
|
USR --> CMD
|
|
USR --> QRY
|
|
TOK --> OIDDICT
|
|
CMD --> VAL
|
|
CMD --> BHV
|
|
CMD --> USER
|
|
QRY --> REPO
|
|
USER --> EVT
|
|
REPO --> CTX
|
|
OIDDICT --> CTX
|
|
CTX --> DB
|
|
CTX --> REDIS
|
|
|
|
style AUTH fill:#4a90d9,stroke:#2d5986,color:#fff
|
|
style USER fill:#50c878,stroke:#2d8659,color:#fff
|
|
style DB fill:#ff6b6b,stroke:#c0392b,color:#fff
|
|
style OIDDICT fill:#9b59b6,stroke:#7d3c98,color:#fff
|
|
```
|
|
|
|
## Luồng Xác Thực OAuth2
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Client
|
|
participant AuthController
|
|
participant OpenIddict
|
|
participant UserManager
|
|
participant Database
|
|
|
|
Note over Client,Database: Password Grant Flow (Đăng nhập)
|
|
|
|
Client->>AuthController: POST /connect/token<br/>grant_type=password
|
|
AuthController->>OpenIddict: Validate Request
|
|
OpenIddict->>UserManager: FindByEmailAsync()
|
|
UserManager->>Database: Query User
|
|
Database-->>UserManager: User Data
|
|
UserManager->>UserManager: CheckPasswordAsync()
|
|
UserManager-->>OpenIddict: User Validated
|
|
OpenIddict->>OpenIddict: Tạo Tokens (JWT)
|
|
OpenIddict-->>AuthController: Token Response
|
|
AuthController-->>Client: access_token + refresh_token
|
|
|
|
Note over Client,Database: Sử dụng Access Token
|
|
|
|
Client->>AuthController: GET /api/v1/users/me<br/>Authorization: Bearer {token}
|
|
AuthController->>OpenIddict: Validate JWT
|
|
OpenIddict-->>AuthController: Claims Principal
|
|
AuthController-->>Client: User Data
|
|
```
|
|
|
|
## Các Loại Token và Grant Types
|
|
|
|
```mermaid
|
|
graph LR
|
|
subgraph "Grant Types"
|
|
PWD[Password Grant]
|
|
REF[Refresh Token]
|
|
CC[Client Credentials]
|
|
end
|
|
|
|
subgraph "Tokens"
|
|
AT[Access Token<br/>15 phút]
|
|
RT[Refresh Token<br/>7 ngày]
|
|
end
|
|
|
|
subgraph "Use Cases"
|
|
USER[Đăng nhập User]
|
|
RENEW[Làm mới Token]
|
|
S2S[Service-to-Service]
|
|
end
|
|
|
|
PWD --> AT
|
|
PWD --> RT
|
|
REF --> AT
|
|
CC --> AT
|
|
|
|
USER --> PWD
|
|
RENEW --> REF
|
|
S2S --> CC
|
|
|
|
style AT fill:#2ecc71,stroke:#27ae60,color:#fff
|
|
style RT fill:#f39c12,stroke:#d68910,color:#fff
|
|
style CC fill:#9b59b6,stroke:#7d3c98,color:#fff
|
|
```
|
|
|
|
## Domain Model
|
|
|
|
### User Aggregate
|
|
|
|
```mermaid
|
|
classDiagram
|
|
class ApplicationUser {
|
|
+Guid Id
|
|
+string Email
|
|
+string FirstName
|
|
+string LastName
|
|
+UserStatus Status
|
|
+DateTime CreatedAt
|
|
+DateTime? LastLoginAt
|
|
+UpdateProfile(firstName, lastName)
|
|
+Disable()
|
|
+RecordLogin()
|
|
}
|
|
|
|
class UserStatus {
|
|
<<enumeration>>
|
|
+Active
|
|
+Locked
|
|
+Disabled
|
|
+PendingVerification
|
|
}
|
|
|
|
class ApplicationRole {
|
|
+Guid Id
|
|
+string Name
|
|
+string Description
|
|
}
|
|
|
|
ApplicationUser --> UserStatus : có
|
|
ApplicationUser "nhiều" --> "nhiều" ApplicationRole : thuộc về
|
|
```
|
|
|
|
### Database Schema
|
|
|
|
```mermaid
|
|
erDiagram
|
|
AspNetUsers {
|
|
uuid Id PK
|
|
string Email UK
|
|
string PasswordHash
|
|
string FirstName
|
|
string LastName
|
|
int StatusId FK
|
|
datetime CreatedAt
|
|
datetime LastLoginAt
|
|
}
|
|
|
|
UserStatuses {
|
|
int Id PK
|
|
string Name
|
|
}
|
|
|
|
AspNetRoles {
|
|
uuid Id PK
|
|
string Name UK
|
|
string Description
|
|
}
|
|
|
|
AspNetUserRoles {
|
|
uuid UserId PK,FK
|
|
uuid RoleId PK,FK
|
|
}
|
|
|
|
OpenIddictTokens {
|
|
uuid Id PK
|
|
uuid ApplicationId FK
|
|
uuid AuthorizationId FK
|
|
string Type
|
|
string Status
|
|
datetime ExpirationDate
|
|
}
|
|
|
|
AspNetUsers ||--o{ UserStatuses : có
|
|
AspNetUsers ||--o{ AspNetUserRoles : có
|
|
AspNetRoles ||--o{ AspNetUserRoles : có
|
|
```
|
|
|
|
## CQRS Pipeline
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Controller
|
|
participant MediatR
|
|
participant LoggingBehavior
|
|
participant ValidatorBehavior
|
|
participant TransactionBehavior
|
|
participant CommandHandler
|
|
participant Repository
|
|
|
|
Controller->>MediatR: Send(Command)
|
|
MediatR->>LoggingBehavior: Handle
|
|
LoggingBehavior->>ValidatorBehavior: Next()
|
|
ValidatorBehavior->>TransactionBehavior: Next()
|
|
TransactionBehavior->>CommandHandler: Next()
|
|
CommandHandler->>Repository: Save
|
|
Repository-->>CommandHandler: Result
|
|
CommandHandler-->>Controller: Response
|
|
```
|
|
|
|
### Thứ Tự Pipeline Behaviors
|
|
|
|
| Thứ tự | Behavior | Mục đích |
|
|
|--------|----------|----------|
|
|
| 1 | LoggingBehavior | Ghi log request/response với timing |
|
|
| 2 | ValidatorBehavior | FluentValidation |
|
|
| 3 | TransactionBehavior | Bao database transaction |
|
|
|
|
## Kiến Trúc Bảo Mật
|
|
|
|
```mermaid
|
|
graph TD
|
|
subgraph "Authentication"
|
|
JWT[JWT Bearer Tokens]
|
|
RS256[RS256 Signing]
|
|
OIDC[OpenIddict Server]
|
|
end
|
|
|
|
subgraph "Authorization"
|
|
RBAC[Role-Based Access]
|
|
CLAIMS[Claims-Based]
|
|
POLICY[Policy Enforcement]
|
|
end
|
|
|
|
subgraph "Protection"
|
|
HASH[bcrypt Password Hash]
|
|
HTTPS[HTTPS/TLS]
|
|
CORS[CORS Policy]
|
|
end
|
|
|
|
JWT --> RS256
|
|
RS256 --> OIDC
|
|
RBAC --> CLAIMS
|
|
CLAIMS --> POLICY
|
|
|
|
style JWT fill:#3498db,stroke:#2980b9,color:#fff
|
|
style RBAC fill:#e74c3c,stroke:#c0392b,color:#fff
|
|
style HASH fill:#2ecc71,stroke:#27ae60,color:#fff
|
|
```
|
|
|
|
## Health Checks
|
|
|
|
```mermaid
|
|
graph TD
|
|
HC[Health Check Endpoints]
|
|
HC -->|/health/live| L[Liveness Probe]
|
|
HC -->|/health/ready| R[Readiness Probe]
|
|
HC -->|/health| F[Full Status]
|
|
|
|
R --> PG[(PostgreSQL Check)]
|
|
R --> RD[(Redis Check)]
|
|
|
|
style HC fill:#3498db,stroke:#2980b9,color:#fff
|
|
style L fill:#2ecc71,stroke:#27ae60,color:#fff
|
|
style R fill:#f39c12,stroke:#d68910,color:#fff
|
|
```
|
|
|
|
## Kiến Trúc Deployment
|
|
|
|
### Docker Compose (Local/Development)
|
|
|
|
```yaml
|
|
services:
|
|
iam-service:
|
|
build: .
|
|
ports: ["5001:8080"]
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
environment:
|
|
- DATABASE_URL=Host=postgres;...
|
|
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
```
|
|
|
|
### Kubernetes (Production)
|
|
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: iam-service
|
|
spec:
|
|
replicas: 3
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: iam-service
|
|
image: goodgo/iam-service:latest
|
|
ports:
|
|
- containerPort: 8080
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health/live
|
|
port: 8080
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health/ready
|
|
port: 8080
|
|
```
|
|
|
|
## Xử Lý Lỗi
|
|
|
|
### Phân Cấp Exception
|
|
|
|
```
|
|
Exception
|
|
└── DomainException
|
|
└── (Custom domain exceptions)
|
|
```
|
|
|
|
### Problem Details (RFC 7807)
|
|
|
|
Tất cả lỗi trả về định dạng Problem Details:
|
|
|
|
```json
|
|
{
|
|
"type": "https://tools.ietf.org/html/rfc7807",
|
|
"title": "Lỗi Validation",
|
|
"status": 400,
|
|
"detail": "Một hoặc nhiều lỗi validation đã xảy ra.",
|
|
"errors": {
|
|
"Email": ["Email là bắt buộc"]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Cân Nhắc Hiệu Năng
|
|
|
|
1. **Connection Pooling**: EF Core với Npgsql resilience
|
|
2. **Token Caching**: Redis cho token validation
|
|
3. **Async Operations**: Tất cả I/O operations đều async
|
|
4. **Database Indexes**: Cấu hình trong EntityConfigurations
|
|
|
|
## Tài Liệu Tham Khảo
|
|
|
|
- [OpenIddict Documentation](https://documentation.openiddict.com/)
|
|
- [ASP.NET Core Identity](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity)
|
|
- [OAuth2 Specification](https://oauth.net/2/)
|
|
- [eShopOnContainers](https://github.com/dotnet-architecture/eShopOnContainers)
|
|
- [CQRS Pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs)
|