How to obtain the Session Id in a Login Module while using JBoss AS

Sometimes the SessionId or the entire HttpSession is needed in the JAAS Login Module or somewhere else.
After searching the Internet I found two
useful Classes at JBoss:

HttpServletRequestLoginModule and
HttpServletRequestCallback

I simply tried to get the getHttpServletRequest() method
working:

protected HttpServletRequest getHttpServletRequest()
throws PolicyContextException
{
   return (HttpServletRequest)
   PolicyContext.getContext("javax.servlet.http.HttpServletRequest");
}

with this method you can obtain the session:
getHttpServletRequest().getSession()

The only thing to do, is to add
javax.servlet.jar and jboss-j2ee.jar to the classpath and add the getHttpServletRequest()
to your own Login Module. Thats all, somethimes the world is easy…

HowTo renew the Session id in Tomcat or JBoss after a login

…or: HowTo prevent a session fixation attack. Most Security Papers (eg. the Security White Paper of the BSI ) suggest to renew the given Session id after a successful login. To archive this goal, you need to create a Valve which manipulates the session. According to the BSI paper there a four steps to renew the session id:

  • store the old session
  • invalidate the old session
  • generate a new session
  • copy the data of the old session into the new session

A valve is a special filter that operate outside of a web application. It intercepts all requests before they are subsequently processed. You can find out more about valves at the Tomcat documentation.

And here is the code for the valve:

public class RenewSessionValve implements Valve{


 public void invoke(Request request, Response response)
    throws IOException, ServletException {
 	// check for the login URI, only after a login
	// we want to renew the session
	if (req.getRequestURI().
		contains("/portal/j_security_check")) {
 	  // step 1: save old session
	  Session oldSession = req.getSessionInternal(true);
	  SavedRequest saved = (SavedRequest) oldSession.
				getNote(Constants.FORM_REQUEST_NOTE);

	  // step 2: invalidate old session
	  req.getSession(true).invalidate();
	  req.setRequestedSessionId(null);
	  req.clearCookies();

	  // step 3: create a new session and set it to the request
	  Session newSession = req.getSessionInternal(true);
	  req.setRequestedSessionId(newSession.getId());
	  // step 4: copy data pointer from the old session
	  // to the new one
	  if (saved != null) {
	    newSession.setNote(Constants.FORM_REQUEST_NOTE, saved);
	  }
	}
 }
}

To make the Valve work, you need to declare it in the server.xml.

The reason why the session id is not renewed if you call request.getSessionInternal(true)
is because of the way how the catalina request class creates a new session.
If the old session id was stored in a cookie it creates a new session
using the old session id:

if (connector.getEmptySessionPath() && isRequestedSessionIdFromCookie()) {
            session = manager.createSession(getRequestedSessionId()); 
        }

The only way to prevent this is to call
request.RequestedSessionId(null) befor calling req.getSessionInternal(true)
This causes a manager.createSession(null) call in the request.doGetSession(), which generates a new session ID.
The JBoss Web 2.1.3 (which is a pimped Tomcat 6.0) has fixed this problem.

I would like to thank Thomas Schmidt who
developed this solution with me.