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

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

一位同事建议我将这篇文章从 StackOverflow 转发到 ServerFault:

这让我抓狂不已。我有一个通过 Apache Web Server 提供服务的 Web 应用程序。支持该应用程序的数据库服务器是 Apache CouchDB,它公开了一个 HTTP API 来检索文档和流式传输附件。

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

我希望能够将公共 URL 映射到存储在此数据库中的文档附件。因此,我尝试在 .htaccess 文件中创建一个重写规则,将来自某些 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,但省略了 URI 方案的用户信息组件。因此,该请求被视为匿名请求,我收到 401 错误。仅当我从数据库中删除安全性时,附件才会流式传输。

我花了几个小时研究 Apache 配置,并进行了多次尝试,但毫无结果。由于所有相关查询都带有类似的关键字,因此网络搜索毫无结果。

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

答案1

我找到了答案!Authorization 标头需要单独设置,而不是将 username:password 作为 URI 方案的一部分。以下解决方案完全在文件中运行.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

希望这也能帮助到我以外的人!

答案2

除了 @StickByAtlas 的答案之外,您还可以通过其RewriteRule本身设置环境变量。下面是一个示例,说明如果文件在本地不存在(.htaccess/download文件夹内),我如何使用它从外部存储加载文件:

RewriteEngine on
# rewrite to external source if local file does not exist
RequestHeader set Authorization "Basic XXXXXXXXXXXX" env=EXTERNAL_SOURCE
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ https://external.example.com/download/$1 [P,E=EXTERNAL_SOURCE]

相关内容