proxy-oidcv2/ARCHITECTURE.md
2025-12-03 21:34:44 +01:00

375 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 📐 Architecture Secure Proxy
## Vue d'Ensemble
```
┌─────────────────────────────────────────────────────────────────┐
│ Internet / External Users │
└────────────────────────────┬────────────────────────────────────┘
│ https://secure.k2r.ovh
┌────────▼────────┐
│ Nginx/SSL │
│ (Reverse Proxy)│
└────────┬────────┘
│ http://localhost:3000
┌────────────────────▼──────────────────────┐
│ Secure Proxy (Node.js) │
│ ┌──────────────────────────────────────┐ │
│ │ Express Server │ │
│ │ - OIDC Authentication (Keycloak) │ │
│ │ - Session Management │ │
│ │ - Rate Limiting & Security │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Routes │ │
│ │ - /auth/* (Authentification) │ │
│ │ - /api/* (Admin API) │ │
│ │ - /admin (Panel Admin) │ │
│ │ - /* (Reverse Proxy) │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Middleware │ │
│ │ - OIDC Middleware │ │
│ │ - Proxy Middleware │ │
│ │ - Security Middleware │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Database (SQLite) │ │
│ │ - Services Management │ │
│ │ - Audit Logs │ │
│ │ - Access Logs │ │
│ └──────────────────────────────────────┘ │
└──────────────┬──────────────┬──────────────┘
│ │
┌──────────────▼──┐ ┌───────▼──────────────┐
│ Keycloak OIDC │ │ Internal Services │
│ (Authentication)│ │ - API Server │
│ │ │ - Grafana │
└─────────────────┘ │ - React App │
│ - Custom Services │
└─────────────────────┘
```
## Structure des Fichiers
```
openidv2/
├── 📁 src/ # Code source principal
│ ├── server.js # Serveur Express principal
│ ├── config.js # Configuration centralisée
│ ├── db.js # Gestion SQLite
│ │
│ ├── 📁 middleware/
│ │ ├── oidcMiddleware.js # Authentification OIDC/Keycloak
│ │ ├── security.js # Rate limit, CSRF, headers, logs
│ │ └── proxyMiddleware.js # Logique du reverse proxy
│ │
│ ├── 📁 routes/
│ │ ├── authRoutes.js # Routes d'authentification
│ │ ├── adminRoutes.js # API admin (CRUD services)
│ │ └── dashboardRoutes.js # Routes dashboard
│ │
│ ├── 📁 controllers/
│ │ ├── authController.js # Logique auth (login, callback)
│ │ ├── serviceController.js # CRUD des services
│ │ └── adminController.js # Stats et logs
│ │
│ ├── 📁 services/
│ │ └── serviceManager.js # Business logic (DB interactions)
│ │
│ └── 📁 utils/
│ └── logger.js # Logging centralisé
├── 📁 public/
│ └── admin.html # Interface admin (UI complète)
├── 📁 db/
│ └── services.db # Base de données SQLite
├── 📁 scripts/
│ ├── initDb.js # Initialiser la DB
│ └── seedDb.js # Charger données d'exemple
├── 📁 sessions/ # Sessions utilisateur (créé à runtime)
├── Configuration
│ ├── .env # Variables d'environnement
│ ├── .env.example # Modèle de configuration
│ ├── package.json # Dépendances Node.js
│ ├── docker-compose.yml # Stack Docker (dev)
│ ├── Dockerfile # Image Docker
│ └── nginx.example.conf # Config Nginx
└── Documentation
├── README.md # Documentation complète
├── INSTALLATION.md # Guide installation détaillé
├── QUICKSTART.md # Démarrage rapide
├── ARCHITECTURE.md # Ce fichier
└── test-api.sh # Tests API
```
## Flux de Requête
### 1⃣ Authentification OIDC
```
Utilisateur → http://localhost:3000/
Pas d'authentification ?
Redirect → /auth/login
Utilisateur clique "Login"
GET /auth/login
Redirect vers Keycloak Authorization Endpoint
Utilisateur s'authentifie sur Keycloak
Keycloak redirige vers /callback avec code
POST /auth/callback
Exchange code → Token
Récupérer userInfo
Créer session utilisateur
Redirect vers page demandée originalement
```
### 2⃣ Accès à un Service Protégé
```
Utilisateur (authentifié) → GET /myapp
Trouve service dans DB
Service nécessite auth ?
Utilisateur a session ?
OUI → Proxifier vers target
Utilisateur (anonyme) → GET /public
Service trouvé
Service nécessite auth ?
NON → Proxifier directement
```
### 3⃣ Management Admin
```
Admin → GET /admin
Vérifier : req.session.user.isAdmin ?
NON → 403 Forbidden
OUI → Servir interface admin.html
Admin clique "+ New Service"
POST /api/services (avec CSRF token)
Valider les données
Insérer dans DB
Log action d'audit
Retourner service créé
Réponse affichée dans l'UI
```
## Flux de Données
### Services Table (SQLite)
```sql
services {
id VARCHAR PRIMARY KEY -- UUID unique
name VARCHAR UNIQUE -- Nom du service
path VARCHAR UNIQUE -- Chemin public (/myapp)
target_url VARCHAR -- URL cible (http://localhost:8080)
require_auth BOOLEAN -- Authentification requise ?
description TEXT -- Description
enabled BOOLEAN -- Service actif ?
created_at DATETIME -- Date création
updated_at DATETIME -- Date modification
}
```
### Audit Logs Table
```sql
audit_logs {
id INTEGER PRIMARY KEY AUTO_INCREMENT
action VARCHAR -- SERVICE_CREATED, UPDATED, DELETED
user_id VARCHAR -- ID Keycloak de l'admin
service_id VARCHAR FK -- Service affecté
ip_address VARCHAR -- IP de l'admin
details JSON -- Détails (données modifiées)
timestamp DATETIME -- Quand
}
```
### Access Logs Table
```sql
access_logs {
id INTEGER PRIMARY KEY AUTO_INCREMENT
service_id VARCHAR FK -- Service accédé
user_id VARCHAR -- Utilisateur (si auth)
path VARCHAR -- Chemin complet
method VARCHAR -- GET, POST, etc.
status_code INTEGER -- Code réponse (200, 404, etc.)
response_time_ms INTEGER -- Temps réponse en ms
ip_address VARCHAR -- IP du client
timestamp DATETIME -- Quand
}
```
## Flux de Sécurité
### OIDC Flow (Authorization Code)
```
┌─────────────┐ ┌────────────────┐ ┌──────────────┐
│ Browser │ │ Secure Proxy │ │ Keycloak │
└──────┬──────┘ └────────┬───────┘ └──────┬───────┘
│ │ │
│──GET /auth/login───────►│ │
│ │──GET /auth/authorize│
│ │ (with state, nonce)─►│
│ │ │
│◄────────────────────────────────────────Redirect with code
│ (to /callback) │ │
│ │ │
│──GET /callback?code────►│ │
│ │──POST token───────►│
│ │◄──ID+Access Token──│
│ │ │
│◄────User data in session| │
│ │ │
```
### Rate Limiting & Security
```
Request → Check IP in rate limit store
Count exceeded ?
OUI → 429 Too Many Requests
NON → Continue
CSRF check (POST/PUT/DELETE)
Security headers added
Request logged
Response sent
```
## Performance & Scalabilité
### Optimisations Actuelles
- **Reverse Proxy** : http-proxy avec streaming
- **Rate Limiting** : En-mémoire (scalable avec Redis)
- **Logs** : SQLite (adapté pour small-medium)
- **Sessions** : File-based (pour dev)
### Pour la Production
```
┌─────────────┐
│ Nginx │ ← Load balancer + SSL termination
└─────┬───────┘
├─► [Proxy 1] ←► Redis (sessions)
├─► [Proxy 2] ←► +
└─► [Proxy 3] ←► PostgreSQL (logs & services)
```
## Sécurité en Couches
### Couche 1 : Transport
- SSL/TLS avec Nginx
- HSTS headers
### Couche 2 : Authentification
- OIDC avec Keycloak
- Sessions sécurisées (httpOnly, sameSite)
### Couche 3 : Autorisation
- Vérification admin pour /admin et /api
- Service auth check avant proxy
### Couche 4 : Validation
- CSRF tokens
- Input validation sur tous les endpoints
- SQL injections protection (parameterized queries)
### Couche 5 : Monitoring
- Audit logs de toutes les actions
- Access logs de tous les services
- Rate limiting anti-DDoS
## Extensibilité
### Ajouter un Nouveau Middleware
```javascript
// 1. Créer src/middleware/myMiddleware.js
export function myMiddleware(req, res, next) {
// Your logic
next();
}
// 2. Dans server.js
import { myMiddleware } from './middleware/myMiddleware.js';
app.use(myMiddleware);
```
### Ajouter une Nouvelle Route
```javascript
// 1. Créer route handler
export function myHandler(req, res) {
res.json({ message: 'Hello' });
}
// 2. Créer route file src/routes/myRoutes.js
const router = express.Router();
router.get('/myendpoint', myHandler);
// 3. Dans server.js
import myRoutes from './routes/myRoutes.js';
app.use('/api/my', myRoutes);
```
### Modifier l'UI Admin
- Éditer `public/admin.html`
- Ajouter sections, boutons, formulaires
- Le JavaScript charge automatiquement l'API
---
**Architecture modulaire, sécurisée et extensible**