如何使用mod_rewrite代理URI的userinfo组件?

时间:2015-07-31 18:12:19

标签: apache .htaccess mod-rewrite couchdb mod-proxy

这让我发疯了。我有一个通过Apache Web Server提供服务的Web应用程序。支持应用程序的数据库服务器是Apache CouchDB,它公开HTTP API以检索文档和流附件。

我通过提供一个安全对象来保护CouchDB数据库,该对象只允许某些用户访问数据库中的数据,并返回401以便匿名请求到HTTP端点。

我希望能够将公共URL映射到此数据库中存储的文档附件。所以,我试图在我的.htaccess文件中创建一个重写规则,它将来自某些URL的请求直接代理到CouchDB,同时硬编码用户凭据,如下所示:

## DOWNLOAD STREAM:
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule download/(.*) http://user:pass@127.0.0.1:5984/database/$1 [P]

在理想的世界中,上面的示例将采用以下URL:

http://domain.com/download/UUID/attachment.ext

代理它:

http://user:pass@127.0.0.1:5984/database/UUID/attachment.ext

此方法确实将请求代理到CouchDB,但省略了URI方案的userinfo组件。因此,请求被视为匿名,我收到401错误。 如果我从数据库中删除安全性,则仅对流附件进行流式传输。

我花了几个小时阅读Apache配置并尝试无济于事。由于具有相似关键字的所有相关查询,网络搜索毫无结果。

如何确保mod_rewrite包含代表CouchDB时重写规则中提供的用户名和密码?

1 个答案:

答案 0 :(得分:0)

我明白了!不是将username:password包含在URI方案中,而是需要独立设置Authorization标头。以下解决方案完全在.htaccess文件中运行,这很重要,因为OS X会定期清除VirtualHost站点内的设置:

SetEnvIf Request_URI ^/download/* ADD_COUCH_BASIC_AUTH
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=ADD_COUCH_BASIC_AUTH

## DOWNLOAD STREAM
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule download/(.*) http://127.0.0.1:5984/database/$1 [P]

这种方式的工作方式:我们使用SetEnvIf来检查请求路径是否与我们想要代理的路径匹配,如果是,则设置一个任意环境变量ADD_COUCH_BASIC_AUTH

在后续行中,我们向传出请求添加Basic Auth标头,仅当我们设置的环境变量存在时才添加。因此,只有在通过/download/请求资源时才会添加基本身份验证标头,从而将身份验证凭据发送到CouchDB。

注意:您必须对您的用户名:密码凭据进行Base64编码,并将XXXXXXXXXXX替换为编码值。在Mac上轻松实现此目的:

echo -n 'user:pass' | openssl base64

希望这能帮助除了我以外的人!