这让我发疯了。我有一个通过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时重写规则中提供的用户名和密码?
答案 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
希望这能帮助除了我以外的人!