Why do I get Unexpected viewExpiredException when authenticated? - jsf

I'm working on an application using WAS 7.0 and Richfaces 3.3.3.
When I was working without authentication, I had only ViewExpiredException as expected, after a timeout.
Now that I'm going thru Webseal, with LTPA cookie, to the same machine, I get ViewExpiredException during my first or second Ajax Calls, making my application useless.
Would somebody have an idea why I suddenly get those ViewExpiredException's "all the time" ?
Thanks in advance.

Related

Blank page response with successful form authentication on wildfly

I'm aware similar sounding questions have been asked in the past. But this issue is really annoying me and I'm not sure if it can be resolved easily.
In order to cope with a successful login when the JSESSIONID cookie was missing or had expired, the web.xml was configured to redirect to the home page on a 408 error. This was when running on JBoss 7.1.1.
The login page is standard j_security_check form based authentication with POST action etc.
We then migrated to Wildfly 8.2.1, where we found that the server simply replies with 200 OK and so a blank page would be presented, with the url ending in xxx/j_security_check .
. Not nice since the user had logged in successfully.
The correct response was still being presented when trying to login with invalid credentials.
I tried running on wildfly 10.1 as well but no difference.
I'm guessing it's caused by a "fix" with undertow which requires some additional handling, possibly in a web filter.
Has anyone else experienced this issue and managed to find a solution?

Why is my httpsession expiring?

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

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 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

ViewExpiredException after upgrade to jsf2

We recently upgraded a major platform from jsf 1.2 to 2.0. After upgrading we're getting several ViewExpiredException errors each hour. From reading up on the topic it seems that this is an expected exception when sessions expire, however we've reviewed the access logs and we are getting these exceptions even when requests are only 5 minutes apart in some cases.
My questions are as follows:
1) Other than session expiration, what other conditions might cause ViewExpiredException?
2) The exception we're logging doesn't contain much detail about the exact condition that is causing the exception (missing session, corrupt session, unable to restore a particular component). Is there a way to introduce additional logging to find out the very specific situation that is triggering this exception in each case?
Mojarra 2.0.4-b09
Tomcat 6
Using Memcached Session Manager for session replication
Any help is appreciated. Thanks!
Other than session expiration, what other conditions might cause ViewExpiredException?
The enduser has requested/created too much views within a session and is submitting to an old view. The default max views per session is 15. In other words, if the enduser opens 16 browser windows/tabs on a page with a form within the same session and submits to the first one, then the user can get ViewExpiredException.
The max views per session is configureable in web.xml by
<context-param>
<param-name>com.sun.faces.numberOfViewsInSession</param-name>
<param-value>15</param-value>
</context-param>
See also Mojarra FAQ for other parameters.
Is there a way to introduce additional logging to find out the very specific situation that is triggering this exception in each case?
Not through JSF and/or a ViewExpiredException. The whole exception just means that the view is not present in the session anymore. This can in turn indeed have more underlying causes. Logging the session creation and destroy using a HttpSessionListener and logging the session attribute modifications by HttpSessionAttributeListener may be helpful.
Update as per the comments, pressing the browser back button on a cached page containing a form and then submitting the form thereafter could indeed also cause ViewExpiredException when the view is been expired. This can be solved in following two ways, preferably in a combination of them:
Instruct the browser to not cache the pages.
Do not use POST forms for plain page-to-page navigation.
For more detail, see this answer.

Resources