Basically the problem is that even for ajax requests, when navigating from another Spring URL, SavedRequestAwareAuthenticationSuccessHandler is redirected to the full page. You can see this in your browser debugging tool, but you cannot bypass / prevent redirection due to the operation of ajax requests (transparent redirects).
There may be a better way, but the following works. Redirecting to ajax requests changes as follows:
Put this class in / groovy source code
class AjaxSuccessAwareRedirectStragegy extends DefaultRedirectStrategy { private String _ajaxSuccessUrl; public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException { if (SpringSecurityUtils.isAjax(request)) { if (url != _ajaxSuccessUrl) { url = _ajaxSuccessUrl + "?targetUrl=" + URLEncoder.encode(url, 'UTF-8') } super.sendRedirect(request, response, url) } else { super.sendRedirect(request, response, url) } } public void setAjaxSuccessUrl(final String ajaxSuccessUrl) { _ajaxSuccessUrl = ajaxSuccessUrl; } }
This special redirection strategy will be used in * AuthenticationSuccessHandler. To register it, enter this configuration in .groovy resources (AjaxSuccessAwareRedirectStragegy is the one that is suitable specifically for this use case)
beans = { def conf = SpringSecurityUtils.securityConfig authenticationSuccessHandler(AjaxAwareAuthenticationSuccessHandler) { //borrowed from DefaultSecurityConfig.groovy requestCache = ref('requestCache') defaultTargetUrl = conf.successHandler.defaultTargetUrl // '/' alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault // false targetUrlParameter = conf.successHandler.targetUrlParameter // 'spring-security-redirect' ajaxSuccessUrl = conf.successHandler.ajaxSuccessUrl // '/login/ajaxSuccess' useReferer = conf.successHandler.useReferer // false redirectStrategy = ref('ajaxSuccessAwareRedirectStrategy') } ajaxSuccessAwareRedirectStrategy(AjaxSuccessAwareRedirectStragegy) { contextRelative = conf.redirectStrategy.contextRelative ajaxSuccessUrl = conf.successHandler.ajaxSuccessUrl } }
And voila, in your LoginController you can change the ajaxSuccess action to use targetUrl, which in turn can be used in your Javascript to login
def ajaxSuccess = { def redirect = params.targetUrl println "LoginControllerAjaxAuthParams " + params render([success: true, username: springSecurityService.authentication.name] << (redirect ? [redirect: redirect] : [:]) as JSON) }
source share