如何使用 Apache 在代理设置中重写位置响应标头?

Posted

技术标签:

【中文标题】如何使用 Apache 在代理设置中重写位置响应标头?【英文标题】:How to rewrite Location response header in a proxy setup with Apache? 【发布时间】:2013-04-24 05:11:36 【问题描述】:

我有一个主代理,它将请求发送到安装了 OpeenSSO 的辅助代理。

如果 OpenSSO 代理确定用户未登录,它会引发 302 重定向到身份验证服务器,并在重定向位置标头中提供用户请求的原始(编码)URL 作为 GET 参数。

但是,GET 变量中的 URL 是内部(辅助)代理服务器的 URL,而不是原始代理服务器的 URL。因此,我想编辑/重写“位置”响应标头以提供正确的 URL。

例如

    http://a.com/hello/(原始请求网址) http://a.com/hello2/(带有 OpenSSO 代理的二级代理) http://auth.a.com/login/?orig_request=http%3A%2F%2Fa.com%2Fhello2%2F(302 重定向到授权服务器,请求的第二个代理服务器的 URL 编码在 GET 变量中) http://auth.a.com/login/?orig_request=http%3A%2F%2Fa.com%2Fhello%2F(编码后的 URL 被重写为原始请求的 URL)

我已经尝试了几乎所有标题组合和重写但没有运气,所以我认为这可能是不可能的。我得到的最接近的是这个,但是 mod_headers 编辑函数不解析环境变量。

# On the primary proxy.
RewriteEngine On
RewriteRule ^/(.*)$ - [E=orig_request:$1,P]
Header edit Location ^(http://auth\.a\.com/login/\?orig_request=).*$ "$1http%3A%2F%2Fa.com%2F%orig_requeste"

【问题讨论】:

【参考方案1】:

ProxyPassReverse

ProxyPassReverse 应该为你做这个:

该指令允许 Apache 调整 HTTP 重定向响应的 Location、Content-Location 和 URI 标头中的 URL。

假设您使用一对 P​​roxyPass 和 ProxyPassReverse 指令来定义它,我不确定为什么您的反向代理还没有以这种方式运行。

编辑位置标题

如果您希望能够按照您的描述编辑 Location 标头,您可以这样做as of Apache 2.4.7:

对于编辑,既有一个正则表达式的值参数,也有一个额外的替换字符串。从 2.4.7 版本开始,替换字符串也可能包含格式说明符。

文档中提到的“格式说明符”包括能够使用环境变量,例如%VARe.

您可能还需要考虑修改您的应用程序,使 orig_request URL 参数相对化,从而可能消除使用环境变量编辑 Header 的需要。

相对路径位置标头

您还可以尝试在 Location 标头中使用相对路径,这样就无需将一个域显式映射到另一个域。这是正式有效的as of RFC 7231(2014 年 6 月),but was was widely supported even before that。您可以使用 Apache Header edit 指令相对化您的 Location 标头(甚至在版本 2.4.7 之前,因为它不需要环境变量替换)。看起来像这样:

Header edit Location "(^http[s]?://)([a-zA-Z0-9\.\-]+)(:\d+)?/" "/"

【讨论】:

感谢您直接直接编辑位置标题的建议! ProxyPassReverse 似乎不适用于 201 Created。有什么解决方法吗? 编辑 Location 标头的正则表达式不会去掉冒号和端口。我成功地使用了这个:Header edit Location "(^http[s]?://)([^/]+)" "" 我发现在Location 块中使用ProxyPassReverse 会导致重定向返回到代理链中负载均衡器的IP,而不是外部FQDN。使用Header edit Location 效果很好,而且感觉更直观。谢谢你的帖子。

以上是关于如何使用 Apache 在代理设置中重写位置响应标头?的主要内容,如果未能解决你的问题,请参考以下文章

Apache 重写或代理

nginx proxy_redirect 不会在响应中重写位置标头

如何为所有路径设置代理位置,除了一些使用 apache2 的路径? [关闭]

使用 Apache 反向代理的 Ratchet websocket 没有响应

具有SSL终止的Apache前向代理

新的 HttpClient 代理设置问题