Skip to content


Configuring different target URLs after login according to user roles (grails spring security)

I was working on some requirement regarding redirecting users to different URLs upon login according to their assigned roles, and was not quite sure how to achieve this in grails (well more specifically with spring security since I am using the spring security core plugin for grails).

Looking through the mailing list, I was able to find this, which had some good information, but did not quite answer the question. After a short chat with Alan (OP) I began my quest to figure out how to do this.

The Basics

One of the great things about the security plugin for grails, is that it gives you lots of functionality out of the box, that most of the time you don’t really need to do more than config changes. It also offers really good documentation on how to do more complex things; but once you hit that point of doing things that are not just configuration changes, it is a good idea to understand how spring security works; and that is what I set out to do.

After reading up some docs and guides on spring security, I got a basic idea of how things are wired, and the basic units that are at hand. For this specific issue, I found this section of the docs very helpful. So from what I gathered after reading the docs and looking at the source code (which was very helpful in putting things together); the idea here is that after an AuthenticationManager has processed the supplied login information, our authentication filter (which is the RequestHolderAuthenticationFilter that the plugin supplies) will delegate the processing to an AuthenticationSuccessHandler or AuthenticationFailureHandler depending on whether the login succeeds or fails.

So, given the above, I implemented my own AuthenticationSuccessHandler to handle redirecting users according to their roles.

 

The Implementation

The plugin already implements its own success handler (namely AjaxAwareAuthenticationSuccessHandler), but I did not really need any of the ajax support, so I went ahead and extended SavedRequestAwareAuthenticationSuccessHandler which is what the plugin extends for the ajax success handler as well. In my implementation below, I don’t really take advantage of what is implemented in that parent class (unless the user role is not in my checks), but just in case I need it, it will be there (the sort of things that the SavedRequestAwareAuthenticationSuccessHandler provides are things that you could configure like the default target url, and whether to always use the default url or make use of the saved request, etc…)

In any case, the code below shows a snapshot of the implementation. The trick is to override the determineTargetUrl method and return a String with the target url you want to send your users to. The rest will be taken care of by the SavedRequestAwareAuthenticationSuccessHandler.
I have put some logic to redirect an admin to a different page from a regular user; and for other roles, I just re-use whatever is defined in the parent class, but feel free to add whatever crazy logic you want here. (I will be passing the admin/user specific urls when defining the bean later on)

package com.omarello.authsuccess;

import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyAuthSuccessHandler 
       extends SavedRequestAwareAuthenticationSuccessHandler {
	
	@Override
	protected String determineTargetUrl(HttpServletRequest request,
                                            HttpServletResponse response) {
		
		boolean hasAdmin = SpringSecurityUtils.ifAllGranted("ROLE_ADMIN");
		boolean hasUser = SpringSecurityUtils.ifAllGranted("ROLE_USER");
		
		if(hasAdmin){
			return adminUrl;
		}else if (hasUser){
			return userUrl;
		}else{
			return super.determineTargetUrl(request, response);
		}
	}

	private String userUrl;
	private String adminUrl;
	
	public void setUserUrl(String userUrl){
		this.userUrl = userUrl;
	}
	
	public void setAdminUrl(String adminUrl){
		this.adminUrl = adminUrl;
	}
}

 

Wiring things

Now, for our shiny success handler to work, we need to wire it to be the one responsible for handling all successful logins instead of the default AjaxAwareAuthenticationSuccessHandler. To do this, we need to edit resources.groovy in our spring config, and assign the authenticationSuccessHandler bean to use our new success handler.

import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils

beans = {
	
	authenticationSuccessHandler(com.omarello.authsuccess.MyAuthSuccessHandler) {
		def conf = SpringSecurityUtils.securityConfig		
		requestCache = ref('requestCache')
		defaultTargetUrl = conf.successHandler.defaultTargetUrl
		alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault
		targetUrlParameter = conf.successHandler.targetUrlParameter
		useReferer = conf.successHandler.useReferer
		redirectStrategy = ref('redirectStrategy')
		adminUrl = "/admin/index"
		userUrl = "/user/profile"
	}
}

Again, looking through the grails spring security plugin source code came in handy here. I used similar configurations adding the adminUrl and userUrl along with the other properties. (it is probably a good idea to move those URLs to the config as well, but you get the idea)

 
Once you have done this, then you should be good to go.
I am not sure if there is another way to do this, maybe implementing your own filter and bypassing all the authentication success and failure handlers is another option. But I think this way you will be able to support any filter you’ve got configured. If anyone has a better way to do this I’d love to hear it :)

Posted in Programming.

Tagged with , .


5 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Lindsey says

    It unlicensed contractors can be a quote and even installing new gutters is an online search for BSA Licensee.
    The higher Sacramento area has specialists who would be complete
    until the job!

  2. acnščíliment a eviter says

    These swellings are usually filled with pus and appear on the neck,
    shoulders, chest, back and the face. You can rub a little portion of garlic on your acne, more than once in a
    day. Skin picking has been associated with mood and anxiety disorders, personality disorders (obsessive-compulsive and borderline personality), impulse-control disorder (Bloch, Elliott, Thompson, & Koran,
    2001), and body dysmorphic disorder (Neziroglu & Mancebo, 2001).

  3. katlynandrade.wordpress.com says

    The proposed weight loss is in the range of half a
    pound to a pound (. Besides tracking our weight, a great bathroom scale is especially important when we’re
    on a specific eating habits or exercise program.
    One weekend she did us the “favor” of throwing out a potted Amaryllis bulb; I rescued it just in time from the rubbish,
    but not before we argued as to whether there was anything actually growing in that pot of bone dry dirt under the pantry cabinets.

  4. google url shortener api key says

    This paragraph will assist the internet users for building up new web site or even a weblog from start
    to end.

Continuing the Discussion

  1. seo outsourcing company india linked to this post on July 8, 2014

    seo outsourcing company india

    Configuring different target URLs after login according to user roles (grails spring security) – train of thought



Some HTML is OK

or, reply to this post via trackback.