25 KiB
Executable File
25 KiB
Executable File
🔐 Authentication Flow Diagram
📊 Complete Authentication Flow
┌─────────────────────────────────────────────────────────────────────────┐
│ СИСТЕМА АУТЕНТИФИКАЦИИ │
│ │
│ ┌───────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ Environment │ │ Guacamole │ │ Application │ │
│ │ Variables │───▶│ Database │───▶│ Runtime │ │
│ │ (.env) │ │ (PostgreSQL) │ │ (FastAPI) │ │
│ └───────────────┘ └──────────────┘ └────────────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SYSTEM_ADMIN_USERNAME / PASSWORD │ │
│ │ (От вас, НЕ захардкожены) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
🔄 Startup Sequence
1️⃣ API STARTUP
┌─────────────────────────────────────────────────────┐
│ docker compose up -d │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ GuacamoleAuthenticator.__init__() │
│ ├─ Read SYSTEM_ADMIN_USERNAME from env │
│ ├─ Read SYSTEM_ADMIN_PASSWORD from env │
│ └─ If missing → ValueError ❌ │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ wait_for_guacamole() │
│ └─ Wait for Guacamole API to be ready │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ cleanup_orphaned_guacamole_connections() │
│ ├─ Get system token (uses env credentials) │
│ ├─ List all Guacamole connections │
│ ├─ Check Redis for each connection │
│ └─ Delete orphaned connections │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ API Ready for User Requests │
└─────────────────────────────────────────────────────┘
👤 User Login Flow
1️⃣ USER LOGIN REQUEST
┌─────────────────────────────────────────────────────┐
│ POST /auth/login │
│ { │
│ "username": "alice", │
│ "password": "user_password" │
│ } │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ guacamole_authenticator.authenticate_user() │
│ ├─ Send to Guacamole: username="alice" │
│ ├─ Send to Guacamole: password="user_password" │
│ ├─ Get Guacamole token for alice │
│ └─ Get user role and permissions │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ create_jwt_for_user() │
│ ├─ Create JWT with username="alice" │
│ ├─ Store Guacamole token in Redis session │
│ └─ Return JWT to client │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ User Authenticated │
│ Client has JWT → Can make API requests │
└─────────────────────────────────────────────────────┘
ВАЖНО:
- ❌ НЕ используется
SYSTEM_ADMIN_USERNAME/PASSWORD - ✅ Используются credentials самого пользователя (alice)
🔌 User Creates Connection
2️⃣ CREATE CONNECTION REQUEST
┌─────────────────────────────────────────────────────┐
│ POST /connect │
│ Authorization: Bearer <JWT> │
│ { │
│ "hostname": "server01", │
│ "protocol": "rdp", │
│ "username": "remote_user", │
│ "password": "remote_password" │
│ } │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ JWT Middleware │
│ ├─ Extract session_id from JWT │
│ ├─ Get Guacamole token from Redis session │
│ ├─ Get user info (username="alice", role="USER") │
│ └─ Pass to endpoint handler │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ create_remote_connection() │
│ ├─ Use alice's Guacamole token │
│ ├─ Create connection in Guacamole │
│ ├─ Store connection info in Redis │
│ └─ Return connection URL │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ Connection Created │
│ Owner: alice (from JWT) │
│ Guacamole Token: alice's token (from Redis) │
└─────────────────────────────────────────────────────┘
ВАЖНО:
- ❌ НЕ используется
SYSTEM_ADMIN_USERNAME/PASSWORD - ✅ Используется Guacamole token самого пользователя (alice)
🗑️ User Deletes Connection
3️⃣ DELETE CONNECTION REQUEST
┌─────────────────────────────────────────────────────┐
│ DELETE /connections/{id} │
│ Authorization: Bearer <JWT> │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ delete_connection() │
│ ├─ Get connection from Redis │
│ ├─ Check ownership (connection.owner == alice) │
│ ├─ Use alice's Guacamole token from Redis │
│ └─ Delete from Guacamole │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ Connection Deleted │
│ Used: alice's token (NOT system admin) │
└─────────────────────────────────────────────────────┘
ВАЖНО:
- ❌ НЕ используется
SYSTEM_ADMIN_USERNAME/PASSWORD - ✅ Используется Guacamole token владельца подключения
🧹 Background Cleanup (System)
4️⃣ CLEANUP EXPIRED CONNECTIONS
┌─────────────────────────────────────────────────────┐
│ Background Task (every 60 seconds) │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ cleanup_expired_connections_once() │
│ ├─ Get all connections from Redis │
│ ├─ Find expired connections │
│ └─ For each expired connection: │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ delete_connection_with_user_token() │
│ ├─ Get user's token from Redis │
│ ├─ Delete from Guacamole using user's token │
│ └─ Delete from Redis │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ Expired Connections Cleaned │
│ Used: Each user's token (NOT system admin) │
└─────────────────────────────────────────────────────┘
ВАЖНО:
- ✅ Использует токен каждого пользователя (из Redis)
- ❌ НЕ используется
SYSTEM_ADMIN_USERNAME/PASSWORD
🔧 Orphaned Cleanup (System)
5️⃣ CLEANUP ORPHANED CONNECTIONS (Startup Only)
┌─────────────────────────────────────────────────────┐
│ API Startup Event │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ cleanup_orphaned_guacamole_connections() │
│ ├─ Get system token using env credentials │
│ ├─ List ALL connections from Guacamole │
│ ├─ Check if each exists in Redis │
│ └─ Delete if NOT in Redis (orphaned) │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ get_system_token() │
│ ├─ Read SYSTEM_ADMIN_USERNAME from env │
│ ├─ Read SYSTEM_ADMIN_PASSWORD from env │
│ ├─ Authenticate to Guacamole │
│ └─ Return system token │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ delete_connection_with_system_token() │
│ └─ Delete orphaned connections │
└──────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ✅ Orphaned Connections Cleaned │
│ Used: SYSTEM_ADMIN credentials from env │
└─────────────────────────────────────────────────────┘
ВАЖНО:
- ✅ Это ЕДИНСТВЕННОЕ место где используется
SYSTEM_ADMIN - ✅ Работает ТОЛЬКО на старте API
- ✅ Credentials берутся из environment variables
🔐 Security Model
┌──────────────────────────────────────────────────────────────┐
│ БЕЗОПАСНОСТЬ CREDENTIALS │
└──────────────────────────────────────────────────────────────┘
┌─────────────────────┬──────────────┬──────────────────────┐
│ Credential Type │ Storage │ Usage │
├─────────────────────┼──────────────┼──────────────────────┤
│ SYSTEM_ADMIN │ .env file │ Startup cleanup │
│ (username/pass) │ ✅ Required │ (orphaned conns) │
├─────────────────────┼──────────────┼──────────────────────┤
│ User Guacamole │ Redis │ User operations │
│ token │ (ephemeral) │ (create/delete) │
├─────────────────────┼──────────────┼──────────────────────┤
│ User JWT │ Client │ API authorization │
│ token │ (ephemeral) │ (all endpoints) │
├─────────────────────┼──────────────┼──────────────────────┤
│ REDIS_PASSWORD │ .env file │ Redis connections │
│ │ ✅ Required │ (all components) │
├─────────────────────┼──────────────┼──────────────────────┤
│ POSTGRES_PASSWORD │ .env file │ DB connections │
│ │ ✅ Required │ (API + Guacamole) │
└─────────────────────┴──────────────┴──────────────────────┘
КРИТИЧНО:
✅ Все credentials из .env (НЕ захардкожены)
✅ User tokens ephemeral (хранятся в Redis с TTL)
✅ System token используется ТОЛЬКО для cleanup
✅ Нет fallback значений (API упадет если нет .env)
📊 Token Types Comparison
┌───────────────────────────────────────────────────────────────┐
│ ТРИ ТИПА ТОКЕНОВ │
└───────────────────────────────────────────────────────────────┘
1️⃣ JWT TOKEN (User API Token)
├─ Создается: При login пользователя
├─ Хранится: На клиенте (LocalStorage/Memory)
├─ Срок жизни: 60 минут (configurable)
├─ Используется для: Авторизации API запросов
└─ Содержит: username, role, session_id
2️⃣ GUACAMOLE TOKEN (User Session Token)
├─ Создается: При аутентификации в Guacamole
├─ Хранится: В Redis (по session_id из JWT)
├─ Срок жизни: Привязан к JWT сессии
├─ Используется для: Создания/удаления подключений
└─ Содержит: Guacamole authToken
3️⃣ SYSTEM TOKEN (Service Account Token)
├─ Создается: При startup API
├─ Хранится: В памяти GuacamoleAuthenticator
├─ Срок жизни: До рестарта API
├─ Используется для: Cleanup orphaned connections
└─ Содержит: Guacamole authToken (for system admin)
ВАЖНО:
✅ User никогда не видит SYSTEM TOKEN
✅ SYSTEM TOKEN используется ТОЛЬКО внутри API
✅ User operations используют User's Guacamole token
🎯 Key Takeaways
✅ Что МОЖНО менять:
SYSTEM_ADMIN_USERNAME=любое_имя # ✅ Любое имя
SYSTEM_ADMIN_PASSWORD=любой_пароль # ✅ Любой пароль
REDIS_PASSWORD=любой_пароль # ✅ Любой пароль
POSTGRES_PASSWORD=любой_пароль # ✅ Любой пароль
❌ Что НЕЛЬЗЯ:
SYSTEM_ADMIN_USERNAME= # ❌ Пустое значение
SYSTEM_ADMIN_PASSWORD=guacadmin # ❌ Дефолтное значение
REDIS_PASSWORD=redis_pass # ❌ Дефолтное значение
🔒 Где используются credentials:
| Credential | Used By | Used For | User Visible? |
|---|---|---|---|
SYSTEM_ADMIN_USERNAME/PASSWORD |
API (startup) | Orphaned cleanup | ❌ No |
| User's Guacamole token | API (runtime) | User operations | ❌ No (in Redis) |
| User's JWT | Client | API authorization | ✅ Yes (client-side) |
🎯 Безопасность:
- ✅ No hardcoded credentials - Все из .env
- ✅ No fallback values - API упадет без credentials
- ✅ System token isolated - Только для cleanup
- ✅ User tokens ephemeral - Срок жизни ограничен
- ✅ Role-based access - GUEST/USER/ADMIN permissions
📚 Related Documentation
ENDPOINT_AUDIT_REPORT.md- Detailed endpoint analysisCOMPATIBILITY_SUMMARY.md- Quick compatibility checkDEPLOYMENT_CHECKLIST.md- Deployment guide
Last Updated: 2025-10-29
Version: 1.0
Status: ✅ PRODUCTION READY