3

Ok, so I've got an interesting case of login page redirection going on.
My webservice has a login page (login.html) with some javascript to handle logging in and redirecting to a hardcoded 'default' page. The webservice is written in Java with a servlet filter handling redirection if a user is unauthenticated (so if a user tries to access domain/statistics without being logged in, they are directed to domain/login.html). The redirection from the protected services works: I can redirect to the login page and once a user is authenticated, redirect them to a default page. I am having issues, however, redirecting to the previous page.
I know this is usually handled with the argument document.referrer in the Javascript, which I have tried, but due to the Java's redirection with response.sendRedirect, the Referer header is not sent.

How can I get these two aspects to redirect to the previously called page? Is it something I need to add on the Javascript side, the Java side, or both?

ZKSteffel
  • 1,115
  • 5
  • 13
  • 22
  • 2
    there is no way you can rely on document.referrer. It can be faked, empty (if coming from a bookmark) and so on – mplungjan Jun 20 '11 at 14:06
  • Well, we've got a case for the empty header (hence a default redirect), and will be implementing a sort of 'whitelist' in order to keep traffic on our site, avoiding redirects to malicious websites, etc. I know it's a security concern, but we're handling that as best as we can. I'd like more recommendations, though, than just telling me "you can't do that". – ZKSteffel Jun 20 '11 at 14:09
  • you *can* do it, but you should definitely not use the referrer. You don't have to - your server knows the *actual* URL for sure anyway. – Pointy Jun 20 '11 at 14:24

2 Answers2

0

What I've done is to drop the original (redirected) URL into a hidden input field on the login form. The code that does the authentication should just check that parameter, and if it's not empty it can redirect after establishing the session.

You have to be careful doing this to prevent XSS attacks etc., but it's not that hard and it works just fine.

In my framework (Stripes), I can push the original URL (taken from the HttpServletRequest object, a combination of the servlet path, the "path info", and the query string) into a special holding box that will cause the framework to give it back to me on the next request as a parameter. Without that, the simple thing to do is add the URL as a parameter when you redirect. Just URL-encode the original attempted URL and tack it onto the redirect URL with some parameter name. Then, on your login page, you just check for it:

    <c:if test='${not empty param.attemptedUrl}'>
      <input type='hidden' name='attemptedUrl' value='${fn:escapeXml(param.attemptedUrl)}'>
    </c:if>

Then your login action will get that parameter too when the login form is submitted, and it can act on it as appropriate.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • I can understand the concept of this, but not so much the application. I can't seem to keep the referred URL in the header to consume in the javascript. I've tried just popping up an alert with `document.referrer`, and I get either a null or undefined (depending upon how I spell 'referrer'). – ZKSteffel Jun 20 '11 at 14:13
  • Do not use "document.referrer". It is absolutely not reliable. – Pointy Jun 20 '11 at 14:17
  • I'm not using Stripes, though... The problem is more server side than anything. When I use Java's HttpServletResponse.sendRedirect, any headers get stripped. I can add as many headers as I want, but as soon as that call goes through, they're gone. I'd be fine using some other alternative, but not if I have to change to a different framework. – ZKSteffel Jun 20 '11 at 14:29
  • If you're not using Stripes, just add the original URL as a parameter to the URL you pass to "sendRedirect()". – Pointy Jun 20 '11 at 14:35
  • I've got a lot of parameters I need to add as well, so I'm afraid this won't be a viable option... – ZKSteffel Jun 20 '11 at 14:42
  • What? Unless you're adding a huge amount of stuff to the original URL, it really shouldn't be a problem. I've used that approach in the past and it works fine. URLs can be very large, at least 10KB or so. – Pointy Jun 20 '11 at 14:43
  • Dang, that's a long URL. I thought the limit was a lot shorter, like somewhere around 250 characters or so. I guess I can put that option back on the table. – ZKSteffel Jun 20 '11 at 14:56
  • Whoa wait asec; sorry I think I was wrong. (I don't know what I was thinking about; there's a 10K limit on *something* out there :-) Anyway [here](http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url) is an older Stackoverflow question about URL length, and that sets the limit at something considerably shorter (about 2K). I'm very sorry about the bad information! – Pointy Jun 20 '11 at 15:18
  • Ah, that's alright. Turns out our project description has changed anyway, and I don't have to implement the redirect anymore (it'll just throw a 401 if a user isn't authenticated instead of redirecting to the login page). So thanks for the assistance up to this point. – ZKSteffel Jun 20 '11 at 15:50
0

Send Redirect will ask to the client to repeat the request to the resource you choose. Have you think of Spring Security with minimal configuration you can achieve this quite easily.

Take a look at this:

http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html

ssedano
  • 8,322
  • 9
  • 60
  • 98
  • Spring Security... easy...? We tried to implement Spring Security in the project before... we spent about two days trying to update dependencies in Maven and still couldn't get it to work. We wrote our own security faster... – ZKSteffel Jun 20 '11 at 15:53
  • Using maven central repo, for a basic set up you only need one dependency (the rest comes as transitives). That looks more as a maven misconfigurationi thou. Just giving my 2 cents trying to help. – ssedano Jun 21 '11 at 07:30