web-dev-qa-db-ja.com

Nginxの背後にあるGunicornのTracにREMOTE_USERを設定する

Nginxの背後にあるGunicornでTracを実行したいと思います。 NginxはLDAPを介してユーザー認証を処理します(これは機能します)が、REMOTE_USERをTracに渡すことができません。

UWSGIの場合、Nginxを次のように構成します(テスト済みで動作します)。

uwsgi_param REMOTE_USER $remote_user;

Gunicornの場合、同様の構成ディレクティブが見つかりませんでした。ヘッダーを設定しようとしましたが、何も変更されていないようです。

proxy_set_header REMOTE_USER $remote_user;

これに関するTrac wikiのエントリ があり、 "wsgiエントリポイントは[...]認証を処理しません"、およびローカルパスワードファイルを使用して基本認証を処理するための回避策。これは私が必要としているものではありません。このREMOTE_USERヘッダーを適切な環境変数に渡すために、エントリポイントを変更する必要がありますか?現在はこれだけです:

import sys
import os

sys.stdout = sys.stderr

os.environ['TRAC_ENV'] = '/path/to/my/trac'

import trac.web.main
application = trac.web.main.dispatch_request
5
Jan Fabry

奇妙なもの。あなたが言ったようにこれをnginx設定に含めることでこれを機能させました

proxy_set_header REMOTE_USER $remote_user;

次に、trac.wsgiファイルの場合はこれ

import trac.web.main
def application(environ, start_application):
    environ['REMOTE_USER'] = environ.get('HTTP_REMOTE_USER')
    return trac.web.main.dispatch_request(environ, start_application)

これを置き換えます

import trac.web.main
application = trac.web.main.dispatch_request

あなたのtrac.wsgiで

どうやら、tracの認証を台無しにする進行中の「HTTP_」について何かがあります

'HTTP_AUTHORIZATION'リクエストヘッダーだけに同じことをすることで同じことが達成できると思いますが、私はそれを試みませんでした。だから私は確かに知りません、私が知っているのはそれが今うまくいくということだけです!

6
byoungb

Mercurialでも同様の問題がありました。上記のbyoungbの答えは、原則としては問題ありませんが、_X-Remote-User_で_REMOTE_USER_ではなく_proxy_set_header_を使用し、次にenviron.get()呼び出しで_HTTP_X_REMOTE_USER_を使用する必要があります。 。

ただし、ほとんどの人はSSLを使用してから基本認証を行うため、次のようにAuthorizationヘッダー(環境に_HTTP_AUTHORIZATION_として到着)を使用できます。

_import base64, re

def use_basic_auth(application):
    def auth_app(environ, start_response):
        auth = environ.get('HTTP_AUTHORIZATION')
        if auth:
            scheme, creds = re.split(r'\s+', auth)
            if scheme.lower() != 'basic':
                raise ValueError('Unknown auth scheme \"%s\"' % scheme)
            user, pword = base64.b64decode(creds).split(':', 1)
            environ['REMOTE_USER'] = user

        return application(environ, start_response)
    return auth_app
_

次に、(Trac用に)書くことができます

_application = use_basic_auth(trac.web.main.dispatch_request)
_

または、私の場合(Mercurialの場合)

_application = use_basic_auth(hgweb(config))
_

HTTP基本認証以外のものを使用している場合、これは明らかに機能しません。その場合、byoungbが提案することを実行するか(より適切なヘッダー名を使用しますが)、認証をnginxに実行させるのではなく、Python最後に移動することができます。後者の欠点は、どこかにセキュリティホールがあると、mightより脆弱になることです。

2
alastair