部署在代理后面时,Grails 会生成正确的链接
Grails generating proper links when deployed behind proxy
为已部署的 Grails 应用程序考虑以下设置。
- Grails 应用程序部署在 Tomcat 服务器 (tomcat7)
- 在 Tomcat 前面部署了一个 Apache 网络服务器
- Apache 执行 SSL 卸载,并充当 Tomcat
的代理
到目前为止,这是一个非常标准的设置,我已经成功使用了很多次。我现在的问题是 Grails 应用程序生成的链接,尤其是那些用于重定向的链接(标准控制器重定向,它一直发生,例如在成功发布表单之后)。
到目前为止,一个配置与所有其他应用程序不同:在此 Grails 应用程序中 未配置 serverURL。该应用程序是一个多租户应用程序,其中每个租户都有自己的子域。 (因此,如果应用程序通常在 https://www.example.com, a tenant can use 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 中省略了关于配置此 class 的内容。)
当运行这段代码奇怪的事情发生时:
- 在日志中您看到正在执行的代码,并且正在生成更改的 url (http > https),但是...
- 发送到浏览器的重定向不变url (http)
- 更糟糕的是:生成的视图中的所有资源都被削弱了:它们现在都以//开头(所以应该是相对的“/css/myapp。css”现在是“/ /css/myapp.css")
如有任何帮助或见解,我们将不胜感激!
顺便说一句,Grails 版本是 2.1.1(运行 升级有点落后...)。
您似乎总是在与外界进行 https 通信,因此您最干净的选择是在您的 Apache 网络服务器上解决问题的源头。添加到 httpd.conf Header edit Location ^http://(.*)$ https://
,你就完成了。
如果您有限制迫使您在应用程序中解决这个问题,您可以在拦截器之后重写 Grails 中的 Location
header 字段。该解决方案的详细信息在 this post.
中
写这个问题已经过去了很多年,但问题仍然相同或至少相似;-)
以防万一有人遇到 same/similar 问题(Grails 重定向 URL 是 http 而不是 https)...我们遇到了这个问题 OpenShift 上的 Grails 3.3.9 应用程序 运行。 应用程序 运行 处于 HTTP 模式(在端口 8080 上)并且 OpenShift 负载均衡器正在执行 SSL 终止。
我们把
解决了
server:
use-forward-headers: true
进入我们的application.yml
。在那之后 Grails 完美运行并且创建的所有重定向都是正确的 https://
.
提示:我们没有在我们的配置中使用grails.serverURL
为已部署的 Grails 应用程序考虑以下设置。
- Grails 应用程序部署在 Tomcat 服务器 (tomcat7)
- 在 Tomcat 前面部署了一个 Apache 网络服务器
- Apache 执行 SSL 卸载,并充当 Tomcat 的代理
到目前为止,这是一个非常标准的设置,我已经成功使用了很多次。我现在的问题是 Grails 应用程序生成的链接,尤其是那些用于重定向的链接(标准控制器重定向,它一直发生,例如在成功发布表单之后)。
到目前为止,一个配置与所有其他应用程序不同:在此 Grails 应用程序中 未配置 serverURL。该应用程序是一个多租户应用程序,其中每个租户都有自己的子域。 (因此,如果应用程序通常在 https://www.example.com, a tenant can use 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 中省略了关于配置此 class 的内容。)
当运行这段代码奇怪的事情发生时:
- 在日志中您看到正在执行的代码,并且正在生成更改的 url (http > https),但是...
- 发送到浏览器的重定向不变url (http)
- 更糟糕的是:生成的视图中的所有资源都被削弱了:它们现在都以//开头(所以应该是相对的“/css/myapp。css”现在是“/ /css/myapp.css")
如有任何帮助或见解,我们将不胜感激!
顺便说一句,Grails 版本是 2.1.1(运行 升级有点落后...)。
您似乎总是在与外界进行 https 通信,因此您最干净的选择是在您的 Apache 网络服务器上解决问题的源头。添加到 httpd.conf Header edit Location ^http://(.*)$ https://
,你就完成了。
如果您有限制迫使您在应用程序中解决这个问题,您可以在拦截器之后重写 Grails 中的 Location
header 字段。该解决方案的详细信息在 this post.
写这个问题已经过去了很多年,但问题仍然相同或至少相似;-)
以防万一有人遇到 same/similar 问题(Grails 重定向 URL 是 http 而不是 https)...我们遇到了这个问题 OpenShift 上的 Grails 3.3.9 应用程序 运行。 应用程序 运行 处于 HTTP 模式(在端口 8080 上)并且 OpenShift 负载均衡器正在执行 SSL 终止。
我们把
解决了server:
use-forward-headers: true
进入我们的application.yml
。在那之后 Grails 完美运行并且创建的所有重定向都是正确的 https://
.
提示:我们没有在我们的配置中使用grails.serverURL