可选择将 REMOTE_USER 传递给应用程序
Optionally pass REMOTE_USER to application
我们公司有一个 apache 服务器 运行 一个 django 应用程序(通过 wsgi)和一些遗留的 php 应用程序。为了进行某种单点登录,我们决定使用 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(成功登录后),他或她应该会收到他们的用户名(基于 header REMOTE_USER)。
如果未经身份验证的用户访问 /mixed-zone,系统不应提示他或她输入凭据。
到目前为止,我们尝试的是省略 /mixed-zone 中的 ReqireAll 标记,这会导致 apache 永远不会设置 REMOTE_USER,即使用户之前已登录也是如此。
感谢关于 sessions 的评论,我终于能够在我们的特定案例中解决问题。
我们现在使用 sessions,如下例所示。
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 header 在底层应用程序可能使用的请求中(参见下面的 PHP 示例)
<?php
$session = array();
parse_str($_SERVER['HTTP_SESSION'], $session);
$username = $session['private-user'];
?>
因为我们使用 django 我写了一个小的中间件,它在 RemoteUserMiddleware 之前执行并根据 session 中的用户设置 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
我们公司有一个 apache 服务器 运行 一个 django 应用程序(通过 wsgi)和一些遗留的 php 应用程序。为了进行某种单点登录,我们决定使用 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(成功登录后),他或她应该会收到他们的用户名(基于 header REMOTE_USER)。
如果未经身份验证的用户访问 /mixed-zone,系统不应提示他或她输入凭据。
到目前为止,我们尝试的是省略 /mixed-zone 中的 ReqireAll 标记,这会导致 apache 永远不会设置 REMOTE_USER,即使用户之前已登录也是如此。
感谢关于 sessions 的评论,我终于能够在我们的特定案例中解决问题。
我们现在使用 sessions,如下例所示。
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 header 在底层应用程序可能使用的请求中(参见下面的 PHP 示例)
<?php
$session = array();
parse_str($_SERVER['HTTP_SESSION'], $session);
$username = $session['private-user'];
?>
因为我们使用 django 我写了一个小的中间件,它在 RemoteUserMiddleware 之前执行并根据 session 中的用户设置 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