我想在 Gunicorn 中运行 Trac,位于 Nginx 后面。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
答案1
很奇怪。我通过像你提到的那样在 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 中
显然,正在进行的“HTTP_”中存在一些问题,导致 trac 的身份验证混乱
我猜想,通过对“HTTP_AUTHORIZATION”请求标头执行相同的操作,可能也能实现相同的效果,但我没有尝试这样做。所以我不确定,我只知道它现在有效!
答案2
我在使用 Mercurial 时遇到了类似的问题;上述 byoungb 的回答在原则上是可以的,但应该使用X-Remote-User
,而不是REMOTE_USER
在 中使用proxy_set_header
,然后在 调用HTTP_X_REMOTE_USER
中使用environ.get()
。
但是,由于大多数人使用 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 Basic 身份验证以外的其他方法,这显然不起作用。在这种情况下,您可以按照 byoungb 的建议(尽管使用更好的标头名称),也可以将身份验证移至 Python 端,而不是让 nginx 执行此操作。后者的缺点是,您可能如果某个地方存在安全漏洞,就会更容易受到攻击。