PDA

View Full Version : Ext with J2EE: Session timeout



Condor
29 Jun 2009, 5:49 AM
I am using a J2EE server for our Ext JS client application (and according to the poll about 30% of you are also using J2EE).

When the session times out on the server the next XmlHttpRequest will return a 401 Unauthorized, which Firefox responds to by showing a BASIC login dialog.
Obviously, I don't want a BASIC login dialog, but simply a 401 status code that I can handle in the requestexception event.

I finally worked around the problem by changing the 401 status code to code 403, but this seems too much of a hack.

Does anybody have a better solution?

Animal
29 Jun 2009, 5:59 AM
I use a parallel timer in the browser which is reset on every Ajax request.

It uses class-level Observability on Ext.data.Connection, and times the browser session out with a graceful logout at (hopefully) exactly the same time that the server session times out.

Condor
29 Jun 2009, 6:50 AM
That would probably provide a better user experience (let's see if my co-workers agree to this solution).

However, I'm not really satisfied with the "hopefully" in your sentence.

Do you have any extra code to handle 401 responses (e.g. in case the server was restarted).

Animal
29 Jun 2009, 6:58 AM
I have my login page add a special HTTP header which all Ajax responses are checked for.

If that header is seen, the session timeout is handled.

Animal
29 Jun 2009, 7:02 AM
It's as simple as this:



AU.startTimeout = function(conn, xhr, options) {
clearTimeout(AU.sessionTimeoutTimer);
if (xhr && xhr.getResponseHeader && xhr.getResponseHeader['Asp-Login']) {
sessionTimeout();
return;
}
AU.sessionTimeoutTimer = setTimeout(sessionTimeout, AC.sessionTimeout * 1000);
};
AU.initializeSession = function() {
// Reset the session timeout timer on every Ajax return
AU.startTimeout();
Ext.util.Observable.observeClass(Ext.data.Connection);
Ext.data.Connection.on('requestcomplete', AU.startTimeout);
}


(Where AU is our namespace)

Condor
29 Jun 2009, 7:03 AM
Do you mean you add the login details to the header or are you simply 'marking' XmlHttpRequests?

If it is the latter, HOW are you handling the request on the server to avoid 401 login dialogs?

In my case it's the application server (IBM WebSphere) that generates the 401 response and I can't seem to avoid this (only 'rebrand' it as a 403 response).

ps. That is old code. In Ext 3.0 it would be xhr.getResponseHeader('Asp-Login').

Animal
29 Jun 2009, 7:04 AM
My login JSP just adds the header to the response.

Condor
29 Jun 2009, 7:07 AM
Looking at your code you somehow got your server to return a 'Asp-Login' header instead of a 401 error on session timeout.

How did you do that?

Animal
29 Jun 2009, 7:11 AM
We have our own servlet filter which checks logged in status, and if a request arrives for which there is no session, it internally redirects to the login page.

But doesn't form based security always do that?

Condor
29 Jun 2009, 7:19 AM
Ah, and you add the header to the login page! Now I get it.

The only problem with that is that IMHO an XmlHttpRequest shouldn't be redirected to a login page. It should respond with a proper JSON (in my case) error message and HTTP error code.

That way it is also usable as a business interface and not only as a host for the Ext client application.

chaos
29 Jun 2009, 8:10 AM
We have our own servlet filter which checks logged in status, and if a request arrives for which there is no session, it internally redirects to the login page.


We also have a filter which check logged status, but intestead redirects to login page, it return a json (so no http error code) with an error code setted (in this case session timeout error).
All the ext remote stores have been extended to intercept these error codes and execute an appropriate action.

ciao
-Mario

Condor
29 Jun 2009, 9:41 AM
All the ext remote stores have been extended to intercept these error codes and execute an appropriate action.

You don't need to extend all stores for that. You can simply observe the entire connection class (as Animal already demonstrated):

Ext.util.Observable.observeClass(Ext.data.Connection);
Ext.data.Connection.on('requestcomplete', handler);

tjstuart
29 Jun 2009, 3:24 PM
We approach this somewhat differently. Periodically (say every five minutes) the web browser polls our JEE application and asks "are there are any messages for the user?". Amongst other things, the browser may receive a "logoff" message at which time the logout process is started (with an overridable warning countdown). Typically, the "logoff" message is sent when the back-office decides that this user has not performed any significant action over a configurable period.

This polling not only keeps the session "alive" but also allows us to easily notify the user of other important administrative messages etc.

chaos
29 Jun 2009, 10:46 PM
@condor: yeah, you are right.

@tjstuart: well, it depends on which kind of application you are developing, usually I avoid polling because with lots of user logged it generate too much traffic.

ciao
-mario

robertoroberto
29 Jun 2009, 11:23 PM
Hi
Are you using Basic or Form Authentication method (in the web.xml) ?

If you will use the Form Auth Method, you will recieve an HTML Page, so you can parse it (i'm parsing the return content type) and display it in your Ext JS panel.

the user will insert again user & psw and the submit MUST be to the j_security_check

Of couse if you have datas in HTTP Session.... all datas are lost... and so maybe your request will not works anymore


Bye

Condor
30 Jun 2009, 12:00 AM
I was using:

<login-config>
<auth-method>UNSPECIFIED</auth-method>
</login-config>
(because I don't think FORM authentication belongs in a JSON service)

But it seems that FORM is indeed the only authentication method that will work in Firefox without showing a login window.

robertoroberto
30 Jun 2009, 12:21 AM
Auth Method UNSPECIFIED is not a standard J2EE method.

FORM authentication only use your own html/jsp/other... as login and error login page.
What it return.... is what you want. You can also return a JSON.. but in this case who manage it the first time ?
The only mandatory behaviour is to submit data to "j_security_check" and form field MUST be "j_username" and "j_password)

You can get a look here : http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security5.html

I can tell you my experience....
I'm using it. It return an HTML page.
So I haven't any problem the first time (when the user access my ERP application).
If session expired and so my Ajax Request returns an HTML page instead of a JSON page, I render it in a panel directly (I'm developing it again.. I'm waiting the final release of ExtJS 3.0)... my final solution will be to render it in an IFRAME