Pieter van Gent
Pieter van Gent

Reputation: 65

Grails generating proper links when deployed behind proxy

Consider the following setup for a deployed Grails application.

So far a quite standard setup, which I have used succesfully many times. My issue is now with the links generated by the Grails application, especially those for the redirects (the standard controller redirects, which occur all the time e.g. after succesfully posting a form).

One configuration is different from all the other applications so far: in this Grails application no serverURL is configured. The application is a multi-tenant application, where each tenant is given it's own subdomain. (So if the application in general is running under https://www.example.com, a tenant can use https://tenant.example.com.) Subdomains are set automagically, that is without any configuration at DNS or Apache level. Grails can do so perfectly, by leaving out the serverURL property in Config.groovy: it then resolves all url's by inspecting the client host.

However: when generating redirect-url's, Grails is not aware the website is running under https. All redirect url's start with http... I guess this is no surprise, because nowhere in the application it is configured we are using https: there is no serverURL config, and technically the application is running on the standard http port of Tomcat, because of the SSL offloading and proxying by Apache.

So, bottom line: what can I do to make Grails generate proper redirects?

I have tried to extend the DefaultLinkGenerator and override the makeServerURL() method. Like this:

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

}

}

(Maybe not the most beautiful code, but I hope it explains what I'd like to do. And I left out the bit about configuring this class in resources.groovy.)

When running this code strange things happen:

Any help or insight would be appreciated!

Grails version is 2.1.1 by the way (running a bit behind on upgrades...).

Upvotes: 5

Views: 862

Answers (2)

Marc Schmid
Marc Schmid

Reputation: 1336

Some years have past since this question was written, but problems remain the same or at least similar ;-)

Just in case anyone hits the same/similar issue (that Grails redirect-URLs are http instead of https) ... We had this issue with a Grails 3.3.9 application running on OpenShift. The application was running in HTTP mode (on Port 8080) and the OpenShift Loadbalancer was doing the SSL-Termination.

We solved it by putting

server:
  use-forward-headers: true

into our application.yml. After that Grails works perfect and all the redirects created were correct with https://.

Hint: We have do not use grails.serverURL in our configuration

Upvotes: 1

jaapvee
jaapvee

Reputation: 141

It seems you're always talking https to the outside world, so your cleanest option is to solve the problem where it originates, at your Apache webserver. Add to httpd.conf Header edit Location ^http://(.*)$ https://$1, and you're done.

If you have limitations that force you to solve this in your application you could do the rewrite of the Location header field in a Grails after interceptor. Details of that solution are in this post.

Upvotes: 3

Related Questions