I use Spring Security to deal with session timeout. My application also uses AngularJs.
I have the following issue:
If the session times out and a user issues a non-ajax request from an angularJs page to a secured url, Spring Security redirects me to the login url but keeps the part of the Url after the # (hash) sign.
Let me illustrate:
- A user is located at /myapp/foo#!/bar
- Session times out
- User issues get request to secured url
- User is redirected to /myapp/signin#!/bar
How can I avoid the #!/bar part from being added to signin page?
Edit: There is a slight mistake in the description above. The problematic use case is as follows:
- A user is not logged in and tries and access a protected resource such as:
localhost:8080/bignibou/curriculum/#/view/1(by pasting this url in browser's address bar for instance).
- They will automatically be redirected to the following Url:
Notice the part including and after the hash sign is kept. Note that this has more to do with AngularJs than Spring Security as Spring Security does not include the hash sign (this is confirmed by the fact that the hash never appears in the network tab of chrome dev tools...)
Rather than Angular, this sounds like the intended behavior for hash fragments on HTTP/3xx redirects, as implemented by most modern browsers (and IE9 onwards, I believe). There is a detailed explanation on the nuances here:
and the official documentation is here:
In order to modify (or, in this case, remove) the fragment, you can leverage HTML5's history state. Try adding this to your signin page:
history.replaceState("", document.title, window.location.pathname + window.location.search)
For further information on the replaceState, it's pretty well documented at Adding and modifying history entries in the Mozilla developer docs.
The obvious caveat here, is what versions of IE you need it to work in. From a quick google, it seems like you are looking at IE10 onwards, so for earlier versions, you would therefore need something more rudimentary like:
window.location.hash = ""
which will remove the fragment but retain the
#, but hey, it's IE.
As a composite solution, therefore, you could use:
if("replaceState" in history) // proper browsers history.replaceState("", document.title, window.location.pathname + window.location.search) else // fallback for ie window.location.hash = ""
This recipe can be found in it's original form on Stack Over Flow.