我如何强制mod_rewrite发送URI的用户信息组件?

一位同事build议我把这个从StackOverflow重新发布到ServerFault:

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

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

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

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

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

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

并代理它:

 http://user:[email protected]:5984/database/UUID/attachment.ext 

这个方法确实将请求代理到CouchDB,但省略了URIscheme的userinfo组件。 所以,该请求被视为匿名,我得到一个401错误。 如果从数据库中删除安全性,附件只能stream式传输。

我花了几个小时阅读Apache的configuration和尝试无济于事。 由于所有相关的查询都有类似的关键字,networkingsearch是徒劳的。

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

我想到了! 授权标头需要独立设置,而不是将用户名:密码作为URIscheme的一部分。 以下解决scheme完全在.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检查请求path是否匹配我们想要代理的path,如果是,请设置一个任意的环境variablesADD_COUCH_BASIC_AUTH

在随后的行中, 只有当我们设置的环境variables存在时, 才会向传出请求添加一个Basic Auth头。 所以,只有在通过/download/请求资源时才会添加基本的auth头,从而将身份validation凭证发送到CouchDB。

注意:您必须对您的用户名:密码凭据进行Base64编码,并用编码值replaceXXXXXXXXXXX 。 一个简单的方法来做到这一点,在Mac上:

 echo -n 'user:pass' | openssl base64 

希望这有助于除了我之外的人!