Grails在代理后部署时生成适当的链接

时间:2015-04-17 07:44:26

标签: apache tomcat grails https

请考虑部署Grails应用程序的以下设置。

  • Grails应用程序部署在Tomcat服务器(tomcat7)
  • 在Tomcat面前部署了一个Apache Web服务器
  • Apache执行SSL卸载,并充当Tomcat的代理

到目前为止,这是一个非常标准的设置,我已成功使用了很多次。我现在的问题是Grails应用程序生成的链接,特别是重定向的链接(标准控制器重定向,一直发生,例如在成功发布表单之后)。

到目前为止,一个配置与所有其他应用程序不同:在此Grails应用程序中没有serverURL 已配置。该应用程序是一个多租户应用程序,每个租户都被赋予它自己的子域。 (因此,如果应用程序通常在https://www.example.com下运行,则租户可以使用https://tenant.example.com。)子域是自动设置的,即在DNS或Apache级别没有任何配置。 Grails可以通过在Config.groovy中省略serverURL属性来完美地完成:它然后通过检查客户端主机来解析所有URL。

但是:在生成redirect-url时,Grails不知道该网站是在https下运行的。所有重定向网址都以http开头...我想这并不奇怪,因为在应用程序中没有配置我们使用的是https:没有serverURL配置,技术上应用程序 运行在Tomcat的标准http端口上,因为Apache卸载和代理。

所以,底线:我该怎么做才能让Grails生成正确的重定向?

我尝试扩展DefaultLinkGenerator并覆盖makeServerURL()方法。像这样:

class MyLinkGenerator extends DefaultLinkGenerator {

MyLinkGenerator(String serverBaseURL, String contextPath) {
    super(serverBaseURL, contextPath)
}

MyLinkGenerator(String serverBaseURL) {
    super(serverBaseURL)
}

def grailsApplication

/**
 * @return serverURL adapted to deployed scheme
 */
String makeServerURL() {
    // get configured protocol
    def scheme = grailsApplication.config.grails.twt.baseProtocol ?: 'https://'
    println "Application running under protocol $scheme"

    // get url from super
    String surl = super.makeServerURL()
    println "> super.makeServerURL(): $surl"
    if (surl) {
        // if super url not matching scheme, change scheme
        if (scheme=='https://' && surl?.startsWith('http://')) {
            surl = scheme + surl?.substring(7)
            println "> re-written: $surl"
        }
    }

    return surl

}

}

(也许不是最漂亮的代码,但我希望它能解释我想做的事情。我在资源中忽略了配置这个类。)

运行此代码时会发生奇怪的事情:

  • 在日志中,您会看到正在执行的代码,以及正在生成的更改的网址(http> https),但是......
  • 发送到浏览器的重定向是未更改的网址(http)
  • 更糟糕的是:生成的视图中的所有资源都被削弱了:它们现在都以//开头(所以应该是一个亲戚" /css/myapp.css"现在是#34; //css/myapp.css")

任何帮助或见解都将不胜感激!

顺便提一下Grails版本是2.1.1(在升级时稍稍落后......)。

2 个答案:

答案 0 :(得分:2)

看起来你总是在和外界讨论https,所以你最干净的选择就是在你的Apache网络服务器上解决它产生的问题。添加到httpd.conf Header edit Location ^http://(.*)$ https://$1,您就完成了。

如果您的限制迫使您在应用程序中解决此问题,则可以在拦截器后重写Grails中的Location标头字段。该解决方案的详细信息位于this post

答案 1 :(得分:0)

自从写这个问题以来已经过去了几年,但问题仍然相同或至少相似;-)

以防万一有人遇到相同/类似的问题(Grails 重定向 URL 是 http 而不是 https)......我们在运行 Grails 3.3.9 应用程序时遇到了这个问题在 OpenShift 上。 应用程序在 HTTP 模式下运行(在端口 8080 上),OpenShift 负载均衡器正在执行 SSL 终止。

我们把它解决了

server:
  use-forward-headers: true

进入我们的application.yml。之后,Grails 工作完美,所有创建的重定向都与 https:// 正确。

提示:我们没有在配置中使用 grails.serverURL