具有 Spring Security 的站点的 Apache 反向代理设置

AAg*_*Agg 2 tomcat reverse-proxy proxypass springframework apache-2.2

我有一个 Spring MVC 应用程序,它使用 Spring Security 进行登录。我使用 Apache Webserver 作为代理和 Tomcat。下面是我的 /etc/apache2/sites-enabled/example.com.conf 文件:

ServerAdmin admin@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html

ProxyPreserveHost On
ProxyRequests off

ProxyPass /myapp/j_spring_security_check http://XX.YY.ZZ.WW:8080/myapp/j_spring_security_check
ProxyPassReverse /myapp/j_spring_security_check http://XX.YY.ZZ.WW:8080/myapp/j_spring_security_check

ProxyPass /myapp http://XX.YY.ZZ.WW:8080/myapp
ProxyPassReverse /myapp http://XX.YY.ZZ.WW:8080/myapp
Run Code Online (Sandbox Code Playgroud)

我的问题是现在我必须访问我的网站:

www.example.com/myapp

我想在哪里访问它

www.example.com

我尝试使用它,但随后登录无法正常工作。我应该如何为此设置 ProxyPass 和 ProxyPassReverse?

Pau*_*aul 5

几天来我一直在为同样的问题苦苦挣扎,我可能已经破解了它。我是 Spring Security 的新手,所以不要把它当作福音!其他人可能会反对...我使用的是 Apache 2.4(在 OS X 上)和 Spring Security 4.1.1。

一切都在本地运行得非常好,但是每当它被部署到反向代理后面时,我每次登录时都会遇到 404 错误。经过多次摸索和谷歌搜索后,我发现了以下内容:

(因为我没有足够的声望点来发布更多 2 个链接,所以我不得不在 URL 的“http://”之后使用一个空格!)

假设 Apache 和 Tomcat 在同一主机 (localhost) 上运行,Apache 配置为将来自 www.example.com 的请求代理到我们部署在上下文路径“/webapp”下的 Web 应用程序

    ProxyPass / http://localhost:8080/webapp/
    ProxyPassReverse / http://localhost:8080/webapp/
Run Code Online (Sandbox Code Playgroud)
  1. 外部客户端请求受保护的 URL:http://www.example.com/secret

    GET /secret HTTP/1.1
    
    Run Code Online (Sandbox Code Playgroud)
  2. Apache 将此代理到 http:// localhost:8080/webapp/secret

  3. Spring 的安全过滤器之一进行干预并响应重定向到 /login

    HTTP/1.1 302 Found
    Location: http://www.example.com/login
    
    Run Code Online (Sandbox Code Playgroud)
  4. 浏览器获取 URL

    GET /login HTTP/1.1
    
    Run Code Online (Sandbox Code Playgroud)
  5. Apache 将此代理到 http:// localhost:8080/webapp/login

  6. Spring 使用其默认登录页面进行响应

    HTTP/1.1 200 OK
    
    Run Code Online (Sandbox Code Playgroud)
  7. 在这一点上要注意的有趣的事情是 Spring 生成的登录表单在表单操作元素前面加上了上下文路径(即 action="/webapp/login")。然后单击提交按钮时,将对 URL /webapp/login 执行 POST

    POST /webapp/login HTTP/1.1
    
    Run Code Online (Sandbox Code Playgroud)

我们现在有一个问题。当 Apache 将其代理到后端服务器时,生成的 URL 将是 http://localhost/webapp/webapp/login。您可以在 catalina.out 日志中看到这一点,显示没有处理程序可以处理请求,因为上下文路径现在在 URL 中出现了两次。

这里的问题是 ProxyPass 和 ProxyReversePass 指令(mod_proxy 模块)只修改 HTTP 位置标头,URL 保持不变。需要的是在 URL 到达代理之前从 URL 中剥离上下文路径,代理将重新添加它。Apache 的RewriteRule似乎可以解决问题:

RewriteRule /webapp/(.*)$ http://localhost:8080/webapp/$1 [P]
Run Code Online (Sandbox Code Playgroud)

虽然这解决了 404 错误并且我可以看到 Apache 现在代理到正确的 URL,但我每次登录时都会不断地重新显示登录页面。下一个配置似乎解决了这个问题:

ProxyPassReverseCookieDomain localhost www.example.com
ProxyPassReverseCookiePath /webapp/ /
Run Code Online (Sandbox Code Playgroud)

我相信这可能是因为代理导致 cookie 中的域和路径设置不正确,但我必须阅读更多相关内容!

我希望这可以帮助其他人,并且在这方面比我更专业的人可以评论这是否是一个公平的解决方案......