2

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

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

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

现在,我们的问题是这个。我们的 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。谢谢

4

5 回答 5

2

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

它本质上与重写入口点有关。

因此,在这些情况下您应该做的部分事情是:

grails.plugins.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true

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

RequestHeader 设置 X-Forwarded-Proto "http"

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

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

于 2012-05-06T00:49:24.293 回答
1

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

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

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

于 2012-05-03T08:46:39.340 回答
0

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

于 2012-04-05T12:36:11.280 回答
0

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

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

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

<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 连接器配置,它可能会给我们更多线索。

于 2012-04-05T15:09:06.210 回答
0

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

像我之前说的那样做端口映射器设置并使用通道安全。

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

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

ProxyPreserveHost 开启

于 2012-05-06T02:07:05.413 回答