Dienst-Authentifizierung
Authentifizierung bereitgestellter Dienste
DownToZero (DTZ) bietet eine integrierte Authentifizierung für Ihre bereitgestellten Dienste, sodass Sie sichere Anwendungen erstellen können, ohne eine eigene Authentifizierungsinfrastruktur verwalten zu müssen.
Übersicht
Wenn Sie einen Dienst bei DTZ bereitstellen, stellt die Plattform automatisch Authentifizierungsdaten und Kontextinformationen über Umgebungsvariablen bereit. Ihr Dienst kann diese verwenden, um:
- Anfragen an andere DTZ-Dienste zu authentifizieren (API-Aufrufe, Objektspeicher, etc.)
- Eingehende Benutzeranfragen zu verifizieren
- Kontext-spezifische Ressourcen zuzugreifen
- Sichere Kommunikation zwischen Diensten zu implementieren
Umgebungsvariablen
DTZ injiziert automatisch die folgenden Umgebungsvariablen in Ihre Service-Container:
| Variable | Beschreibung | Beispiel |
|---|---|---|
DTZ_ACCESS_TOKEN |
Ein JWT-Token zum Zugriff auf DTZ-Dienste innerhalb Ihres Kontexts. | eyJhbGciOiJSUzI1NiI... |
DTZ_CONTEXT_ID |
Ihre DTZ-Kontextkennzeichnung. | context-3cd84429-64a4-4226-b868-c83feeff0f46 |
PORT |
Der Port, auf dem Ihr Dienst lauschen sollte. | 80 |
Authentifizierung eingehender Anfragen
Ihr bereitgestellter Dienst kann eingehende Anfragen mit mehreren Methoden authentifizieren:
API-Schlüssel-Authentifizierung
Nutzer können sich mit DTZ-API-Schlüsseln bei Ihrem Dienst authentifizieren, indem sie den Schlüssel im Header X-API-KEY übergeben.
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/api/endpoint
Bearer-Token-Authentifizierung
Geben Sie ein JWT-Token im Authorization-Header an, um sich zu authentifizieren.
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/api/endpoint
Basic-Authentifizierung
Sie können API-Schlüssel auch über die Basis-Authentifizierung übergeben.
curl -u apikey:your-api-key https://yourservice.dtz.rocks/api/endpoint
Cookie-basierte Authentifizierung
Für Webanwendungen kann der DTZ Identity-Dienst die Authentifizierung über Browser-Cookies übernehmen.
OAuth-Flow
DTZ bietet automatische OAuth-Authentifizierung für Webanwendungen. Wenn nicht authentifizierte Benutzer auf Ihren Dienst zugreifen, werden sie automatisch zur DTZ-Anmeldeseite weitergeleitet und nach erfolgreicher Anmeldung zurückgeleitet.
Verwendung der DTZ-Authentifizierung in Ihrem Dienst
Authentifizierte Anfragen an DTZ-Dienste stellen
Verwenden Sie die Umgebungsvariable DTZ_ACCESS_TOKEN, um authentifizierte Aufrufe an andere DTZ-Dienste zu tätigen.
import os
import requests
# Get the DTZ access token from the environment
token = os.environ.get('DTZ_ACCESS_TOKEN')
context_id = os.environ.get('DTZ_CONTEXT_ID')
# Make an authenticated request to the DTZ API
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.dtz.rocks/v1/containers/services',
headers=headers
)
// Node.js example
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'
}
});
# Bash example
curl -H "Authorization: Bearer $DTZ_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
https://api.dtz.rocks/v1/containers/services
Eingehende Authentifizierung verifizieren
DTZ behandelt die Authentifizierung für eingehende Anfragen automatisch. Wenn ein Benutzer eine authentifizierte Anfrage an Ihren Dienst stellt, führt DTZ folgende Schritte durch:
- Validiert die Authentifizierungsdaten.
- Konvertiert API-Schlüssel in JWT-Tokens.
- Leitet die Anfrage mit einem
Authorization: Bearer <token>-Header weiter.
Ihr Dienst erhält das JWT-Token und kann Benutzerinformationen daraus extrahieren.
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': 'No authentication provided'}, 401
token = auth_header.split(' ')[1]
try:
# The token is already verified by DTZ, so you can
# extract claims without signature verification.
payload = jwt.decode(token, options={"verify_signature": False})
user_id = payload.get('sub') # Identity ID
context_id = payload.get('scope') # Context ID
roles = payload.get('roles', []) # User roles
return {
'user_id': user_id,
'context_id': context_id,
'roles': roles,
'message': 'Access granted'
}
except jwt.InvalidTokenError:
return {'error': 'Invalid token'}, 401
// Express.js example
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: 'No authentication provided' });
}
const token = authHeader.split(' ')[1];
try {
// The token is already verified by DTZ.
const payload = jwt.decode(token);
const userId = payload.sub; // Identity ID
const contextId = payload.scope; // Context ID
const roles = payload.roles || []; // User roles
res.json({
user_id: userId,
context_id: contextId,
roles: roles,
message: 'Access granted'
});
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
});
JWT-Token-Struktur
DTZ-JWT-Tokens enthalten die folgenden Claims:
| Claim | Beschreibung | Beispiel |
|---|---|---|
iss |
Aussteller (immer “dtz.rocks”) | "dtz.rocks" |
sub |
Subject (Benutzer-Identitäts-ID) | "identity-abc123..." |
aud |
Audience (immer “dtz.rocks”) | "dtz.rocks" |
scope |
Kontext-ID | "context-3cd84429..." |
roles |
Benutzerrollen/Berechtigungen | ["https://dtz.rocks/context/admin/{context_id}"] |
contexts |
Verfügbare Kontexte | ["context-3cd84429..."] |
exp |
Ablaufzeit | 1640995200 |
iat |
Ausstellungszeitpunkt | 1640908800 |
Rollenbasierte Zugriffskontrolle
DTZ verwendet rollenbasierte Zugriffskontrolle mit URI-basierten Rollenkennzeichnungen. Gängige Rollenmuster umfassen:
https://dtz.rocks/context/admin/{context_id}- Kontext-Administratorhttps://dtz.rocks/containers/admin/{context_id}- Administrator des Container-Diensteshttps://dtz.rocks/objectstore/admin/{context_id}- Administrator des Objektspeichers
Sie können in Ihrem Dienst auf Rollen prüfen:
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
# Example:
if check_role(token, 'https://dtz.rocks/containers/admin/{context_id}'):
# User has container admin permissions
pass
Bewährte Verfahren
Sicherheit
- Validieren Sie stets, dass JWT-Tokens die erwarteten Claims enthalten.
- Prüfen Sie Benutzerrollen, bevor Sie Zugriff auf sensible Operationen gewähren.
- Verwenden Sie HTTPS für alle Kommunikationswege.
- Protokollieren Sie keine sensiblen Authentifizierungs-Tokens.
Fehlerbehandlung
- Geben Sie passende HTTP-Statuscodes zurück (z. B. 401 für nicht autorisiert, 403 für verboten).
- Bieten Sie aussagekräftige Fehlermeldungen, ohne sensible Informationen preiszugeben.
Leistung
- Cachen Sie bei Möglichkeit die Ergebnisse der JWT-Token-Validierung.
- Verwenden Sie Connection-Pooling für DTZ-API-Aufrufe.
- Ziehen Sie die Implementierung von Ratenbegrenzung in Betracht.
Beispiel: Vollständig authentifizierter Dienst
Hier ein vollständiges Beispiel eines Python-Flask-Dienstes mit DTZ-Authentifizierung:
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):
"""Extracts user information from a DTZ JWT token."""
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):
"""A decorator to require authentication."""
def decorated(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return jsonify({'error': 'Authentication required'}), 401
token = auth_header.split(' ')[1]
user = get_user_from_token(token)
if not user:
return jsonify({'error': 'Invalid token'}), 401
request.user = user
return f(*args, **kwargs)
decorated.__name__ = f.__name__
return decorated
@app.route('/health')
def health():
"""A public health check endpoint."""
return jsonify({'status': 'healthy'})
@app.route('/profile')
@require_auth
def profile():
"""A protected endpoint that returns the user's profile."""
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():
"""An admin-only endpoint."""
required_role = f'https://dtz.rocks/context/admin/{DTZ_CONTEXT_ID}'
if required_role not in request.user['roles']:
return jsonify({'error': 'Admin access required'}), 403
# Make an authenticated request to the DTZ API
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)
Fehlerbehebung
Häufige Probleme
- Authentifizierungs-Token nicht gefunden: Stellen Sie sicher, dass Ihr Dienst über den DTZ-Containerservice bereitgestellt wird und die Umgebungsvariablen korrekt gelesen werden.
- Ungültige Token-Fehler: Prüfen Sie, ob Sie das Token korrekt aus dem
Authorization-Header extrahieren und ob das JWT-Parsing funktioniert. - 403 Forbidden-Fehler: Vergewissern Sie sich, dass der Benutzer die erforderlichen Rollen in seinem JWT-Token hat.
- Dienst-zu-Dienst-Authentifizierung schlägt fehl: Stellen Sie sicher, dass Sie für ausgehende Anfragen die Umgebungsvariable
DTZ_ACCESS_TOKENverwenden.
Authentifizierung testen
Sie können die Authentifizierung Ihres Dienstes mit curl testen:
# Test with an API key
curl -H "X-API-KEY: your-api-key" https://yourservice.dtz.rocks/profile
# Test with a bearer token
curl -H "Authorization: Bearer your-jwt-token" https://yourservice.dtz.rocks/profile
# Test unauthenticated (should return 401)
curl https://yourservice.dtz.rocks/profile
For more detailed information about DTZ authentication, see the Authentication documentation.