Grails在代理之后部署时生成正确的链接



考虑以下已部署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。

然而:当生成重定向url时,Grails并不知道网站是在https下运行的。所有重定向url都以http开头。。。我想这并不奇怪,因为在配置应用程序的任何地方,我们都使用https:没有serverURL配置,从技术上讲,由于Apache的SSL卸载和代理,应用程序运行在Tomcat的标准http端口上。

所以,底线是:我能做些什么来让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
}
}

(也许不是最漂亮的代码,但我希望它能解释我想做什么。我在resources.groovy中省略了关于配置这个类的部分。)

当运行这个代码时,奇怪的事情发生了:

  • 在日志中,您可以看到正在执行的代码,以及正在生成的更改后的url(http>https),但是
  • 发送到浏览器的重定向是未更改的url(http)
  • 更糟糕的是:生成的视图中的所有资源都被破坏了:它们现在都以//开头(所以应该是相对的"/css/myapp.css"现在是"//css/myapp.css")

如有任何帮助或见解,我们将不胜感激!

顺便说一句,Grails的版本是2.1.1(在升级时运行有点落后…)

你似乎总是在与外界谈论https,所以你最干净的选择是在Apache Web服务器上解决它的来源问题。添加到httpd.confHeader edit Location ^http://(.*)$ https://$1,就完成了。

如果您的应用程序中有一些限制,迫使您解决这个问题,那么您可以在Grails after拦截器中重写Location头字段。有关该解决方案的详细信息,请参阅本文。

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

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

我们通过放置解决了这个问题

server:
use-forward-headers: true

进入我们的CCD_ 3。在那之后,Grails的工作非常完美,并且使用https://创建的所有重定向都是正确的。

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

最新更新