在所有其他指令之后执行 RewriteRule 代理重定向指令

在所有其他指令之后执行 RewriteRule 代理重定向指令

我有一个后端应用程序位于受 SSO 保护的反向代理后面。成功验证后,SSO 会导出包含用户 ID 的 HTTP 标头。我需要将此 uid 和其他数据传递给将对所有内容进行签名的程序。

工作原理如下:

  1. 使用 RewriteMap 定义脚本
  2. 使用 SSO 导出的标头值设置环境变量
  3. 调用脚本,获取返回的值并将其附加到环境变量中
  4. 检查环境变量并使用这些值创建 cookie

然后,最后的 RewriteRule 指令会将流量传递给后端应用程序,问题是,一旦我使用 P 标志设置 RewriteRule,所有上述变量影响都不再起作用。

问题:在代理所有流量之前,如何设法执行所有指令并创建 cookie,以便我的 cookie 可在我的后端应用程序中使用?

RewriteMap  cookiemap prg:/dir/cookieSign.py
RewriteRule ^ - [env=LLNGUID:%{HTTP:Test}]

RewriteCond ${cookiemap:%{REMOTE_ADDR}-%{ENV:LLNGUID}} ^(.*)\s(.*)\s(.*)\s([a-z]+)$
RewriteRule ^ - [E=SIGNATURE:%1,E=SETTIME:%2,E=SETIP:%3,E=UIDSCRIPT:%4]

RewriteCond "%{ENV:SIGNATURE}" "!^$"
RewriteCond "%{ENV:SETTIME}" "!^$"
RewriteCond "%{ENV:SETIP}" "!^$"
RewriteCond "%{ENV:UIDSCRIPT}" "!^$"
RewriteRule ^ - [CO=MY_COOKIE:userid=%{ENV:UIDSCRIPT}&sign=%{ENV:SIGNATURE}&time=%{ENV:SETTIME}&ip=%{ENV:SETIP}:.test.ltd:86400:/:true:true]

RewriteRule "^(.*)$" "http://127.0.0.1:8080$1" [P,L]

谢谢 :)

答案1

问题不在于执行顺序 - 指令按照显示的顺序执行 - 而是变量范围和 cookie 设置的问题。

您在此处设置的环境变量将无法用于目标服务器,因为这是一个不同的范围

您正在“设置”的 cookie 将无法在当前请求中供您的脚本使用。设置 cookie(例如使用标志CO)会Set-Cookie在 HTTP 上设置 HTTP 响应标头回复返回到客户端/浏览器。cookie 仅在下一个当浏览器(希望)返回CookieHTTP要求標軸。

如果你想将此信息发送到你的后端服务器当前的请求,那么您需要使用不同的方法。也许是代理请求上的查询字符串?

例如:

RewriteMap  cookiemap prg:/dir/cookieSign.py

RewriteRule ^ - [env=LLNGUID:%{HTTP:Test}]

RewriteCond ${cookiemap:%{REMOTE_ADDR}-%{ENV:LLNGUID}} ^([^\s]+)\s([^\s]+)\s([^\s]+)\s([a-z]+)$
RewriteRule ^ - [E=SIGNATURE:%1,E=SETTIME:%2,E=SETIP:%3,E=UIDSCRIPT:%4]

RewriteCond %{ENV:SIGNATURE} .
RewriteCond %{ENV:SETTIME} .
RewriteCond %{ENV:SETIP} .
RewriteCond %{ENV:UIDSCRIPT} .
RewriteRule ^ - [ENV=MY_QUERY:userid=%{ENV:UIDSCRIPT}&sign=%{ENV:SIGNATURE}&time=%{ENV:SETTIME}&ip=%{ENV:SETIP}]

RewriteRule (.*) http://127.0.0.1:8080$1?%{ENV:MY_QUERY} [P]

笔记:

  • 将与 rewritemap 的输出匹配的正则表达式更改为使用[^\s]+而不是.*避免不必要的回溯。
  • 不需要将所有参数括在引号中,除非它们包含空格
  • 与其检查是否为空("!^$"),不如检查它是否为某物, IE .
  • L使用标志时不需要该标志P(它是隐含的)。

答案2

感谢@MrWhite 的详细回复,与此同时,我找到了一个似乎可行的解决方案。我保留了上述所有配置,但我没有将其保留在 VHOST 配置中,而是在 VHOST 标签内添加了一个位置标签:

<VirtualHost _default_:443>
#
# Some conf here
#
<LocationMatch "^/*">
        RewriteRule ^ - [env=LLNGUID:%{HTTP:Test}]

        RewriteCond ${cookiemap:%{REMOTE_ADDR}-%{ENV:LLNGUID}} ^(.*)\s(.*)\s(.*)\s([a-z]+)$
        RewriteRule ^ - [E=SIGNATURE:%1,E=SETTIME:%2,E=SETIP:%3,E=UIDSCRIPT:%4]

        RewriteCond "%{ENV:SIGNATURE}" "!^$"
        RewriteCond "%{ENV:SETTIME}" "!^$"
        RewriteCond "%{ENV:SETIP}" "!^$"
        RewriteCond "%{ENV:UIDSCRIPT}" "!^$"
        RewriteRule ^ - [CO=MY_COOKIE:userid=%{ENV:UIDSCRIPT}&sign=%{ENV:SIGNATURE}&time=%{ENV:SETTIME}&expires=480&ip=%{ENV:SETIP}:.domain.ltd:86400:/:true:true]

        RewriteRule "^(.*)$" "http://127.0.0.1:8080%{REQUEST_URI}" [P,L]
</LocationMatch>

</VirtualHost>

通过此配置,cookie 已创建并可供我的后端应用程序使用。我会纠正您在评论中指出的问题。

相关内容