Would anyone please be able to shed light on the following:
When a web-application uses "j_security_check" , where does it store the name of the original page requested by the user (the one to which user should be redirected after a successful login ) ?
For example, assuming the following scenario:
0) A web application contains a page "secret.html", which is a protected resource, declared to require login. Assume mode is "Form Based Login".
1) User tries to access page "secret.html"
2) User is re-directed to "login.jsp", fills in "j_username" and "j_password", and submits them to "j_security_check".
3) "j_security_check" checks the user/password. If they are valid, it creates a "LoginContext", and then redirects the user to the originally-requested page ("secret.html").
At least that's my understanding of how it works...
The question: in step 3, how does "j_security_check" know which is the originally-requested page ("secret.html") ?
I had expected it to be sotred in the session context, or at least as a request attribute/parameter.
But a simple test I conducted (on Websphere), shows it's not there... I put a Filter before "j_security_check", and printed all session/request attributes, and all parameters, but saw no trace of the original page name.
Thanks a lot :)
Thanks very much :)
Simple, pragmatic answer: the web server does not store the original request in the session.
And besides, do you really care? Do you intend to do something with that data? I wouldn't recommend it, since what that data exactly is and how it's stored is container-dependant.
Cheers and happy coding,
Belated thanks for your reply.
Not surprisingly, the reason I need such data is to beacuse i'm trying to replace "j_security_check" with my own customized servlet.
Namely, i'd like to have form-based login, but while most login pages contain :
"< form action=j_security_check... >"
I'd like my login page to contain:
"< form action=mySerlvetUrl... >"
where "myServletUrl" would point to my own servlet, that would handle user validation, then redirect the user to the originally requested page (that's where I need it).
The reason I need such a crazy servlet is, of course, crazy requirements (that cannot be satisfied by simply replacing the user registry)... long story.
Thanks again :)
Actually j_security_check implementation is application
server specific. It's up to vendor how to implement the standard.
Regards this, could you please let us know which web container do you use?
I can give abit more information if it's Websphere:
I needed to do a bit of login customization for WAS.
Thank you in advance.
Hi, I've got a similar requirement and I'm using WAS.
Could you point me out to what you've learned about how j_security_check in WAS stores these information?
WAS Stores it in a cookie
Just a (belated) suggestion..... To achieve your custom login solution could you not use j_security_check in combination with a custom registry? The custom registry could implement your customised security requirements and then authenticate against any registry you want to use....
If you have to capture the user credentials including requested secure resource, the best thing would be write your own authentication mechanism.
For instance, all secure resources would include a checklogin function, which would check for existence of a user session object. If the object exists, the page would render according to user privileges contained in the object. Otherwise, the user is re-directed to a login page where this user session object is created. The redirection happens with a "fromResource" (or "fromContext" or "fromWherever"...) parameter...which solves the basic problem expressed in this thread. Specifically, this parameter will allow you to get back to original requested resource. To work across multiple contexts, container instances or platforms (with single sign on considerations etc), you would need to devise ways to persist this user session (object) and marshal/unmarshall it wherever/whenever needed.
If you insist on using j_security check (and also to centralize login accross various applications), couple of options come to mind:
1. Take the user to login page. Specifically, have the context login page response.redirect the user to the "real" login page. In this case, the scent of the origial page is indeed lost. Filtering for j_security_check would be somewhat of a hack. This thread documents some of all the gory details...(probably not for me...thanks).
2. Bring the login page (HTML) to the user...using a web scrape of a centralized login page. For tips on screen scraping see "USING HTTPURLCONNECTION TO ACCESS WEB PAGES" in Sun Core Java Technologies Tech Tips for February 10, 2004 (http://java.sun.com/developer/JDCTechTips/2004/tt0210.html#2
). Of course, you would need to deliver the login page with fully qualified links such as “forgot password”, etc. An advantage is that applications can “customize” the login page any way they want…which means the login page must ideally be really simple. In fact, just the j_security_check form is all it needs to be delivered. While the servlet specification seems to be silent on what to do after validation using j_security_check, containers like Tomcat have taken the liberty to interpret it as any reasonable user would i.e. go to the requested secure resource directly after a valid login. Exactly how that happens is somewhat of a mystery...and is probably intended that way so people don’t mess around with it too much. However, if we bring the login page HTML code to the user, then user would authenticate just as if that page was residing within the context from which it was requested. Please note that this is still dramatically different from actually including a login.jsp within every application…(I hope that is obvious…).
First of all, there is a third-party implementation for j_security_check called SecurityFilter (www.securityfilter.org). It mimics container managed security but allows form-based authentication. It is implemented as a filter.
Our particular circumstance required us to find a way to forward the user to a desired destination URL once credentials were verified. However, the j_security_check implementation simply sends a redirect to the URL specified in the securityfilter.xml file without passing any parameters through. SecurityFilter, as it should, clears all session attributes but this causes a problem because if you set a session attribute after SecurityFilter returns from chain.doFilter(), SecurityFilter has already sent a redirect to the browser and you may or may not get the session attribute set fast enough for the browser to see it.
Our solution was to write our own filter that sits above SecurityFilter in the filter chain. We also subclassed HttpServletResponse (actually you have to subclass HttpServletResponseWrapper because HttpServletResponse is an interface) so that we could intercept the sendRedirect() call made by SecurityFilter. After we call chan.doFilter() (which executes SecurityFilter) we then set up a session attribute with the data we want to pass, and then we send the actual redirect ourselves. We wanted to ensure that we set the session attribute prior to any redirect being sent to the browser so that a "race" condition is avoided where the browser might attempt to access the page it is being redirected to before the session attribute is set.
Do we have any answer for this?
we were facing some similiar issues... we did a lookup for the following parameter (javax.servlet.forward.request_uri) in the request... and we got our originally requested page...now what happens, when tomcat encounters a secure url... it takes that request away from the current session ( this will give you a new .... yes life is made up of that... SESSION with a new SESSIONID...) and will serve whatever login form you have given for your ... (we had a springcontroller doing that for us...smarts...) .... and on your login controller you can get this parameter ( mind this is only a servlet spec 2.4 thingy and will only happen for requests which are forwarded and since tomcat while doing a j_security_check forwards and websphere redirects... cooked like a crooked crack...).... and our test, prods and devs are websphere....but local machines are tomcats...just for some other bum like me doling around for a similiar answer for websphere in a similiar scenario websphere is sending you cookies for that ( wasrequrl is the name of your cookie)... the smart thing to do again is to create a cookie at your loginpagecontroller named wasrequrl (just for tomcat...detect tomcat somehow...maybe this cookie being null is one of the way...)... so.... we are finally out of our messs....
How did you called a filter before j_security_check.
It is not possible in tomcat.
Tomcat stores forward page info in session only.
You can see that if you check code source of FormAuthenticator.java