Optionally pass REMOTE_USER to application

杀马特。学长 韩版系。学妹 提交于 2020-01-15 03:24:09

问题


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

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.

This is an example configuration.

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

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

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

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.


回答1:


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>

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'];

?>

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


来源:https://stackoverflow.com/questions/34168295/optionally-pass-remote-user-to-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!