切换到 HTTPS 时出现 Grails + Tomcat + Apache 错误

Posted

技术标签:

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

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

ProxyPass         / ajp://localhost:9013/
ProxyPas-s-reverse  / 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页面时也会失败? 【参考方案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/
    ProxyPas-s-reverse  / ajp://localhost:8009/
</VirtualHost>

<VirtualHost _default_:443>

    # SSL config
    ...
    ProxyPass         / ajp://localhost:8009/
    ProxyPas-s-reverse  / 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/
ProxyPas-s-reverse  / 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 开启

【讨论】:

以上是关于切换到 HTTPS 时出现 Grails + Tomcat + Apache 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Acegi 和 Grails 通过 LDAP 进行身份验证时出现 PartialResultException

尝试在 Tomcat 中启动 grails App 时出现“严重:错误 listenerStart”

为 grails 运行 test-app -coverage 命令时出现错误,即使所有测试用例都通过了

创建新项目时出现 Grails 2.3.7 错误

更改服务方法的名称时出现 Grails ReloadingException

在 Grails 的 Spring Security Rest Plugin 中注销时出现 404