springspring-securitygrails-2.0grails-filters

Grails Spring Security AbstractPreAuthenticatedProcessingFilter redirect


I am trying to do PreAuthentication using Spring Security Grails plugin. I read the pre authentication documentation given below, but could not find anything concrete for my situation http://static.springsource.org/spring-security/site/docs/3.0.x/reference/preauth.html

In my situation, we have a agent which parses the SAML request and gives a map after successful authentication. Recommendation is to use this jar. Hence, I extended AbstractPreAuthenticatedProcessingFilter and try to do this

@Override 
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
      userInfo = agent.readToken(request); 
        if (!userInfo){ 
             WebUtils.retrieveGrailsWebRequest().getCurrentResponse().sendRedirect(ssoUrl) 
        } 
        return userInfo 
}

I have placed myFilter under src/groovy and registered this filter in BootStrap

def init = { servletContext -> 
        SpringSecurityUtils.clientRegisterFilter( 
                'myFilter', SecurityFilterPosition.PRE_AUTH_FILTER.order) 
} 

Its getting loaded correctly, but filter is not issuing a redirect. First of all, I wanted to check if this is the right approach and if it is, how to get redirect working.

I have asked the same question in grails user forum

Any help is greatly appreciated.

Update:

Final configuration which worked for me

Wrote MyAuthenticationService which implements AuthenticationUserDetailsService as suggested. You also have to define preAuthenticatedAuthenticationProvider which wraps your custom service

resources.groovy

securityFilter(MySSOAuthFilters){ bean ->
    authenticationManager = ref('authenticationManager')
    grailsApplication = ref('grailsApplication')
}

customUserDetailsService(MyAuthenticationService)

preAuthenticatedAuthenticationProvider(org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider) {
    preAuthenticatedUserDetailsService = ref('customUserDetailsService')
}

I was not able to do <form-login> because in Grails, this is done using grails.plugins.springsecurity.auth.loginFormUrl config parameter which only accepts relative url.

What I ended up doing is grails.plugins.springsecurity.auth.loginFormUrl = '/login/index'

In LoginController

def index() {
    if(springSecurityService.isLoggedIn()){
        log.info("User is logged in")
        return redirect(controller: 'mycontroller', action: 'list')
    }
    log.info("user is not logged in...redirect to sso.")
    return redirect(url: ssoUrl)
}

Hope this helps


Solution

  • A couple of things I see that need to be changed.

    First, do not to send a redirect in the preauth filter just simply return null. The preauth filter is only used to return a subject that your AuthenticationUserDetailsService can use to create the UserDetails object by implementing the method below in your implementation of the AuthenticationUserDetailsService .

    public UserDetails loadUserDetails(AbstractAuthenticationToken token) {
        return createUserFromSubject((Subject) token.getPrincipal());
    }
    

    Second, set the form login page as part of your configuration. This will be used to redirect to if no subject exists.

    <form-login login-page="http://url_youwanttoredirect_to_on_auth_req" authentication-failure-url="http://url_youwanttoredirect_to_on_auth_req"/>