Authentification des Services
Authentification des Services Déployés
DownToZero (DTZ) fournit une authentification intégrée pour vos services déployés, ce qui facilite la création d’applications sécurisées sans gérer votre propre infrastructure d’authentification.
Vue d’ensemble
Lorsque vous déployez un service sur DTZ, la plateforme fournit automatiquement des informations d’authentification et du contexte via des variables d’environnement. Votre service peut les utiliser pour :
- Authentifier les requêtes vers d’autres services DTZ (appels API, stockage d’objets, etc.)
- Vérifier les requêtes entrantes des utilisateurs
- Accéder à des ressources spécifiques au contexte
- Implémenter une communication sécurisée entre services
Variables d’environnement
DTZ injecte automatiquement les variables d’environnement suivantes dans vos conteneurs de service :
| Variable | Description | Exemple |
|---|---|---|
DTZ_ACCESS_TOKEN |
Un jeton JWT pour accéder aux services DTZ dans votre contexte. | eyJhbGciOiJSUzI1NiI... |
DTZ_CONTEXT_ID |
Votre identifiant de contexte DTZ. | context-3cd84429-64a4-4226-b868-c83feeff0f46 |
PORT |
Le port sur lequel votre service doit écouter. | 80 |
Authentification des requêtes entrantes
Votre service déployé peut authentifier les requêtes entrantes de plusieurs manières :
Authentification par clé API
Les utilisateurs peuvent s’authentifier auprès de votre service en utilisant les clés API DTZ en fournissant la clé dans l’en-tête X-API-KEY.
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/api/endpoint
Authentification par jeton Bearer
Fournissez un jeton JWT dans l’en-tête Authorization pour vous authentifier.
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/api/endpoint
Authentification basique
Vous pouvez également transmettre les clés API via l’authentification basique.
curl -u apikey:your-api-key https://yourservice.dtz.rocks/api/endpoint
Authentification par cookie
Pour les applications web, le service d’identité DTZ peut gérer l’authentification via les cookies du navigateur.
Flux OAuth
DTZ fournit une authentification OAuth automatique pour les applications web. Lorsque des utilisateurs non authentifiés accèdent à votre service, ils sont automatiquement redirigés vers la page de connexion DTZ puis renvoyés après une connexion réussie.
Utilisation de l’authentification DTZ dans votre service
Effectuer des requêtes authentifiées vers les services DTZ
Utilisez la variable d’environnement DTZ_ACCESS_TOKEN pour effectuer des appels authentifiés vers d’autres services DTZ.
import os
import requests
# Récupération du jeton d'accès DTZ depuis l'environnement
token = os.environ.get('DTZ_ACCESS_TOKEN')
context_id = os.environ.get('DTZ_CONTEXT_ID')
# Effectuer une requête authentifiée à l'API DTZ
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.dtz.rocks/v1/containers/services',
headers=headers
)
// Exemple Node.js
const token = process.env.DTZ_ACCESS_TOKEN;
const contextId = process.env.DTZ_CONTEXT_ID;
const response = await fetch('https://api.dtz.rocks/v1/containers/services', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
# Exemple Bash
curl -H "Authorization: Bearer $DTZ_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
https://api.dtz.rocks/v1/containers/services
Vérification de l’authentification entrante
DTZ gère automatiquement l’authentification des requêtes entrantes. Lorsqu’un utilisateur fait une requête authentifiée à votre service, DTZ :
- Valide les informations d’authentification.
- Convertit les clés API en jetons JWT.
- Transmet la requête avec un en-tête
Authorization: Bearer <token>.
Votre service reçoit le jeton JWT et peut en extraire les informations utilisateur.
import jwt
import os
from flask import Flask, request
app = Flask(__name__)
@app.route('/protected')
def protected_endpoint():
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return {'error': 'Aucune authentification fournie'}, 401
token = auth_header.split(' ')[1]
try:
# Le token est déjà vérifié par DTZ, vous pouvez donc
# extraire les claims sans vérification de signature.
payload = jwt.decode(token, options={"verify_signature": False})
user_id = payload.get('sub') # Identité
context_id = payload.get('scope') # ID du contexte
roles = payload.get('roles', []) # Rôles utilisateur
return {
'user_id': user_id,
'context_id': context_id,
'roles': roles,
'message': 'Accès autorisé'
}
except jwt.InvalidTokenError:
return {'error': 'Jeton invalide'}, 401
// Exemple Express.js
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
app.get('/protected', (req, res) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Aucune authentification fournie' });
}
const token = authHeader.split(' ')[1];
try {
// Le token est déjà vérifié par DTZ.
const payload = jwt.decode(token);
const userId = payload.sub; // Identité
const contextId = payload.scope; // ID du contexte
const roles = payload.roles || []; // Rôles utilisateur
res.json({
user_id: userId,
context_id: contextId,
roles: roles,
message: 'Accès autorisé'
});
} catch (error) {
res.status(401).json({ error: 'Jeton invalide' });
}
});
Structure du jeton JWT
Les jetons JWT DTZ contiennent les claims suivants :
| Claim | Description | Exemple |
|---|---|---|
iss |
Émetteur (toujours “dtz.rocks”) | "dtz.rocks" |
sub |
Sujet (identifiant de l’utilisateur) | "identity-abc123..." |
aud |
Audience (toujours “dtz.rocks”) | "dtz.rocks" |
scope |
ID du contexte | "context-3cd84429..." |
roles |
Rôles/permissions utilisateur | ["https://dtz.rocks/context/admin/{context_id}"] |
contexts |
Contextes disponibles | ["context-3cd84429..."] |
exp |
Date d’expiration | 1640995200 |
iat |
Date d’émission | 1640908800 |
Contrôle d’accès basé sur les rôles
DTZ utilise un contrôle d’accès basé sur les rôles avec des identifiants de rôle sous forme d’URI. Les rôles communs incluent :
https://dtz.rocks/context/admin/{context_id}- Administrateur du contextehttps://dtz.rocks/containers/admin/{context_id}- Administrateur du service conteneurhttps://dtz.rocks/objectstore/admin/{context_id}- Administrateur du stockage d’objets
Vous pouvez vérifier les rôles dans votre service :
def check_role(token, required_role_pattern):
payload = jwt.decode(token, options={"verify_signature": False})
roles = payload.get('roles', [])
context_id = payload.get('scope')
required_role = required_role_pattern.replace('{context_id}', context_id)
return required_role in roles
# Exemple :
if check_role(token, 'https://dtz.rocks/containers/admin/{context_id}'):
# L'utilisateur a les permissions d'admin conteneur
pass
Bonnes pratiques
Sécurité
- Validez toujours que les jetons JWT contiennent les claims attendus.
- Vérifiez les rôles utilisateur avant d’autoriser l’accès à des opérations sensibles.
- Utilisez HTTPS pour toutes les communications.
- Ne consignez pas les jetons d’authentification sensibles.
Gestion des erreurs
- Retournez les codes HTTP adéquats (ex. 401 pour non autorisé, 403 pour interdit).
- Fournissez des messages d’erreur pertinents sans exposer d’informations sensibles.
Performance
- Mettez en cache les résultats de validation des jetons JWT lorsque c’est possible.
- Utilisez le pool de connexions pour les appels à l’API DTZ.
- Envisagez la limitation du débit des requêtes.
Exemple : Service complet authentifié
Voici un exemple complet d’un service Python Flask avec authentification DTZ :
import os
import jwt
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
DTZ_TOKEN = os.environ.get('DTZ_ACCESS_TOKEN')
DTZ_CONTEXT_ID = os.environ.get('DTZ_CONTEXT_ID')
def get_user_from_token(token):
"""Extrait les informations utilisateur d'un jeton JWT DTZ."""
try:
payload = jwt.decode(token, options={"verify_signature": False})
return {
'user_id': payload.get('sub'),
'context_id': payload.get('scope'),
'roles': payload.get('roles', [])
}
except jwt.InvalidTokenError:
return None
def require_auth(f):
"""Un décorateur pour exiger l'authentification."""
def decorated(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return jsonify({'error': 'Authentification requise'}), 401
token = auth_header.split(' ')[1]
user = get_user_from_token(token)
if not user:
return jsonify({'error': 'Jeton invalide'}), 401
request.user = user
return f(*args, **kwargs)
decorated.__name__ = f.__name__
return decorated
@app.route('/health')
def health():
"""Un endpoint public de vérification de santé."""
return jsonify({'status': 'healthy'})
@app.route('/profile')
@require_auth
def profile():
"""Un endpoint protégé qui retourne le profil utilisateur."""
return jsonify({
'user_id': request.user['user_id'],
'context_id': request.user['context_id'],
'roles': request.user['roles']
})
@app.route('/admin/users')
@require_auth
def admin_users():
"""Un endpoint réservé aux administrateurs."""
required_role = f'https://dtz.rocks/context/admin/{DTZ_CONTEXT_ID}'
if required_role not in request.user['roles']:
return jsonify({'error': 'Accès admin requis'}), 403
# Effectuer une requête authentifiée à l'API DTZ
headers = {'Authorization': f'Bearer {DTZ_TOKEN}'}
response = requests.get(
'https://identity.dtz.rocks/api/2021-02-21/users',
headers=headers
)
return jsonify(response.json())
if __name__ == '__main__':
port = int(os.environ.get('PORT', 80))
app.run(host='0.0.0.0', port=port)
Dépannage
Problèmes courants
- Jeton d’authentification non trouvé : Assurez-vous que votre service est déployé via le service containers de DTZ et que les variables d’environnement sont bien lues.
- Erreurs de jeton invalide : Vérifiez que vous extrayez correctement le jeton depuis l’en-tête
Authorizationet que l’analyse JWT fonctionne. - Erreurs 403 Forbidden : Vérifiez que l’utilisateur possède les rôles requis dans son jeton JWT.
- Échec de l’authentification service-à-service : Assurez-vous d’utiliser la variable d’environnement
DTZ_ACCESS_TOKENpour les requêtes sortantes.
Tester l’authentification
Vous pouvez tester l’authentification de votre service avec curl :
# Test avec une clé API
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/profile
# Test avec un jeton bearer
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/profile
# Test non authentifié (devrait retourner 401)
curl https://yourservice.dtz.rocks/profile
Pour plus d’informations détaillées sur l’authentification DTZ, consultez la documentation Authentication.