ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Django 如何用 REMOTE_USER 接入 IIS、CAS 等外部单点登录

Django 如何用 REMOTE_USER 接入 IIS、CAS 等外部单点登录 Django 如何用 REMOTE_USER 接入 IIS、CAS 等外部单点登录【免费下载链接】djangoThe Web framework for perfectionists with deadlines.项目地址: https://gitcode.com/GitHub_Trending/dj/django内网应用经常把认证工作交给前置的 Web 服务器或单点登录网关如 IIS Integrated Windows Authentication、Apache mod_authnz_ldap、CAS、WebAuth、mod_auth_sspi等Django 本身不处理密码只接收认证后的用户名。这类方案下服务器会把认证后的用户名放入REMOTE_USERWSGI 部署中它出现在request.META的REMOTE_USER键ASGI 部署中则通过 HTTP 头传递对应request.META的HTTP_REMOTE_USER键。Django 提供RemoteUserMiddleware或PersistentRemoteUserMiddleware与RemoteUserBackend来处理这个值实现自动登录。官方操作文档见 docs/howto/auth-remote-user.txt后端 API 说明见 docs/ref/contrib/auth.txt。基本配置两步改动都写在项目settings中。第一步添加中间件。把django.contrib.auth.middleware.RemoteUserMiddleware加入MIDDLEWARE且必须放在django.contrib.auth.middleware.AuthenticationMiddleware之后MIDDLEWARE [ ..., django.contrib.auth.middleware.AuthenticationMiddleware, django.contrib.auth.middleware.RemoteUserMiddleware, ..., ]这个顺序有硬性要求如果AuthenticationMiddleware没在前面即request上还没有user属性RemoteUserMiddleware会抛出ImproperlyConfigured提示在 MIDDLEWARE 中把AuthenticationMiddleware插到它前面。第二步替换认证后端。在AUTHENTICATION_BACKENDS中用RemoteUserBackend替换ModelBackendAUTHENTICATION_BACKENDS [ django.contrib.auth.backends.RemoteUserBackend, ]这样配置后RemoteUserMiddleware会从request.META[REMOTE_USER]ASGI 下为request.META[HTTP_REMOTE_USER]取出用户名通过RemoteUserBackend认证并自动登录该用户。RemoteUserBackend继承自ModelBackend所以权限检查逻辑has_perm、get_all_permissions等与默认后端一致。默认行为有两点要注意create_unknown_user默认为True数据库中不存在的用户名会被自动创建为User对象is_activeFalse的用户不允许认证。如需放行非激活用户改用django.contrib.auth.backends.AllowAllUsersRemoteUserBackend。保留 admin 登录通道的可选方案只配置RemoteUserBackend时默认ModelBackend被禁用意味着如果某次请求没有REMOTE_USER值用户无法登录——包括通过 Django admin 界面登录。如果还需要保留密码登录作为后备把两个后端都放进列表即可AUTHENTICATION_BACKENDS [ django.contrib.auth.backends.RemoteUserBackend, django.contrib.auth.backends.ModelBackend, ]文档明确说明当REMOTE_USER不存在时回退到ModelBackend可以解决无法登录 admin 的问题。另外要清楚边界contrib.admin的用户管理界面和createsuperuser命令操作的是数据库里存储的用户与AUTHENTICATION_BACKENDS无关它们不会和 remote user 流程联动。使用自定义 HTTP 头可选分支如果你的认证机制传递的不是REMOTE_USER而是自定义 HTTP 头可以子类化RemoteUserMiddleware并设置header属性为对应的request.META键。例如文档中的例子放在mysite/middleware.pyfrom django.contrib.auth.middleware import RemoteUserMiddleware class CustomHeaderRemoteUserMiddleware(RemoteUserMiddleware): header HTTP_AUTHUSER然后在MIDDLEWARE中用这个自定义中间件替换RemoteUserMiddleware。这里有一条必须遵守的安全约束文档以 warning 形式强调RemoteUserMiddleware绝不能部署在客户端可以自己提供该头的配置中。必须确保 Web 服务器或反向代理基于认证检查结果来设置或剥离该头绝不允许终端用户提交伪造的头值。由于X-Auth-User和X-Auth_User这类头在request.META中都会归一化为HTTP_X_AUTH_USER还要确认 Web 服务器不允许用下划线替代连字符来伪造头。两个环境的差异WSGI默认配置header REMOTE_USER下上述警告不适用因为request.META中不以HTTP_开头的键只能由 WSGI 服务器设置HTTP 请求头无法直接写入ASGI所有配置下该警告都适用因为 ASGI 没有等价于 WSGI environ 的可信值通道。ASGI 部署使用此中间件时必须配合文档所述的反向代理。只在登录页做外部认证PersistentRemoteUserMiddlewareRemoteUserMiddleware假设每个已认证请求都携带REMOTE_USER。这在 Basic HTTP Authhtpasswd之类下是合理的但对 NegotiateGSSAPI/Kerberos这类开销较大的认证方式前端服务器通常只对一两个登录 URL 启用认证登录成功后由应用自己维持会话。PersistentRemoteUserMiddleware正是为这种场景设计的它会保持认证会话有效直到用户显式登出即使请求中找不到request.META键也不会强制注销其实现上就是把force_logout_if_no_header设为False。它可以在上面的配置中作为RemoteUserMiddleware的直接替换使用中间件位置与后端配置不变。验证接入是否生效仓库自带的测试 tests/auth_tests/test_remote_user.py 展示了核对方式可作为验证思路向视图发起不带REMOTE_USER的请求确认response.context[user].is_anonymous为True且User.objects.count()不增加未提供用户名时不会创建用户带上REMOTE_USER头再次请求确认request.user已认证为对应用户且默认情况下新用户名会在数据库中被自动创建。测试中 WSGI 客户端通过 environ 直接传入REMOTE_USER值ASGI 客户端则通过headers传递——这与上文两种环境下request.META键名不同的说明一致。生产环境则应由你的 Web 服务器IIS、Apache 模块等在认证后注入该值Django 侧只负责消费。需要更多控制时若默认行为不够用例如用户名需要清洗 LDAP DN、认证后要按外部目录属性设置用户组可以继承RemoteUserBackend并重写clean_username(username)和configure_user(request, user, createdTrue)等方法configure_user在用户取出或创建后立即调用created参数可区分是首次创建还是同步已有用户适合做本地与外部系统的属性同步如按 LDAP 属性设置用户组。这些方法的语义见 docs/ref/contrib/auth.txt 中RemoteUserBackend一节自定义后端思路在 docs/howto/auth-remote-user.txt 中也有说明。限制与边界认证的最终控制权在前端用户名被认为是可信的Django 不校验密码。因此头防伪造是部署侧的硬前提is_activeFalse的用户默认被拒绝用AllowAllUsersRemoteUserBackend放行是显式选择admin 界面与createsuperuser不感知 remote user 流程它们管理的是数据库用户ASGI 部署必须走反向代理注入/剥离认证头不能用默认配置直接暴露。【免费下载链接】djangoThe Web framework for perfectionists with deadlines.项目地址: https://gitcode.com/GitHub_Trending/dj/django创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表