Return Django REST Framework 中自定义身份验证的值

Return values of custom authentication in Django REST Framework

我正在尝试为 Django REST Framework 编写基本的自定义身份验证。我有以下身份验证后端:

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 header,authenticate() 函数 returns None。根据 DRF 文档:

To implement a custom authentication scheme, subclass BaseAuthentication and override the .authenticate(self, request) method. The method should return a two-tuple of (user, auth) if authentication succeeds, or None otherwise.

In some circumstances instead of returning None, you may want to raise an AuthenticationFailed exception from the .authenticate() method.

A None 表示身份验证失败,理想情况下应该是 return 401 或 403。但是,实际上情况似乎并非如此。没有 HTTP_X_FORWARDED_USER 的请求被简单地允许并且 200 被 returned:

$ 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 被视为成功的身份验证尝试?

问题是您混淆了身份验证和授权(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')