如何在使用Apache代理的情况下重新编写位置响应头?

19

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

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

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

例如:

  1. http://a.com/hello/(原始请求的URL)
  2. http://a.com/hello2/(安装了OpenSSO代理的辅助代理)
  3. http://auth.a.com/login/?orig_request=http%3A%2F%2Fa.com%2Fhello2%2F(302重定向到带有编码的第二个代理服务器的请求URL的身份验证服务器)
  4. 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_request}e"
1个回答

25

ProxyPassReverse

ProxyPassReverse可以为您完成此操作:

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

如果您使用一对ProxyPass和ProxyPassReverse指令定义反向代理,我不确定为什么您的反向代理还没有表现出这种行为。

编辑Location头

如果您想按照您描述的那样编辑Location头,您可以在Apache 2.4.7版本之后实现:

对于编辑,有一个值参数是正则表达式,还有一个额外的替换字符串。自2.4.7版本以来,替换字符串还可以包含格式说明符。

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

您还可以考虑修改应用程序,使orig_request URL参数成为相对路径,从而可能消除对带有环境变量的Header编辑的需求。

相对路径Location头

您也可以尝试在Location头中使用相对路径,这将消除显式映射一个域到另一个域的需要。这是自RFC 7231(2014年6月)官方有效的,但即使在那之前也得到了广泛支持。您可以使用Apache的Header edit指令使您的Location头变成相对路径(甚至在2.4.7版本之前,因为它不需要环境变量替换)。它看起来像这样:

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

1
感谢您建议直接编辑位置标头! - gaqzi
ProxyPassReverse似乎无法处理201 Created状态码。有什么解决方法吗? - Jochen Bedersdorfer
4
编辑位置头信息的正则表达式未去除冒号和端口号,我成功地使用了以下正则表达式:Header edit Location "(^http[s]?://)([^/]+)" "" - grtjn
我发现在Location块中使用ProxyPassReverse会导致重定向返回到代理链中负载均衡器的IP,而不是外部FQDN。使用Header edit Location完美地解决了这个问题,而且感觉更直观。感谢您的帖子。 - halfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接