可选择将 REMOTE_USER 传递给应用程序 [英] Optionally pass REMOTE_USER to application

查看:25
本文介绍了可选择将 REMOTE_USER 传递给应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们公司,我们有一个 apache 服务器运行 django 应用程序(通过 wsgi)和一些遗留的 php 应用程序.为了实现某种单一登录,我们决定使用 mod_auth_form 和 wsgi 作为 AuthFormProvider.在 Django 本身中,我们启用了 RemoteUserBackend 并且一切正常.遗留的 php 应用程序也通过 mod_auth_form 和 wsgi 得到保护.

In our company we have an apache server running a django application (through wsgi) and some legacy php applications. To have some sort of single sign on we decided to use mod_auth_form and wsgi as the AuthFormProvider. In django itself we enabled the RemoteUserBackend and all works fine. The legacy php applications are also protected via mod_auth_form and wsgi.

问题在于,有些位置应该由经过身份验证的匿名用户访问,其中经过身份验证的用户具有某种额外功能(例如个人问候语或启用的注销按钮).

The problem is that there are some locations which should be accessible by authenticated and anonymous users where authenticated users have some sort of extras (like personal greeting or an enabled logout button).

但是,根据我们当前的配置,如果用户之前已登录,我无法告诉 apache 设置 REMOTE_USER,但如果用户未登录,则不会要求输入密码.

With our current configuration however I can't figure out to tell apache to set REMOTE_USER if a user has logged in previously but does not ask for a password if the user is not logged in.

我将尝试举例说明我想要完成的工作.

I will try to give an example of what I want to accomplish.

这是一个示例配置.

<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).

If users go to /protected-zone they should be asked for a password - that's quite easy. If the user then goes to /mixed-zone (after sucessfull login) he or she should be greeted with their username (based on the header REMOTE_USER).

如果未经身份验证的用户访问/mixed-zone,则不应提示他或她输入凭据.

If an unauthenticated user goes to /mixed-zone he or she should not be prompted to enter credentials.

到目前为止,我们尝试的是省略/mixed-zone 中的 ReqireAll 标记,这会导致 apache 永远不会设置 REMOTE_USER,即使用户之前已登录.

What we've tried so far was to omit the ReqireAll tag in /mixed-zone which causes apache to never set REMOTE_USER even if the user was logged in before.

推荐答案

感谢关于 session 的评论,我终于能够在我们的特定案例中解决问题.

Thanks to the comment about sessions I was finally able to fix the problem in our specific case.

我们现在使用如下例中的会话.

We now use sessions like in the example below.

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 示例)下面)

With SessionEnv set to On apache sets an additional HTTP_SESSION header in the request which may be used by the underlying application (see PHP example below)

<?php

$session = array();
parse_str($_SERVER['HTTP_SESSION'], $session);
$username = $session['private-user'];

?>

因为我们使用 django,所以我写了一个小的中间件,它在 RemoteUserMiddleware 之前执行,如果之前没有指定,则根据会话中的用户设置 REMOTE_USER.

Since we use django I wrote a small middleware which is executed before RemoteUserMiddleware and sets REMOTE_USER according to the user in the session if it was not specified previously.

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

这篇关于可选择将 REMOTE_USER 传递给应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆