Files
pos-system/services/iam-service-net/docs/en/ARCHITECTURE.md
Ho Ngoc Hai 4ae24a7bc8 feat(docs): Revamp IAM service documentation and authentication flow
- 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.
2026-01-12 16:37:31 +07:00

8.4 KiB

IAM Service Architecture

Architecture documentation for IAM (Identity and Access Management) Service built with .NET 10, OpenIddict, and Clean Architecture.

Architecture Overview

graph TB
    subgraph "Clients"
        WEB[Web App]
        MOB[Mobile App]
        SVC[Other Services]
    end
    
    subgraph "API Layer"
        AUTH[AuthController]
        USR[UsersController]
        TOK[Token Endpoint]
    end
    
    subgraph "Application Layer - CQRS"
        CMD[Commands]
        QRY[Queries]
        VAL[Validators]
        BHV[Behaviors]
    end
    
    subgraph "Domain Layer"
        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

OAuth2 Authentication Flow

sequenceDiagram
    participant Client
    participant AuthController
    participant OpenIddict
    participant UserManager
    participant Database
    
    Note over Client,Database: Password Grant Flow (User Login)
    
    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: Generate Tokens (JWT)
    OpenIddict-->>AuthController: Token Response
    AuthController-->>Client: access_token + refresh_token
    
    Note over Client,Database: Using 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

Token Types and Flows

graph LR
    subgraph "Grant Types"
        PWD[Password Grant]
        REF[Refresh Token]
        CC[Client Credentials]
    end
    
    subgraph "Tokens"
        AT[Access Token<br/>15 min]
        RT[Refresh Token<br/>7 days]
    end
    
    subgraph "Use Cases"
        USER[User Login]
        RENEW[Token Renewal]
        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

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 : has
    ApplicationUser "many" --> "many" ApplicationRole : belongs to

Database Schema

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 : has
    AspNetUsers ||--o{ AspNetUserRoles : has
    AspNetRoles ||--o{ AspNetUserRoles : has

CQRS Pipeline

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

Pipeline Behaviors

Order Behavior Purpose
1 LoggingBehavior Log request/response with timing
2 ValidatorBehavior FluentValidation
3 TransactionBehavior Database transaction wrapper

Security Architecture

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

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

Deployment Architecture

Docker Compose (Local/Development)

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)

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

Error Handling

Exception Hierarchy

Exception
└── DomainException
    └── (Custom domain exceptions)

Problem Details (RFC 7807)

All errors return Problem Details format:

{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Validation Error",
  "status": 400,
  "detail": "One or more validation errors occurred.",
  "errors": {
    "Email": ["Email is required"]
  }
}

Performance Considerations

  1. Connection Pooling: EF Core with Npgsql resilience
  2. Token Caching: Redis for token validation
  3. Async Operations: All I/O operations are async
  4. Database Indexes: Configured in EntityConfigurations

References