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')
我正在尝试为 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')