Service Authentication
Autenticazione dei Servizi Distribuiti
DownToZero (DTZ) fornisce un sistema di autenticazione integrato per i tuoi servizi distribuiti, rendendo semplice costruire applicazioni sicure senza dover gestire un’infrastruttura di autenticazione propria.
Panoramica
Quando distribuisci un servizio su DTZ, la piattaforma fornisce automaticamente credenziali di autenticazione e informazioni contestuali tramite variabili d’ambiente. Il tuo servizio può utilizzare queste per:
- Autenticare le richieste verso altri servizi DTZ (chiamate API, object storage, ecc.)
- Verificare le richieste in ingresso degli utenti
- Accedere a risorse specifiche del contesto
- Implementare una comunicazione sicura tra servizi
Variabili d’Ambiente
DTZ inietta automaticamente le seguenti variabili d’ambiente nei container dei tuoi servizi:
| Variabile | Descrizione | Esempio |
|---|---|---|
DTZ_ACCESS_TOKEN |
Un token JWT per accedere ai servizi DTZ all’interno del tuo contesto. | eyJhbGciOiJSUzI1NiI... |
DTZ_CONTEXT_ID |
Il tuo identificatore di contesto DTZ. | context-3cd84429-64a4-4226-b868-c83feeff0f46 |
PORT |
La porta su cui il tuo servizio dovrebbe ascoltare. | 80 |
Autenticazione delle Richieste in Ingresso
Il tuo servizio distribuito può autenticare le richieste in ingresso con diversi metodi:
Autenticazione con API Key
Gli utenti possono autenticarsi con il tuo servizio usando le chiavi API DTZ, fornendo la chiave nell’header X-API-KEY.
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/api/endpoint
Autenticazione con Bearer Token
Fornisci un token JWT nell’header Authorization per autenticarti.
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/api/endpoint
Autenticazione Basic
Puoi anche passare le chiavi API usando l’autenticazione basic.
curl -u apikey:your-api-key https://yourservice.dtz.rocks/api/endpoint
Autenticazione Basata su Cookie
Per applicazioni web, il servizio Identity di DTZ può gestire l’autenticazione tramite cookie del browser.
Flusso OAuth
DTZ fornisce autenticazione OAuth automatica per le applicazioni web. Quando utenti non autenticati accedono al tuo servizio, vengono automaticamente reindirizzati alla pagina di login DTZ e poi riportati indietro dopo un login riuscito.
Utilizzo dell’Autenticazione DTZ nel Tuo Servizio
Effettuare Richieste Autenticate ai Servizi DTZ
Usa la variabile d’ambiente DTZ_ACCESS_TOKEN per effettuare chiamate autenticate ad altri servizi DTZ.
import os
import requests
# Ottieni il token di accesso DTZ dall'ambiente
token = os.environ.get('DTZ_ACCESS_TOKEN')
context_id = os.environ.get('DTZ_CONTEXT_ID')
# Effettua una richiesta autenticata all'API DTZ
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.dtz.rocks/v1/containers/services',
headers=headers
)
// Esempio 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'
}
});
# Esempio Bash
curl -H "Authorization: Bearer $DTZ_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
https://api.dtz.rocks/v1/containers/services
Verifica dell’Autenticazione in Ingresso
DTZ gestisce automaticamente l’autenticazione per le richieste in ingresso. Quando un utente fa una richiesta autenticata al tuo servizio, DTZ:
- Valida le credenziali di autenticazione.
- Converte le chiavi API in token JWT.
- Inoltra la richiesta con un header
Authorization: Bearer <token>.
Il tuo servizio riceve il token JWT e può estrarre le informazioni utente da esso.
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': 'Nessuna autenticazione fornita'}, 401
token = auth_header.split(' ')[1]
try:
# Il token è già verificato da DTZ, quindi puoi
# estrarre le claims senza verificare la firma.
payload = jwt.decode(token, options={"verify_signature": False})
user_id = payload.get('sub') # ID identità
context_id = payload.get('scope') # ID contesto
roles = payload.get('roles', []) # Ruoli utente
return {
'user_id': user_id,
'context_id': context_id,
'roles': roles,
'message': 'Accesso consentito'
}
except jwt.InvalidTokenError:
return {'error': 'Token non valido'}, 401
// Esempio 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: 'Nessuna autenticazione fornita' });
}
const token = authHeader.split(' ')[1];
try {
// Il token è già verificato da DTZ.
const payload = jwt.decode(token);
const userId = payload.sub; // ID identità
const contextId = payload.scope; // ID contesto
const roles = payload.roles || []; // Ruoli utente
res.json({
user_id: userId,
context_id: contextId,
roles: roles,
message: 'Accesso consentito'
});
} catch (error) {
res.status(401).json({ error: 'Token non valido' });
}
});
Struttura del Token JWT
I token JWT DTZ contengono le seguenti claims:
| Claim | Descrizione | Esempio |
|---|---|---|
iss |
Emittente (sempre “dtz.rocks”) | "dtz.rocks" |
sub |
Soggetto (ID identità utente) | "identity-abc123..." |
aud |
Destinatario (sempre “dtz.rocks”) | "dtz.rocks" |
scope |
ID contesto | "context-3cd84429..." |
roles |
Ruoli/permessi utente | ["https://dtz.rocks/context/admin/{context_id}"] |
contexts |
Contesti disponibili | ["context-3cd84429..."] |
exp |
Tempo di scadenza | 1640995200 |
iat |
Tempo di emissione | 1640908800 |
Controllo di Accesso Basato sui Ruoli
DTZ utilizza il controllo di accesso basato sui ruoli con identificatori di ruolo basati su URI. I pattern di ruolo comuni includono:
https://dtz.rocks/context/admin/{context_id}- Amministratore del contestohttps://dtz.rocks/containers/admin/{context_id}- Amministratore dei servizi containerhttps://dtz.rocks/objectstore/admin/{context_id}- Amministratore dell’object store
Puoi controllare i ruoli nel tuo servizio:
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
# Esempio:
if check_role(token, 'https://dtz.rocks/containers/admin/{context_id}'):
# L'utente ha permessi di amministratore dei container
pass
Best Practices
Sicurezza
- Valida sempre che i token JWT contengano le claims previste.
- Controlla i ruoli utente prima di concedere accesso a operazioni sensibili.
- Usa HTTPS per tutte le comunicazioni.
- Non registrare nei log token di autenticazione sensibili.
Gestione degli Errori
- Ritorna codici di stato HTTP appropriati (es. 401 per non autorizzato, 403 per proibito).
- Fornisci messaggi di errore significativi senza esporre informazioni sensibili.
Performance
- Cache i risultati della convalida dei token JWT quando possibile.
- Usa connection pooling per le chiamate API DTZ.
- Considera di implementare il rate limiting delle richieste.
Esempio: Servizio Completo Autenticato
Ecco un esempio completo di un servizio Python Flask con autenticazione 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):
"""Estrae le informazioni utente da un token 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 decoratore per richiedere l'autenticazione."""
def decorated(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return jsonify({'error': 'Autenticazione richiesta'}), 401
token = auth_header.split(' ')[1]
user = get_user_from_token(token)
if not user:
return jsonify({'error': 'Token non valido'}), 401
request.user = user
return f(*args, **kwargs)
decorated.__name__ = f.__name__
return decorated
@app.route('/health')
def health():
"""Un endpoint pubblico per il controllo dello stato."""
return jsonify({'status': 'healthy'})
@app.route('/profile')
@require_auth
def profile():
"""Un endpoint protetto che restituisce il profilo utente."""
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 riservato agli amministratori."""
required_role = f'https://dtz.rocks/context/admin/{DTZ_CONTEXT_ID}'
if required_role not in request.user['roles']:
return jsonify({'error': 'Accesso admin richiesto'}), 403
# Effettua una richiesta autenticata all'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)
Risoluzione dei Problemi
Problemi Comuni
- Token di autenticazione non trovato: Assicurati che il tuo servizio sia distribuito tramite il servizio container DTZ e che le variabili d’ambiente vengano lette correttamente.
- Errori token non valido: Controlla che estrai correttamente il token dall’header
Authorizatione che il parsing JWT funzioni. - Errori 403 Forbidden: Verifica che l’utente abbia i ruoli richiesti nel token JWT.
- Autenticazione servizio a servizio fallita: Assicurati di usare la variabile d’ambiente
DTZ_ACCESS_TOKENper le richieste in uscita.
Test dell’Autenticazione
Puoi testare l’autenticazione del tuo servizio usando curl:
# Test con una API key
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/profile
# Test con un token bearer
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/profile
# Test senza autenticazione (dovrebbe restituire 401)
curl https://yourservice.dtz.rocks/profile
Per maggiori dettagli sull’autenticazione DTZ, consulta la documentazione sull’autenticazione.