如何使用 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。
假设您使用一对 ProxyPass 和 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 在代理设置中重写位置响应标头?的主要内容,如果未能解决你的问题,请参考以下文章
nginx proxy_redirect 不会在响应中重写位置标头
如何为所有路径设置代理位置,除了一些使用 apache2 的路径? [关闭]