【问题标题】:Grails + Tomcat + Apache error when switching to HTTPS切换到 HTTPS 时出现 Grails + Tomcat + Apache 错误
【发布时间】:2012-04-19 02:26:33
【问题描述】:

我们有一个 Grails Web 应用程序,在 Apache2 后面的 tomcat7 中运行。使用 ProxyPass 和 ajp 协议一切正常:

ProxyPass         / ajp://localhost:9013/
ProxyPassreverse  / ajp://localhost:9013/

其中 9013 是我们在 tomcat 的 server.xml 中的 AJP 端口。

现在,我们的问题是这样的。我们的 Grails 应用程序同时运行 HTTP 和 HTTPS。当转到应用程序中的某个区域时,Spring Security(Grails Spring Security Core 插件)会将您从使用 HTTP 的地址重定向到 HTTPS,例如当点击:

http://www.example.com/secure/path

Spring Security 会将您重定向到:

https://www.example.com/secure/path

但是现在,当它重定向到那里时,服务器挂起,最后 Firefox 给出 “Firefox 检测到服务器正在以永远不会完成的方式重定向该地址的请求。” 错误.

我是否正确假设使用 AJP 代理进行的某些重定向会变坏?谁能提供有关此设置如何工作的更多信息?


进一步观察,我们发现了以下内容:

当直接(通过 IP 和端口)在 tomcat 中点击应用程序时,一切正常 100%。但是一旦我们通过 Apache,Spring Security 重定向就不起作用了。您不断在 Apache 日志中获得以下信息:

staging.server.com:80 41.133.194.248 - - [05/Apr/2012:14:03:41 +0200] "GET /user/signup HTTP/1.1" 302 223 "http://staging.server.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0"
staging.server.com:80 41.133.194.248 - - [05/Apr/2012:14:03:42 +0200] "GET /user/signup HTTP/1.1" 302 223 "http://staging.server.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0"
staging.server.com:80 41.133.194.248 - - [05/Apr/2012:14:03:42 +0200] "GET /user/signup HTTP/1.1" 302 223 "http://staging.server.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0"
staging.server.com:80 41.133.194.248 - - [05/Apr/2012:14:03:42 +0200] "GET /user/signup HTTP/1.1" 302 223 "http://staging.server.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0"

...

而不是重定向到 https,似乎 apache 神奇地让它再次尝试 http。 谢谢

【问题讨论】:

  • 是只有在有重定向时才会失败,还是在尝试直接进入HTTPS页面时也会失败?

标签: apache tomcat grails ajp


【解决方案1】:

虽然我不能告诉你如何解决它,但我可以告诉你问题是什么。

本质上是重写入口点。

所以你在这些情况下应该做的部分事情已经确定:

grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true

如果我们真的在 http/https 上,这将通过设置标头来查找,默认为:

RequestHeader 设置 X-Forwarded-Proto "http"

现在我在 nginx 中可以正常工作。前面有 apache 的问题是重写规则 ARENT 拿起 apache 服务器。他们只是捡起自我。因此,当它运行时,它基本上会遇到无限重定向,因为它所知道的只是你所在的 9013 服务器。

现在我想我只是编写自己的自定义 HttpsEntry 但我想有一些 apache 设置可以使这项工作正常进行。

【讨论】:

    【解决方案2】:

    Grails/Spring-Security 具有以下属性:

    grails {
       // redirect ports
       plugins {
          springsecurity {
             portMapper {
                httpPort = 80
                httpsPort = 443
             }
          }
       }
    }
    

    您可以使用 hongo 的上述 httpd-config(端口 80/443,SSL 终止于 Apache)。您可能还想适当地设置server.url 属性。

    【讨论】:

      【解决方案3】:

      免责声明,我不是 Grails 专家。

      但根据您的描述,配置可能如下:

      SSL 被卸载到 apache httpd。因此,只需要在 Tomcat 中配置 ajp 连接器,或者可能需要额外的 http 连接器来进行测试。 按照http://httpd.apache.org/docs/2.0/ssl/ssl_howto.html 为 apache httpd 配置启用 SSL 和

      <VirtualHost _default_:80>
      
          RedirectPermanent /secure/path https://www.example.com/secure/path
          ProxyPass         / ajp://localhost:8009/
          ProxyPassreverse  / ajp://localhost:8009/
      </VirtualHost>
      
      <VirtualHost _default_:443>
      
          # SSL config
          ...
          ProxyPass         / ajp://localhost:8009/
          ProxyPassreverse  / ajp://localhost:8009/
      </VirtualHost>
      

      应该可以。

      另一个好处是,当 SSL 卸载到 apache httpd 时,您可能会看到性能提升。

      另外,为什么不对所有东西强制使用 SSL:

      <VirtualHost _default_:80>
      RedirectPermanent / https://www.example.com/
      </VirtualHost>
      
      <VirtualHost _default_:443>
      
      # SSL config
          ...
      
      ProxyPass         / ajp://localhost:8009/
      ProxyPassreverse  / ajp://localhost:8009/
      </VirtualHost>
      

      至于为什么会有无限循环,可能与 Spring Security 的 sendRedirect 有关。 如果您可以发布完整的 apache VirtualHost 和 tomcat ajp 连接器配置,它可能会给我们更多线索。

      【讨论】:

        【解决方案4】:

        不确定 spring-security-core 在切换到 HTTPS 时如何决定使用哪个端口,但默认 Tomcat 配置为 AJP 连接器设置了 redirectPort="8443",也许您需要更改为 443 以便重定向命中Apache 的 HTTPS 端口。

        【讨论】:

        • 这不起作用,因为我们需要运行多个 tomcat 实例,所以一旦我们有两个都需要 https 的应用程序,一个将无法运行,因为它无法运行绑定到 443 端口。
        • 这里不涉及绑定,它只是一个 Tomcat 在重定向到 HTTPS 时将使用的端口的属性。
        • 但是如上所述,我不确定spring-security-core是否使用了这个属性。
        【解决方案5】:

        顺便说一句……这是你的答案。

        端口映射器设置也是如此,并像我之前所说的那样使用通道安全性。

        通道安全需要知道何时转发到 http/https

        但在重定向中,您需要保留代理设置,以便 request.getServerPort() 可以找到它们。您可以将其添加到您的 Apache httpd.conf:

        ProxyPreserveHost 开启

        【讨论】:

          猜你喜欢
          • 2019-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-24
          • 2013-08-27
          • 1970-01-01
          • 2016-09-25
          • 1970-01-01
          相关资源
          最近更新 更多