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

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

问题描述:

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

I have a primary proxy which sends requests to a secondary proxy on which OpeenSSO is installed.

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

If the OpenSSO agent determines that the user is not logged in, it raises a 302 redirect to the authentication server and provides the original (encoded) URL that the user requested as a GET parameter in the redirect location header.

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

However, the URL in the GET variable is that of the internal (secondary) proxy server, not the original proxy server. Therefore, I would like to edit/rewrite the "Location" response header to give the correct URL.

例如

  1. http://a.com/hello/(原始请求的网址)
  2. http://a.com/hello2/(OpenSSO代理的辅助代理)
  1. http://a.com/hello/ (Original requested URL)
  2. http://a.com/hello2/ (Secondary proxy with OpenSSO agent)
  3. http://auth.a.com/login/?orig_request=http%3A%2F%2Fa.com%2Fhello2%2F (302 redirect to auth server with requested URL of second proxy server encoded in GET variable)
  4. http://auth.a.com/login/?orig_request=http%3A%2F%2Fa.com%2Fhello%2F (Encoded URL is rewritten to that of the original request)

我已经尝试了头文件和重写文件的几乎所有组合,但是没有运气,所以我认为这可能是不可能的.我最接近的是这个,但是mod_headers编辑功能无法解析环境变量.

I have tried pretty much all combinations of headers and rewrites without luck so I'm thinking it may not be possible. The closest I got was this, but the mod_headers edit function does not parse environment variables.

# 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"

ProxyPassReverse

ProxyPassReverse 应该为您做到这一点:>

ProxyPassReverse

ProxyPassReverse should do this for you:

此指令可让Apache调整HTTP重定向响应上的位置,内容位置和URI标头中的URL.

This directive lets Apache adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses.

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

I'm not sure why your reverse proxy isn't behaving this way already, assuming you're using a pair of ProxyPass and ProxyPassReverse directives to define it.

如果您希望能够按照自己的描述编辑位置标头,则可以从Apache 2.4.7起:

If you want to be able to edit the Location header as you describe, you can do it as of Apache 2.4.7:

对于编辑,既有一个值参数(它是一个正则表达式),又有一个附加的替换字符串.从2.4.7版开始,替换字符串也可能包含格式说明符.

For edit there is both a value argument which is a regular expression, and an additional replacement string. As of version 2.4.7 the replacement string may also contain format specifiers.

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

The "format specifiers" mentioned in the docs include being able to use environment variables, e.g. %{VAR}e.

您可能还需要考虑修改应用程序,以便使orig_request URL参数相对应,从而潜在地消除了使用环境变量进行标头编辑的需要.

You might also want to consider modifying your application such that the orig_request URL parameter is relativized, thus potentially eliminating the need for Header edits with environment variables.

您还可以尝试在Location标头中使用相对路径,这样就无需将一个域显式映射到另一个域.根据RFC 7231,这是正式有效的 (2014年6月),,但在此之前,该方法得到了广泛的支持.您可以使用Apache Header edit指令使位置标头相对化(甚至在版本2.4.7之前,因为它不需要环境变量替换).看起来像这样:

You can also try using a relative path in your Location header, which would eliminate the need to explicitly map one domain to the other. This is officially valid as of RFC 7231 (June 2014), but was was widely supported even before that. You can relativize your Location header using Apache Header edit directives (even prior to version 2.4.7, since it wouldn't require environment variable substitution). That would look something like this:

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