【问题标题】:Maintaining user session without having user saved in django authentication system维护用户会话而无需将用户保存在 django 身份验证系统中
【发布时间】:2020-01-30 08:46:12
【问题描述】:

我有一个小型 Django 应用程序,其中用户需要通过安装在 Apache 上的 Webgate 插件进行外部身份验证。 Webgate 将使用托管在 Intranet 上的其他企业身份验证系统来对进入我的 django 站点的用户进行身份验证。一旦企业身份验证系统对用户进行身份验证,它将使用标头 REMOTE-USER 将他们重定向到我们的站点。此标头将包含用户名。我只需要确保该标头中提到的用户能够访问该站点,即使它在我的站点上不存在,相信他已经通过身份验证。 为此,我正在使用

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.auth.middleware.RemoteUserMiddleware',
]
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackend',
)

这行得通。但它会在网站中创建用户。要求是用户不得存在于我们的数据库中。它们可以存在于内存中。他们需要开会 这在 Django 中甚至可能吗?如果是,我怎么能做到这一点? 我尝试将 AllowAllUsersRemoteUserBackend 子类化如下并覆盖身份验证方法以返回仅在内存中而不是在 DB 中的用户。

class AllowAllUsersRemoteUserBackendWithoutCreatingUnknownUsers(AllowAllUsersRemoteUserBackend):

    create_unknown_user = False

    def authenticate(self, request, remote_user):
        return User(username = remote_user)

AUTHENTICATION_BACKENDS = (
    'polls.middleware.authentication.AllowAllUsersRemoteUserBackendWithoutCreatingUnknownUsers',
)

但是我得到了一个例外

ValueError at /polls/
Cannot force an update in save() with no primary key.
Request Method: GET
Request URL:    http://localhost:8001/polls/
Django Version: 2.1.7
Exception Type: ValueError
Exception Value:    
Cannot force an update in save() with no primary key.
Exception Location: C:\Users\rizwan_shaikh\Envs\sessiontest\lib\site-packages\django\db\models\base.py in _save_table, line 803
Python Executable:  C:\Users\rizwan_shaikh\Envs\sessiontest\Scripts\python.exe
Python Version: 3.8.1
Python Path:    
['C:\\ApplicationCode\\Kenstar\\sessiontest\\djangosessiontestwithwsgi',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest\\Scripts\\python38.zip',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest\\DLLs',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest\\lib',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest\\Scripts',
 'c:\\softwares\\pythoninstallation\\Lib',
 'c:\\softwares\\pythoninstallation\\DLLs',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest',
 'C:\\Users\\rizwan_shaikh\\Envs\\sessiontest\\lib\\site-packages',
 '/app',
 '/usr/local/lib/python3.7/site-packages']
Server time:    Thu, 30 Jan 2020 08:37:34 +0000

现在我没有在 apache 上运行我的代码,而是在 django 开发服务器上运行。我正在通过另一个中间件手动添加包含用户名的标头。目标是让基本的东西正常工作,然后将代码部署到 apache。

【问题讨论】:

    标签: python django django-authentication


    【解决方案1】:

    我可以通过使用以下设置来解决这个问题。

    MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',  
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'module.CheckIDMHeaderMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    AUTH_USER_MODEL = 'auth.User'
    
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.SessionAuthentication',
        ),
        'DEFAULT_PERMISSION_CLASSES': [],
        'UNAUTHENTICATED_USER': None,
    }
    

    必须创建我自己的用户类。

    class User:
    username = ''
    user_permissions = []
    is_active = True
    
    def get_user_permissions(self):
        return self.user_permissions
    
    def __init__(self, username):
        self.username = username
        self.is_active = True
    

    在 CheckIDMHeaderMiddleware 的 call 方法中,我正在读取包含从 webgate 插件获得的用户名的标头。使用该用户名,我创建了一个用户对象并在它的会话中进行设置。

    def __call__(self, request):
        # some code skipped to keep the answer simple.
        ....
        username = request.META[header_name]
        user = User(username = username)
        request.user = user
        response = self.get_response(request)
        return response
        ....
        # some code skipped to keep the answer simple.
                
    

    ....

    【讨论】:

      猜你喜欢
      • 2016-05-29
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 1970-01-01
      • 2020-10-21
      • 2010-12-02
      • 2012-05-04
      相关资源
      最近更新 更多