Возвращаемые значения пользовательской аутентификации в Django REST Framework - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь написать свою базовую пользовательскую аутентификацию для Django REST Framework.У меня есть следующий auth backend:

class JoeAuth(authentication.BaseAuthentication):
    def authenticate(self, request):
        username = request.META.get('HTTP_X_FORWARDED_USER')
        if not username:
            return

        try:
            user = User.objects.get(krb_name=username, active=True).name
        except User.DoesNotExist:
            raise PermissionDenied('Unauthorized user')

        return (user, None)

В сопровождении представления:

@api_view()
def hello(request):
    return Response(data='hello')

И, конечно, включено в settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'helloworld.auth.JoeAuth',
    )
}

Теперь,если запрос приходит и не указывает заголовок HTTP_X_FORWARDED_USER, функция authenticate() возвращает None.В соответствии с этим документ DRF:

Чтобы реализовать собственную схему аутентификации, создайте подкласс BaseAuthentication и переопределите метод .authenticate (self, request).Метод должен возвращать два кортежа (user, auth), если аутентификация прошла успешно, или None в противном случае.

В некоторых случаях вместо возврата None вы можете вызвать исключение AuthenticationFailed из .authenticate ()method.

A None означает, что аутентификация не пройдена и в идеале должна возвращать 401 или 403. Однако на практике это не так.Запрос без HTTP_X_FORWARDED_USER просто разрешается, и возвращается 200:

$ http http://127.0.0.1:8000/ HTTP_X_FORWARDED_USER:joe
HTTP/1.1 200 OK

"hello"

$ http http://127.0.0.1:8000/
HTTP/1.1 200 OK

"hello"

Не понимаю ли я документацию в том смысле, что None считается успешной попыткой аутентификации?

1 Ответ

0 голосов
/ 07 декабря 2018

Проблема в том, что вы путаете аутентификацию и авторизацию (разрешения в Django).Что делает аутентификация, так это идентифицирует пользователя, но никак не ограничивает пользователя - это работа авторизации (разрешения).Классы разрешений выполняют проверку прав пользователя на определенный ресурс.Из того, что я вижу, кажется, что у вас есть глобальный набор разрешений AllowAny по умолчанию, который разрешает любому доступ.Вам необходимо установить разрешение для ограничения конечной точки только для аутентифицированных пользователей.

В вашем случае вам необходимо добавить permission_classes к представлению или использовать глобальные разрешения в настройках DRF.Вы можете добавить классы разрешений в представление API на основе функций следующим образом:

from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import permission_classes, api_view


@api_view()
@permission_classes([IsAuthenticated])
def hello(request):
    return Response(data='hello')
...