386 lines
25 KiB
Markdown
Executable File
386 lines
25 KiB
Markdown
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
|
||
|
||
### ✅ **Что МОЖНО менять:**
|
||
```env
|
||
SYSTEM_ADMIN_USERNAME=любое_имя # ✅ Любое имя
|
||
SYSTEM_ADMIN_PASSWORD=любой_пароль # ✅ Любой пароль
|
||
REDIS_PASSWORD=любой_пароль # ✅ Любой пароль
|
||
POSTGRES_PASSWORD=любой_пароль # ✅ Любой пароль
|
||
```
|
||
|
||
### ❌ **Что НЕЛЬЗЯ:**
|
||
```env
|
||
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) |
|
||
|
||
### 🎯 **Безопасность:**
|
||
|
||
1. ✅ **No hardcoded credentials** - Все из .env
|
||
2. ✅ **No fallback values** - API упадет без credentials
|
||
3. ✅ **System token isolated** - Только для cleanup
|
||
4. ✅ **User tokens ephemeral** - Срок жизни ограничен
|
||
5. ✅ **Role-based access** - GUEST/USER/ADMIN permissions
|
||
|
||
---
|
||
|
||
## 📚 Related Documentation
|
||
|
||
- `ENDPOINT_AUDIT_REPORT.md` - Detailed endpoint analysis
|
||
- `COMPATIBILITY_SUMMARY.md` - Quick compatibility check
|
||
- `DEPLOYMENT_CHECKLIST.md` - Deployment guide
|
||
|
||
---
|
||
|
||
**Last Updated:** 2025-10-29
|
||
**Version:** 1.0
|
||
**Status:** ✅ PRODUCTION READY
|
||
|