1

I have a servlet filter to force user authentication. It checks for the existence of a non-null object in the HttpSession. For some reason that I cannot figure out, the session contains an object with the correct name, but HttpSession.getAttribute is returning as null. Here is the process that it goes through.

from the login page, it calls an action which contains the following user validation code. At this point I am 100 percent sure the object "login" is not null.

if (passWordIsValid) {
   HttpSession session = getCurrentFacesSession();
   session.setAttribute("loginBean", login);
return "welcome";
} else {
   // error handling here 
}

The outcome 'Welcome' goes to a facelet page with the following code in it:

<h:outputText value="Welcome #{sessionScope.loginBean.email}"/>

This code does successfully show the email address, thus confirming that there is a loginBean object in session scope, and its not null. A command link on that welcome page submits a request to a different view. When the servlet filter intercepts the request, it does the following:

HttpSession session = ((HttpServletRequest) servletRequest).getSession();
Object beanObj = session.getAttribute("loginBean");
if (beanObj!=null) {
   chain.doFilter(servletRequest,servletResponse);
} else {
   // code to send back to login page
}

Its ALWAYS sending the user back to the login page, because the beanObj is always coming back null. This is a mystery I cannot seem to solve. Any suggestions?

EDITED For further debugging I added logging code into the servlet filter to dump the attributes in the session:

for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements();) {
    log("Found Session attribute="+e.nextElement());
}

The output confirms that there IS an attribute named "loginBean" in the session! This is maddening...

EDITED

In case of invisible characters, I completely retyped the name of the bean, and then did a full clean/republish to make sure I was getting the newest code.

HttpSession session = ((HttpServletRequest) servletRequest).getSession();
String s = "loginBean";
Object beanObj = session.getAttribute(s);
if (beanObj!=null) {
   chain.doFilter(servletRequest,servletResponse);
} else {
   // code to send back to login page
}

Same behavior...

debugging

I registered an HttpSessionAttributeListener. The output confirms that the bean was added into the session. There are no subsequent instances of that bean getting replaced or removed from the session. I'm not sure how to proceed with using a debugger, especially on something as complex as this (an entire web container running in the JVM.)

tcprogrammer
  • 113
  • 1
  • 2
  • 13
  • Code posted so far looks okay. Are you 100% sure that you're running the code you think you're running? Isn't there some old code still running in server's memory where you typo'ed the attribute name, for example? Clean, rebuild, redeploy, restart, etc. If still the same problem, please track the `JSESSIONID` cookie in the HTTP traffic and see if it's as per the expectation. – BalusC Mar 22 '12 at 03:21
  • That is a good idea, and it was the first thing I tried. I put in logging code to dump the session id, and then compared it to the session id that gets put into the URL by JSF and they match exactly. – tcprogrammer Mar 22 '12 at 03:32
  • Well, the only explanation can be that the `login` instance is by itself `null` when you did `session.setAttribute("loginBean", login)`. But you said youself that it's for sure not `null`... Are you 100% certain? – BalusC Mar 22 '12 at 03:49
  • If it was null when I put the attribute in there, how would the next view (the welcome page) be able to display one of the properties? – tcprogrammer Mar 22 '12 at 03:57
  • Oh, I overlooked that :) Well, apparently there's some invisible character in the attribute name, e.g. a joiner character (like as used in Arabic and CJK). I'd suggest to remove the entire attribute name string and re-enter it carefully once again in the filter. – BalusC Mar 22 '12 at 04:02
  • That doesn't seem to be it either. This is just plain crazy ... – tcprogrammer Mar 22 '12 at 04:15
  • You could try implementing and registering a [`HttpSessionAttributeListener`](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionAttributeListener.html) so that you can track adding/removing/replacing of all session attributes. You could use `Thread.dumpStack()` (or the debugger ;) ) to examine who/what is doing that. – BalusC Mar 22 '12 at 04:20
  • may i ask what is the login Object that you stated here : session.setAttribute("loginBean", login); ? – Li3ro Aug 29 '12 at 08:39

1 Answers1

0

Ok, I feel dumb now. It was a mistake in the servlet filter code; two actually. The first was I was missing a 'return' statement after one of the doFilter(request,response) method calls. The second was that JSESSIONID was getting appended to the URL and I didn't account for this in the code that always permits the login page. Well, actually I tried to account for it but I did it incorrectly. I had written it as if JSESSIONID was a query parameter, like this ?JSESSIONID=blah when in actuality it is not a query parameter, it uses a semicolon like this: ;JSESSIONID=blah.

The combination of these bugs made it look like the servlet filter was not able to locate the object in session; but what was actually happening was that log message was from the PREVIOUS request -- it never got as far as checking the session on subsequent requests when the bean was actually there. Whoops! For those who have this problem in the future, I'll tell you how I figured it out: I removed all code from the servlet filter that did forwarding or redirect and put a single doFilter() at the bottom, and then put logging statements to see the value. It was then immediately apparent what was happening. The HttpSessionAttributeListener was helpful as well.

tcprogrammer
  • 113
  • 1
  • 2
  • 13