I want to redirect a user upon a successful login based on his roles. I am following this example but the method never executes(print does not happen).
My resources.groovy:
beans = {
authenticationSuccessHandler(UrlRedirectEventListener)
{
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')
defaultUrl= "/"
adminUrl = "/admin/"
userUrl = "/user/"
}
}
And my UrlRedirectEventListener
class UrlRedirectEventListener
extends SavedRequestAwareAuthenticationSuccessHandler
{
@Override
protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response) {
boolean hasBoth = SpringSecurityUtils.ifAllGranted("ROLE_USER,ROLE_ADMIN");
boolean hasUser = SpringSecurityUtils.ifAnyGranted("ROLE_USER");
boolean hasAdmin = SpringSecurityUtils.ifAnyGranted("ROLE_ADMIN");
println("hasBoth:"+hasBoth+ " hasUser:"+hasUser+ " hasAdmin:"+hasAdmin)
if( hasBoth ){
return defaultLoginUrl;
}else if ( hasUser ){
return userUrl ;
}else if ( hasAdmin ){
return adminUrl ;
}else{
return super.determineTargetUrl(request, response);
}
}
private String defaultLoginUrl;
private String mmrLoginUrl;
private String pubApiLoginUrl;
...setters for urls
}
What am I missing? I am using Grails 2.0.4 and Spring Security Plugin 2 RC2.0
Thanks!
Edit:
I also have this controller to test that my bean is created, which shows up correctly.
class TestController {
AuthenticationSuccessHandler authenticationSuccessHandler
def index()
{
render( authenticationSuccessHandler )
}
}
After looking at the source, I figured it out. The problem was that SavedRequestAwareAuthenticationSuccessHandler
's method onAuthenticationSuccess
would never reach the overridden method determineTargetUrl
with the simple login scheme I was using( the default that is generated by the plugin ). I had to actually override onAuthenticationSuccess
instead and put my logic there.
The source in question:
SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
My updated UrlRedirectEventListener
, with most copy-pasted from SavedRequestAwareAuthenticationSuccessHandler
:
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
super.onAuthenticationSuccess(request, response, authentication);
return;
}
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
return;
}
def targetUrl = savedRequest.getRedirectUrl();
if( targetUrl != null && targetUrl != "" && targetUrl.endsWith("/myApp/") ) // I only want to differently handle "/". If a user hits /user/, or any other url, attempt to send him there. Spring Security will deny him access based on his privileges if necessary.
targetUrl = this.determineTargetUrl( request, response ) // This is the method defined above. Only thing changed there is I removed the `super` call
clearAuthenticationAttributes(request);
logger.info("Redirecting to Url: " + targetUrl);
getRedirectStrategy().sendRedirect(request, response, targetUrl);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With