考虑以下已部署的 Grails 应用程序的设置。
- Grails 应用程序部署在 Tomcat 服务器 (tomcat7) 上
- 在 Tomcat 前面部署了一个 Apache 网络服务器
- Apache 执行 SSL 卸载,并充当 Tomcat 的代理
到目前为止,这是一个非常标准的设置,我已经成功使用了很多次。我现在的问题是 Grails 应用程序生成的链接,尤其是那些用于重定向的链接(标准 Controller 重定向,它一直发生,例如在成功发布表单之后)。
到目前为止,有一个配置不同于所有其他应用程序:在此 Grails 应用程序中,没有配置 serverURL。该应用程序是一个 Multi-Tenancy 应用程序,其中每个租户都有自己的子域。 (因此,如果应用程序通常在 https://www.example.com 下运行,则租户可以使用 https://tenant.example.com。)子域是自动设置的,即在 DNS 或 Apache 级别没有任何配置。 Grails 可以完美地做到这一点,方法是在 Config.groovy 中省略 serverURL 属性:然后它通过检查客户端主机来解析所有 url。
但是:在生成重定向 URL 时,Grails 并不知道该网站是在 https 下运行的。所有重定向 url 都以 http 开头...我想这并不奇怪,因为在应用程序中没有配置我们使用 https:没有 serverURL 配置,从技术上讲,应用程序正在上运行Tomcat 的标准 http 端口,因为 Apache 的 SSL 卸载和代理。
那么,归根结底:我该怎么做才能使 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)
- 更糟糕的是:生成的 View 中的所有资源都被削弱了:它们现在都以//开头(所以应该是相对的“/css/myapp.css”现在是“//css/myapp.css” )
如有任何帮助或见解,我们将不胜感激!
顺便说一下,Grails 版本是 2.1.1(升级有点落后......)。
最佳答案
您似乎总是在与外界进行 https 通信,因此您最干净的选择是在您的 Apache 网络服务器上解决问题的源头。添加到 httpd.conf Header edit Location ^http://(.*)$ https://$1
,就大功告成了。
如果您有限制迫使您在应用程序中解决这个问题,您可以在拦截器之后重写 Grails 中的 Location
header 字段。该解决方案的详细信息在 this post 中.
关于apache - 部署在代理后面时,Grails 会生成正确的链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29693237/