http://omarello.com/2011/09/grails-custom-target-urls-after-login/
My solution is based on the previous blog entry. The only thing I've added is using Config.groovy to register different ROLE/URL cases. I thought it worthed sharing it.
Let's say we want to redirect users with role ROLE_MANAGER to /users/search and users with role ROLE_PROVIDER to /invoices/search. So I came up with the following lines in my Config.groovy
authenticationurl{ mappings{ ROLE_MANAGER.controller='users' ROLE_MANAGER.action='search' ROLE_PROVIDER.controller='invoices' ROLE_PROVIDER.action='search' } }
The nice thing about configuration files in Grails is that you can build maps just sharing the same root, in other words, I can ask which controller and action should be used for a manager accessing to the key ROLE_MANAGER:
def map = authenticationurl.mappings.ROLE_MANAGER def controller = map.controller // 'users' def action = map.action // 'search'
Taking into account that premise, I built my own AuthenticationHandler. This handler takes the authenticated user's role and use it as key to look for its correspondent controller/action:
import org.codehaus.groovy.grails.plugins.springsecurity.AjaxAwareAuthenticationSuccessHandler import org.springframework.security.core.Authentication import org.apache.commons.logging.LogFactory import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import static org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils.ifAllGranted class AuthenticationHandler extends AjaxAwareAuthenticationSuccessHandler { static log = LogFactory.getLog(AuthenticationHandler) def grailsLinkGenerator def configurationService def springSecurityService @Override protected String determineTargetUrl(HttpServletRequest request,HttpServletResponse response) { /* Taking configuration mappings */ def authMappings = configurationService.authenticationHandlerUrlMappings def defaultUrl = super.determineTargetUrl(request, response) if(log.isDebugEnabled()){ log.debug("Default URL: $defaultUrl") } /* Taking the first match or the targetUrl */ return authMappings.findResult{k,v-> if(ifAllGranted(k)){ /* Here's better to get it absolute */ grailsLinkGenerator.link(v << [absolute:true]) } } ?: defaultUrl } }The line with the authMapping variable assignment is doing grailsApplication.config. authenticationurl.mappings underneath. The value is itself a map of maps.
The method determineTargetUrl loops through the map looking for the first result matching the user's role. If there's an entry the user will be redirected to the configured URL otherwise the default URL will be used (normally it is the same URL where the user was when he tried to authenticate himself).
Notice that I'm using the service grailsLinkGenerator to generate the proper link passing the controller and action arguments to it. This works the same as if we were using the
Ah of course don't forget to register your authentication handler in the resources.groovy file
authenticationSuccessHandler(AuthenticationHandler) { /* Reusing the security configuration */ def conf = SpringSecurityUtils.securityConfig /* Configuring the bean */ requestCache = ref('requestCache') redirectStrategy = ref('redirectStrategy') springSecurityService = ref('springSecurityService') grailsLinkGenerator = ref('grailsLinkGenerator') configurationService = ref('configurationService') defaultTargetUrl = conf.successHandler.defaultTargetUrl alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault targetUrlParameter = conf.successHandler.targetUrlParameter ajaxSuccessUrl = conf.successHandler.ajaxSuccessUrl useReferer = conf.successHandler.useReferer }
No comments:
Post a Comment