Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails & Spring Security - Saved request - Empty parameters and unbound command object

I have a controller which accepts a form POST. This method/action of the controller is protected by Spring Security. In this situation the user's session has expired and they click the submit button.

Spring security is creating a saved request and redirecting the user to the login page. Upon logging in Spring Security is redirecting to the POST url for the form. However, params within the controller method/action is empty (except for controller and action name) and the command object is unpopulated.

Using the some simple code within the onInteractiveAuthenticationEvent I can see that the Saved Request has all the parameters in the Parameter Map.

grails.plugins.springsecurity.onInteractiveAuthenticationSuccessEvent = { e, appCtx ->

    def request = org.codehaus.groovy.grails.plugins.springsecurity.SecurityRequestHolder.getRequest()
    def response = org.codehaus.groovy.grails.plugins.springsecurity.SecurityRequestHolder.getResponse()
    org.springframework.security.web.savedrequest.SavedRequest savedRequest = new org.springframework.security.web.savedrequest.HttpSessionRequestCache().getRequest(request, response);

    println savedRequest
    if (savedRequest) {
        savedRequest.getParameterMap().each { k, v ->
            println "${k}: ${v}"
        }
    }
}

Any ideas as to why the params and command object for the controller action/method are empty and unbound? I would expect that after successful login the saved request would be used to populate both params and then in turn the command to bind to the parameters.

I have tested this with both Grails 2.0.4, Spring Security Core Plugin 1.2.7.3 as well as Grails 2.4.2 and Spring Security Core Plugin 2.0-RC3.

like image 343
Joshua Moore Avatar asked Dec 18 '25 01:12

Joshua Moore


1 Answers

Since this appears to be left to you (the user of Spring Security) to implement I decided to do so using a Grails filter. I know it could have been implemented using a Spring Security filter and placed in the filter chain (as indicated by the Spring Security API documentation) but I needed to move on to other things.

So, here is an example of what I did.

package com.example

class SavedRequestFilters {

    def filters = {
        // only after a login/auth check to see if there are any saved parameters
        savedRequestCheck(controller: 'login', action: 'auth') {
            after = {
                org.springframework.security.web.savedrequest.SavedRequest savedRequest = new org.springframework.security.web.savedrequest.HttpSessionRequestCache().getRequest(request, response)
                if (savedRequest) {
                    // store the parameters and target uri into the session for later use
                    session['savedRequestParams'] = [
                        uri: savedRequest.getRedirectUrl(),
                        data: savedRequest.getParameterMap()
                    ]
                }
            }
        }

        all(controller:'*', action:'*') {
            before = {
                // if the session contains dr saved request parameters
                if (session['savedRequestParams']) {
                    def savedRequestParams = session['savedRequestParams']
                    // only if the target uri is the current will the params be needed
                    if (savedRequestParams.uri.indexOf("/${controllerName}/") > -1) {
                        savedRequestParams.data.each { k, v ->
                            params[k] = v.join(",")
                        }
                        // clear the session storage
                        session['savedRequestParams'] = null
                    }
                }
            }
        }
    }
}
like image 132
Joshua Moore Avatar answered Dec 20 '25 18:12

Joshua Moore



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!