5

I have a Grails app with some pages only accessible over https and some over http. This is easily handled using a before filter. However when on an https page as soon as a controller does a redirect the user ends up back on http and is directed to https again by the filter.

def update = {
    ...
    redirect(action: "show", id: domainInstance.id)
}

In Firebug I get:

POST ... localhost:8443 (the form submit to controller)
GET ... 302 ... localhost:8080 (the redirect to show in controller)
GET ... 301 ... localhost:8443 (the redirect back to https in filter)

How can I get the controller redirect call to "remember" the current protocol etc.? Or am I doing something else wrong?

David Tinker
  • 9,383
  • 9
  • 66
  • 98

4 Answers4

5

I sorted this out by using an after filter to convert the "Location" header in the response to https when needed. The default CachingLinkGenerator is constructed with the http server URL and uses this to create links. So there doesn't seem to be a way to get it to keep the protocol. I also couldn't see any easy way to replace it with my own extended LinkGenerator.

class SecurityFilters {
    def filters = {
        overall(controller: '*', action: '*') {
            after = {
                String loc = response.getHeader("Location")
                if (isRequiresHttps()) {
                    response.setHeader("Location", convertToHttps(loc))
                }
            }
        }
    }
    private boolean isRequiresHttps() { ... }
    private String convertToHttps(String url) { ... }
}
David Tinker
  • 9,383
  • 9
  • 66
  • 98
  • I'm using grails 1.3.7 and when I use this I get: groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.grails.web.sitemesh.GrailsContentBufferingResponse.getHeader() is applicable for argument types: (java.lang.String) values: [Location] – VMOrtega Oct 24 '14 at 15:40
  • Hmm. Maybe this was only added in Grails 2.0? I never used Grails 1.3.x. – David Tinker Oct 27 '14 at 05:44
3

It's a bug and appears to be fixed in version 2.0

Todd
  • 1,822
  • 15
  • 18
0

I would suggest constructing your URL manually and using redirect with that

Manually as in:

def uri = createLink(action: "show", id: domainInstance.id, absolute: false)
redirect(uri: uri)

OR

def url = createLink(action: "show", id: domainInstance.id, absolute: true)
url = url.replace("http:", "https:")
redirect(url: url)
Jan Wikholm
  • 1,557
  • 1
  • 10
  • 19
  • Yeah but then I have to go an edit every controller + the scaffolded controllers will use a normal redirect – David Tinker Nov 02 '11 at 07:49
  • Might be related to this JIRA issue: http://jira.grails.org/browse/GRAILS-8053 so I would maybe go pitch my voice on that issue to give it weight. – Jan Wikholm Nov 02 '11 at 08:41
  • Hmm. Its marked as fixed in 2.0M2 and I am using 2.0RC1. I think I will have to look at the Grails code to figure out whats happening here. – David Tinker Nov 04 '11 at 05:11
0

I am not sure how you have configured your grails app to run SSL. Maybe you have configured it transparently in you tomcat server connector?

However, in your code you should not care about SSL or not. Maybe this helps: http://www.juliesoft.com/2010/04/automatic-httphttps-switching-with-grails/

Chris
  • 8,031
  • 10
  • 41
  • 67