Why is my httpsession expiring? - jsf

I'm pretty new to JSF and I ran into an interesting problem. I have a web application, with a session timeout specified and even if I make actions, the session expires. As far as I know, every new request restarts the timeout counter, well it is not happening. Also, during development I noticed, that after timeout (redirected to the login page), if I reload the page, the session is still valid. Same session Id, counter still going... I have no idea what is wrong, I am using Glassfish and PrimeFaces.
I googled a lot, even tried to catch the ViewExpiredException, but with no luck. The redirection is done using the
<meta http-equiv="refresh" content="#{session.maxInactiveInterval};url=login.jsf?reason=expired>
method. Maybe I am missing something obvious in the web.xml, I am out of ideas.
Please give me some advice on this, thank you very much!

The approach you are using is not the best fit for implementing session timeout, The reason is meta tag will refresh the page on a specific interval, and in your case it redirects to another url on refresh,
i.e., if value of session.maxInactiveInterval is 5, the page will be refreshed in 5 seconds and redirects to login.jsf?reason=expired, regardless of the actions you make. only page refresh will reset the counter.
Learn more about meta tags here
If you want to implement idle monitor, i suggest you to have a look at <p:idleMonitor> at Primefaces showcase - IdleMonitor

Related

Reload page from backBean

How can I do to reload the JSF page after the session expire?
I have a filter, when the session expires, it executes this code:
res.sendRedirect("/index.xhtml");
But when I use a component when ajax, and the session is expired, nothing happens. So, think about taking a reload always after this line, but do not know how to do.
My idea is to put a line of reload when the session expires. Anyone know if it is possible to do this, or other better idea?
See BalusC's answer here: https://stackoverflow.com/a/3642969/1453701
Especially the following section: Handling ViewExpiredException

j_security_check not redirecting to welcome page - successful login event listener?

For ages I've been puzzled about why after login I sometimes don't directed to the application welcome page. I've finally figured it out (years after everyone else):
I login successfully via j_security_check and go to the welcome page
wait for session timeout
click on h:link which sends a GET request
because it's a GET and not a POST my custom ViewExpiredException
handler doesn't kick in
container security redirects to the login page because the session
has timed out. Because of the session timeout+container security the
get request (from h:link) isn't seen by the application, in either a phase listener
or filter.
I successfully login again
j_security_check redirects me to the page which triggered the
authentication, in this case the target of the GET request.
The last bit I'd not understood, I assumed it would always go to the welcome page.
My problem is that my current design requires that after login I always show the welcome page. The welcome page has a preRenderView event which sets up some context information in a session scoped bean after login and increments a few counters etc...
This context information is required by backing bean code for other pages, and presently if I don't go through the welcome page first there'll be an exception.
In terms of fixing it I've looked at the following options:
Ideally there'd be an #PostLogin method that could be called, which would cleanly solve all my problems. I use JSF (Mojarra) with Myfaces CODI but I don't see anything which does what I want.
I could add some more code to my filter, but I need to persist some data (i.e. login count), it doesn't look like a nice option. Maybe I'm wrong.
I make all the preRenderView methods of potential targets of j_security_check (pages called with GET) handle the case where they are called directly from j_seecurity_check. I can see this being what I have to do but it seems like a lot of hassle.
Write a Server Authentication Module for glassfish to override j_security_check behavior.
How is this normally handled? I've started hitting this problem after moving to GETs for simple navigation cases after years of abusing POSTs, and the custom exception handler doesn't work. If anyone has any guidance on this issue I'd appreciate it, at least I know what's going on now. Hopefully I've missed something obvious!
Thanks
O/S
Ideally there'd be an #PostLogin method that could be called, which would cleanly solve all my problems. I use JSF (Mojarra) with Myfaces CODI but I don't see anything which does what I want.
There is indeed no such thing.
I could add some more code to my filter, but I need to persist some data (i.e. login count), it doesn't look like a nice option. Maybe I'm wrong.
That would indeed be the "easiest" way. Basically:
UserPrincipal user = request.getUserPrincipal();
HttpSession session = request.getSession();
if (user != null && session.getAttribute("user") == null) {
session.setAttribute("user", user);
// First-time login. You can do your intercepting thing here.
response.sendRedirect(request.getContextPath() + "/welcome.xhtml");
}
I make all the preRenderView methods of potential targets of j_security_check (pages called with GET) handle the case where they are called directly from j_seecurity_check. I can see this being what I have to do but it seems like a lot of hassle.
That's not DRY.
Write a Server Authentication Module for glassfish to override j_security_check behavior.
Can't answer that as I've never done that.

JSF - set STATE_SAVING_METHOD per-page

I would like to set a particular page (one that does not require a user to sign in to use) to have a STATE_SAVING_METHOD of client rather than server while the rest of the pages use server. Is there a way to set it on a per-page basis?
I would like to do this to get around the dreaded ViewExpiredException.
There is no way. This is however been requested as new feature. See also JSF spec issue 1056.
To solve the particular ViewExpiredException issue, you need to look for alternative ways. You can just ask a new question here about specifically the issue you have. There are always ways to go around it.
The state saving method is set once in web.xml and is there for the whole app. If you don't want that particular view to expire you could do an ajax poll that "pings" the page in a specific interval of time and thus avoiding view expired exception. Kinda workaround but this is the way with stateful frameworks.

JSF authentication logout

I know that this question seems to be answered by a lot of other threads, but I can't find a solution with JSF 2.0 with Glassfish 3.0.1 for logout an user.
I tried either with a BASIC authentication and FORM authentication using j_security_check as action.
But for the logout method I can't find any of them that works.
I tried using a servlet with session.invalidate(), i used a managed bean tring to invalide the session, but nothing happened. I also tried with j_security_logout without success.
Does someone know what I can do for logout an user?
Calling session.invalidate() should work.
Your problem is probably that you used the browser back button to view a restricted page to test if logout really succeeded, but that page was actually served from the browser cache instead of straight from the webserver over a real HTTP connection.
In that case, you need to instruct the webbrowser to not cache the restricted pages. This way the browser will always request the page straight from the webserver. You can do this with help of a Filter. You can find an example in this question: Prevent user from seeing previously visited secured page after logout

Session timeout and re-direction on login

On session timeout we re-direct to the login page and if the user logs back into the portal he gets re-directed to the page he was trying to navigate in the first place.
In our case, the re-directed page tries to fetch values from the session and it fails badly with exceptions and it works just fine when there is no dependency on pages which don't have any dependency on session variables.
What is the best way to handle the situation? Can we just redirect this to the home page instead, if so how to do this?
It depends on how much information you are storing in the session, as a guideline, you should always the "shortest" scope ever.
Probably your best option is to allow redirect only on stateless pages, so that it won't give you any problem about inconsistent state.
As for your last problem, take a look at this: redirecting-on-session-timeout-in-jsf-richfaces-facelet. Just set the tag to whatever you want.

Resources