Django:自定义http标头身份验证

时间:2018-11-05 16:43:16

标签: python django authentication http-headers

我想为我的Django 1.11项目创建一个身份验证。如果请求包含标头<button>,则将对用户进行身份验证。 我正在使用通用视图,因此我使用X_USERNAME来控制访问。

我做了这个自定义身份验证类:

LoginRequiredMixin

我在设置中添加了它:

class CustomAuthentication:
    def authenticate(self, request):
        username = request.META.get('X_USERNAME')
        logging.warning(username)
        if not username:
            return None
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User(username=username)
            user.is_staff = False
            user.is_superuser = False
            if request.META.get('X_GROUPNAME') == 'administrator':
                user.is_staff = True
                user.is_superuser = True
            user.save()
        return user, None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

但是我无法使其工作。我被重定向到不存在的AUTHENTICATION_BACKENDS = ['path.to.file.CustomAuthentication']

谢谢!

编辑:

我也尝试创建一个子类,如下所述:Django RemoteUser documentation,因为它看起来像我想要实现的:

/accounts/login/?next=

它给了我相同的结果。

2 个答案:

答案 0 :(得分:0)

似乎authenticate()方法除了username参数外还必须指定passwordrequest参数。没有这些,Django将忽略后端(请参阅Django 2.0中的django.contrib.auth.__init__._authenticate_with_backend)。

由于您要通过标头提供用户名,因此您应该能够将这些参数默认设置为None

class CustomAuthentication:
    def authenticate(self, request, username=None, password=None):
        username = request.META.get('X_USERNAME')
        ...

或者,使用**credentials

def authenticate(self, request, **credentials):

答案 1 :(得分:0)

我终于设法找到了解决方法:

在authentication.py中:

from django.contrib.auth.middleware import RemoteUserMiddleware
from django.contrib.auth.middleware import RemoteUserBackend

class CustomMiddleware(RemoteUserMiddleware):
    header = 'HTTP_X_USERNAME'

第二次输入是强制性的,我不确定为什么。

在settings.py中:

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'app.authentication.CustomMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

AUTHENTICATION_BACKENDS = ['app.authentication.RemoteUserBackend']

最后在基于类的视图中,我使用LoginRequiredMixin