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

Excellent, just what I was looking for.
Thanks for this.
great article, simplifies something which is tricky to discover.
This is exactly what I needed! Unfortunately when I implemented your code it didn’t seem to have any effect. I threw some breakpoints and print statements into your code and it looks like it isn’t ever being executed. I’m not very familiar with spring and wiring up beans. Is there anything else that needs to be done to make this work? Maybe in the config.groovy file?
I stuck the MyAuthSuccessHandler class in my src/java directory. I assume this is ok? I’m using Grails 2.0 and spring-security-core 1.2.6
Ryan, did you ever get an answer to this? I’m having the exact same problem, the code never seems to get executed.
why i can not do some save action here, it seems no session has been found in MyAuthSuccessHandler
This is great! I was doing crytpic logic post login to achieve this but this is so much more elegant and maintainable
In my configuration determineTargetUrl() is never called. I don’t know exacly why. But one can ovveride onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) and there set url with setDefaultTargetUrl(adminUrl) before calling super.
Hi mlip, can you clarify exactly what you implemented in your MyAuthSuccesHandler? If you could share the code that would really help.
In my application determineTargetUrl() is never called. Can any body let me know what I am doing wrong ?.
Thanks a lot, exactly what I was looking for. It works perfect in my app.
Excellent, clean and well done
Thanks for this. Very well done.
I really understand why post. I’ve been looking everywhere for this reason!
Thank heavens I uncovered it on Bing. You’ve got made my day! Thanks again
Paragraph writing is also a fun, if you be acquainted with then
you can write or else it is difficult to write.
Hi, after reading this remarkable piece of writing i am
as well cheerful to share my experience here with mates.
There’s certainly a great deal to find out about this topic. I love all the points you made.
I got this web page from my friend who informed me regarding this website and now this time I am visiting this web page and reading very informative
content at this place.
Good post however , I was wanting to know if you could write a litte
more on this topic? I’d be very thankful if you could elaborate a little bit further. Kudos!
The write-up has proven useful to us. It’s extremely
educational and you’re simply clearly very experienced of this type. You possess opened up my personal sight in order to varying thoughts about this specific matter with intriguing and sound content.
Admiring the persistence you put into your blog and in depth information you present.
It’s nice to come across a blog every once in a while that isn’t the same old rehashed material.
Wonderful read! I’ve saved your site and I’m including your RSS feeds to my Google account.
Hi, I do believe this is an excellent website. I stumbledupon it
I may return
once again since I book marked it. Money and freedom is the greatest way to change, may you be rich and continue to guide other people.
Excellent solutions from you, man. We’ve realize your stuff before and you happen to be just too excellent.
Great post. I was checking continuously
this weblog and We are impressed! Very helpful information particularly the remaining part :
) I maintain such info much. I had been trying to
find this certain info to the number of years. Thanks a lot and all
the best.
I really like looking through an article that
can make men and women think. Also, many thanks for allowing for me to
comment!
I’m keen this blog a whole lot quite a lot good info.
For one thing thank you for writing this. Additionally
there is an issue with your new stylesheet or maybe it’s just my netbook but it doesn’t display right.
I’d constantly have to be update on new websites in this particular site, saved to favorites! .
That is really attention-grabbing, You are an excessively skilled blogger.
I have joined your rss feed and sit up for seeking extra of
your fantastic post. Also, I have shared your web site in
my social networks.
Hmm it appears like your website ate my first comment
(it was extremely long) so I guess I’ll just sum it up what I submitted and say, I’m thoroughly enjoying your blog.
I as well am an aspiring blog blogger but I’m still new to everything. Do you have any recommendations for novice blog writers? I’d genuinely appreciate it.