在我们公司,我们有一个运行django应用程序(通过wsgi)和一些遗留php应用程序的apache服务器。为了获得某种单点登录,我们决定使用mod_auth_form和wsgi作为AuthFormProvider。 在django本身我们启用了RemoteUserBackend,一切正常。 遗留的php应用程序也受到mod_auth_form和wsgi的保护。
问题在于,经过身份验证的用户可以访问某些位置,其中经过身份验证的用户可以使用某些附加功能(例如个人问候语或已启用的注销按钮)。
使用我们当前的配置但是,如果用户先前已登录,我无法告诉apache设置REMOTE_USER,但如果用户未登录则不会要求输入密码。
我将尝试举例说明我想要完成的事情。
这是一个示例配置。
<Location "/protected-zone">
AuthType basic
AuthName "private area"
AuthBasicProvider file
AuthUserFile /usr/local/etc/apache2/userfile.htaccess
<RequireAll>
Require valid-user
</RequireAll>
</Location>
<Location "/mixed-zone">
AuthType basic
AuthName "private area"
AuthBasicProvider file
AuthUserFile /usr/local/etc/apache2/userfile.htaccess
<RequireAll>
Require [todo]
</RequireAll>
</Location>
如果用户访问/ protected-zone,则应该要求他们输入密码 - 这很容易。 如果用户然后进入/ mixed-zone(在成功登录后),他或她应该受到他们的用户名(基于标题REMOTE_USER)的欢迎。
如果未经身份验证的用户进入/ mix-zone,则不应提示他或她输入凭据。
我们到目前为止尝试的是省略/ mixed-zone中的ReqireAll标记,这导致apache永远不会设置REMOTE_USER,即使用户之前已登录。
答案 0 :(得分:1)
感谢有关会议的评论,我终于能够在特定情况下解决问题。
我们现在使用以下示例中的会话。
SessionMaxAge [age in seconds]
SessionCookieName session-cookie path=/;httponly;secure;version=1
SessionCryptoPassphrase [some random string]
<Location "/protected-zone">
Session On
SessionEnv On
AuthType basic
AuthName "private"
AuthBasicProvider file
AuthUserFile /usr/local/etc/apache2/userfile.htaccess
<RequireAll>
Require valid-user
</RequireAll>
</Location>
<Location "/mixed-zone">
Session On
SessionEnv On
</Location>
将 SessionEnv 设置为 On apache会在请求中设置一个可供底层应用程序使用的其他 HTTP_SESSION 标头(请参阅PHP示例)下文)
<?php
$session = array();
parse_str($_SERVER['HTTP_SESSION'], $session);
$username = $session['private-user'];
?>
由于我们使用django,我编写了一个小型中间件,它在 RemoteUserMiddleware 之前执行,并根据会话中的用户设置REMOTE_USER(如果之前未指定)。
from urllib.parse import parse_qs # works in pyhton3
class SessionUserMiddleware (object):
"""
Middleware to extract a user from a session if no REMOTE_USER is set.
"""
header = "REMOTE_USER"
session_header = "HTTP_SESSION"
session_key = "private-user"
def process_request(self, request):
if self.header not in request.META or not request.META[self.header]:
try:
username = parse_qs(request.META[self.session_header])[self.session_key]
request.META[self.header] = username
except KeyError:
pass