11

I am using Spring Security and wondering how can I implement redirection after succesfull login to the source page if that page contains # (hash) sign.

Right now I use always-use-default-target="false" and it works fine on URL kind of: /path/to/page/.

But when the URL become to #/path/to/page it doesn't make any redirections.

Is there any way to fix it?

Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
nKognito
  • 6,297
  • 17
  • 77
  • 138

2 Answers2

13

Here is the solution I used at the end:

$(document).ready(function(){
  $('#auth-form').submit(function() {
    var el = $(this);
    var hash = window.location.hash;
    if (hash) el.prop('action', el.prop('action') + '#' + unescape(hash.substring(1)));
    return true;
  });
});

This snippet addes the hash to authorization form's action attribute and Spring redirect you to the URL of kind: #/path/to/page without any problem.

nKognito
  • 6,297
  • 17
  • 77
  • 138
  • 2
    This works great if using angular-js with a spring backend. Thanks! – Andrew Westberg - BCSH Jan 04 '14 at 19:15
  • Good idea! Use this if you don't want to use jQuery. `document.addEventListener("DOMContentLoaded", function() { var form = document.getElementById('auth-form'); var hash = window.location.hash; form.action = form.action + '#' + decodeURI(hash.substring(1)); });` – user1127860 Mar 29 '18 at 18:16
3

Maybe this is the old question, but during my recent research in this topic, I found that the problem is common and still exists (especially in case of modern AngularJS front-end apps with back-end security). I'd like to share my solution with you.

On the login page, e.g., /login.html, put following code before the </body> tag:

<script type="text/javascript">
    var hash = window.location.hash;
    document.cookie="hashPart=" + window.btoa(hash);
</script>

Note (1): btoa() function works in IE >= 10 (http://www.w3schools.com/jsref/met_win_btoa.asp), for older browsers use jQuery equivalent.

Note (2): The encryption of the # part of URL is necessary as it may contain special characters, which are not allowed to be stored in cookie value string.

From the server side you have to modify onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) method of class implementing AuthenticationSuccessHandler interface.

In my case, I simply extend the SavedRequestAwareAuthenticationSuccessHandler class and override the onAuthenticationSuccess method using its original code. Then I obtain the hashPart cookie value from the request, decode it and add to resolved redirect URL. My code fragment below:

@Override
public void onAuthenticationSuccess(HttpServletRequest request,
        HttpServletResponse response, Authentication authentication)
        throws ServletException, IOException {

    // ... copy/paste original implementation here, until ...

    // Use the DefaultSavedRequest URL
    String targetUrl = savedRequest.getRedirectUrl();

    for (Cookie cookie : req.getCookies()) {
        if (cookie.getName().equals("hashPart")) {
            targetUrl += new String(Base64Utils.decodeFromString(cookie.getValue()));
            cookie.setMaxAge(0); // clear cookie as no longer needed
            response.addCookie(cookie);
            break;
        }
    }

    getRedirectStrategy().sendRedirect(request, response, targetUrl);
}

Finally, just inject your success handler class to your Spring Security configuration, as described in: https://stackoverflow.com/a/21100458/3076403

I'm looking forward to your comments or other solutions to this problem.

Community
  • 1
  • 1
Thomas Weglinski
  • 1,094
  • 1
  • 10
  • 21