
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),僅供參考