Antwort

8

Wenn Sie eine grundlegende Authentifizierungsanforderung ausführen, fügen Sie die Anmeldeinformationen wirklich in den Header Authorization ein. Vor der Übertragung sind diese Anmeldeinformationen Base64-codiert, Sie müssen sie also beim Empfang dekodieren.

Der folgende Codeausschnitt geht davon aus, dass es nur einen gültigen Benutzernamen und Passwort ein:

import base64 

def my_view(request): 
    auth_header = request.META.get('HTTP_AUTHORIZATION', '') 
    token_type, _, credentials = auth_header.partition(' ') 

    expected = base64.b64encode(b'username:password').decode() 

    if token_type != 'Basic' or credentials != expected: 
     return HttpResponse(status=401) 

    # Your authenticated code here: 
    ... 

Wenn Sie auf den Benutzernamen und das Kennwort eines User Modell zu vergleichen, gehen Sie wie folgt statt:

def my_view(request): 
    auth_header = request.META.get('HTTP_AUTHORIZATION', '') 
    token_type, _, credentials = auth_header.partition(' ') 

    username, password = base64.b64decode(credentials).split(':') 
    try: 
     user = User.objects.get(username=username) 
    except User.DoesNotExist: 
     return HttpResponse(status=401) 

    password_valid = user.check_password(password) 

    if token_type != 'Basic' or not password_valid: 
     return HttpResponse(status=401) 

    # Your authenticated code here: 
    ... 

Bitte beachten Sie, dass diese letztere Version nicht extrem sicher ist. Auf den ersten Blick kann ich sehen, dass es zum Beispiel anfällig für timing attacks ist.

+0

Ja, das sollte funktionieren. Aber irgendwie denke ich, ich bin auf dem Holzweg, wenn ich es so löse. Ich habe persönliche Richtlinien (für mich). Eine lautet: "Schreiben Sie keinen Quellcode, um eine Sicherung zu implementieren" und der nächste "Schreiben Sie keinen Quellcode, um die Authentifizierung zu implementieren". Dies wurde zuvor von mehr talentierten Leuten gelöst und es gibt bereits Implementierungen, die seit einigen Monaten getestet wurden. Trotzdem vielen Dank für diesen Ausschnitt. Ich implementiere dies jedoch viel mehr Code. – guettli

0

Sie können einen benutzerdefinierten Dekorateur versuchen (wie der empfohlene Weg here und here zu sein scheint), anstatt neue Middleware hinzuzufügen:

my_app/decorators.py:

import base64 

from django.http import HttpResponse 
from django.contrib.auth import authenticate 
from django.conf import settings 


def basicauth(function): 
    def wrap(request, *args, **kwargs): 
     if 'HTTP_AUTHORIZATION' in request.META: 
      auth = request.META['HTTP_AUTHORIZATION'].split() 
      if len(auth) == 2: 
       if auth[0].lower() == "basic": 
        uname, passwd = base64.b64decode(auth[1]).split(':') 
        user = authenticate(username=uname, password=passwd) 
        if user is not None and user.is_active: 
         request.user = user 
         return view(request, *args, **kwargs) 

     response = HttpResponse() 
     response.status_code = 401 
     response['WWW-Authenticate'] = 'Basic realm="{}"'.format(
      settings.BASIC_AUTH_REALM 
     ) 
     return response 

Dann verwenden Sie dies, um Ihre Ansicht zu schmücken:

from my_app.decorators import basicauth 


@basicauth 
def my_view(request): 
    ...