python / intermediate
Snippet
Django REST Framework Authentifizierungsklassen
Eigene Authentifizierungsklassen in Django REST Framework ermöglichen die Implementierung beliebiger Authentifizierungsmechanismen durch Erweiterung von BaseAuthentication. Dieses Beispiel implementiert HMAC-basierte Authentifizierung mit Zeitstempelvalidierung zur Verhinderung von Replay-Angriffen. Die authenticate()-Methode gibt entweder None (ermöglicht anderen Authentifikatoren) oder ein Tuple von (user, auth) zurück, das DRF verwendet um request.user zu setzen.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from rest_framework.authentication import BaseAuthenticationfrom rest_framework.exceptions import AuthenticationFailedfrom django.contrib.auth.models import Userimport hmacclass HMACAuthentication(BaseAuthentication):def authenticate(self, request):signature = request.META.get('HTTP_X_SIGNATURE')timestamp = request.META.get('HTTP_X_TIMESTAMP')if not signature or not timestamp:return Noneif not self.is_valid_timestamp(timestamp):raise AuthenticationFailed('Request expired')secret = self.get_user_secret(request)expected = hmac.new(secret.encode(),timestamp.encode(),hashlib.sha256).hexdigest()if not hmac.compare_digest(signature, expected):raise AuthenticationFailed('Invalid signature')user = self.get_user_from_request(request)return (user, None)def is_valid_timestamp(self, timestamp):import timereturn abs(time.time() - float(timestamp)) < 300def get_user_secret(self, request):api_key = request.META.get('HTTP_X_API_KEY', '')return f'secret_{api_key}'def get_user_from_request(self, request):return User.objects.get(username='api_user')
django
Erklärung
1
class HMACAuthentication(BaseAuthentication):
Erweitere BaseAuthentication um eine eigene Authentifizierungsmethode zu erstellen
2
if not signature or not timestamp: return None
Gib None zurück wenn Anmeldedaten fehlen, DRF versucht dann nächsten Authentifikator
3
raise AuthenticationFailed('Request expired')
Werfe Exception bei Validierungsfehler um Anfrage sofort abzulehnen
4
hmac.compare_digest(signature, expected)
Verwende konstantzeitigen Vergleich um Timing-Angriffe zu verhindern
5
return (user, None)
Gib Tuple zurück: Benutzerobjekt und Authentifizierungsinfo (hier None)