I'm maintaining a Java web application.
Looking into the login code it gets an HttpSession out of HttpServletRequest via the getSession() method of HttpServletRequest. (It uses some values in the session for authentication purposes)
However I'm worried about session fixation attacks so after I have used the initial session I want to either start a new session or change the session id. Is this possible?
The Servlet 3.0 API doesn't allow you to change the session id on an existing session. Typically, to protect against session fixation, you'll want to just create a new one and invalidate the old one as well.
You can invalidate a session like this
request.getSession(false).invalidate();
and then create a new session with
getSession(true) (getSession() should work too)
Obviously, if you have an data in the session that you want to persist, you'll need to copy it from the first session to the second session.
Note, for session fixation protection, it's commonly considered okay to just do this on the authentication request. But a higher level of security involves a tossing the old session and making a new session for each and every request.
Since Java EE 7 and Servlet API 3.1 (Tomcat 8) you can use HttpServletRequest.changeSessionId() to achieve such behaviour. There is also a listener HttpSessionIdListener which will be invoked after each change.
Related
Can someone give me insight of how do I implement session management in Dropwizard 0.8.x or above. I was using Dropwizard 0.7.0 till now and working perfectly in it. But I really confused by change docs provided when I migrated to 0.8.x.
In Dropwizard 0.7.0 (which I was using previously) it was done like the following
/*MainApplication.class session handler */
environment.jersey().register(HttpSessionProvider.class);
environment.servlets().setSessionHandler(new SessionHandler());
/*Resource.class session check*/
HttpSession session = httpServletRequest.getSession(true);
But it does not seems working anymore, precisely saying HttpSessionProvider.class is not there and replaced by some other implementations.
It would be really helpful someone show to what this is changed to.
Thanks.
The reason this isn't working for you is because you need to set the cookie in the response. I noticed this while looking into enabling session state for a dropwizard application where the underlying cookie gets created on the Jetty Response object but it never makes it's way onto the Jersey Response object and therefor gets dropped.
What I've done to work around this issue is to implement a Filter that extracts the "Set-Cookie" information from Jetty and puts it onto the outbound response object.
String cookie = HttpConnection.
getCurrentConnection()
.getHttpChannel()
.getResponse()
.getHttpFields().get(HttpHeader.SET_COOKIE.asString());
if (LOG.isDebugEnabled()) {
LOG.debug("Adding session cookie to response for subsequent requests {}", cookie);
}
httpServletResponse.addHeader(HttpHeader.SET_COOKIE.asString(), cookie);
#Yashwanth Krishnan
I know this is old but I noticed that the session was not maintained from one URL to another, simply add this code when you init the application, session handling is mostly a container thing and not specific to DropWizard.
SessionHandler sessionHandler = new SessionHandler();
sessionHandler.getSessionManager().setMaxInactiveInterval(SOME_NUMBER);
/**
* By default the session manager tracks sessions by URL and Cookies, we
* want to track by cookies only since
* we are doing a validation on all the app not URL by URL.
*/
sessionHandler.getSessionManager().setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
environment.servlets().setSessionHandler(sessionHandler);
This question already has answers here:
How do servlets work? Instantiation, sessions, shared variables and multithreading
(8 answers)
Closed 7 years ago.
This is a pretty remedial question. I have not used the HttpSession class before. I am reading this tutorial, and I see that the session is a property of the HttpServletRequest.
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
// get current session, or initialise one if none
HttpSession sess = req.getSession(true);
}
My question is, how does the session get stored? On the client? In the past I have been accustomed to storing the session server / database side. How does this work? If I update the session on a given request, will that always be reflected through subsequent calls? Is the session stored on the client?
how does the session get stored? On the client? In the past I have
been accustomed to storing the session server / database side. How
does this work?
A session can be defined as a server-side storage of information that is desired to persist throughout the user's interaction with the web site or web application.
Is the session stored on the client?
Instead of storing large and constantly changing information via cookies in the user's browser, only a unique identifier is stored on the client side (called a "session id"). This session id is passed to the web server every time the browser makes an HTTP request (ie a page link or AJAX request). The web application pairs this session id with it's internal database and retrieves the stored variables for use by the requested page.
when ever getSession() method is called it returns session if exists else it create a new session.apart from creating a session it does 5 things which you wont do.
You don’t make the new HttpSession object yourself.
You don’t
generate the unique session ID. You don’t make the new Cookie
object.
You don’t associate the session ID with the cookie. You don’t set
the Cookie into the response
All the cookie work happens behind the scenes.
If I update the session on a given request, will that
always be reflected through subsequent calls?
yes it effects the subsequent calls.
With a session cookie, or if cookies are disabled you're able to see the telltale JSESSIONID parameter. This was at least the case a while ago, and I shouldn't think it has changed.
The HttpSession is by default stored in memory and created/maintained by the web server (jetty, tomcat, ...). Depending on the web server you use you might have options like storing session information into the database.
Here is the tomcat documentation for the session manager[1]
[1] https://tomcat.apache.org/tomcat-7.0-doc/config/manager.html
We need a functionality of killing a specific session (by session ID) from some kind of an admin panel.
I attempted using the following approach:
public static void killSession(String sid) {
HttpSessionContext sc = FacesUtil.getSession().getSessionContext();
HttpSession session=sc.getSession(sid);
session.invalidate();
}
However
HttpSessionContext, and getSessionContext() and
getSession(sessionId) methods of a session are all deprecated (for seemingly paranoid security reasons)
The above code also gets a null session when invoked in an ApplicationScoped JSF managed bean
I'm seeking an alternative way of achieving the functionality.
Yes, you can't invalidate session from another session due to security reasons. What you can do is to manually store all sessions in some static attribute available to admin. So user logs in, you add him and his session to this attribute (usually a Map/HashMap with user as a key and session as value).
Look at my older answer here and you will get an idea.
I am using servlets for the first time but I made a lot of progress. My servlets are working well. So I decided to put an authentication mechanism, which creates a session, if users give the right password and id's. But sessions are totally new for me. So I don't quite follow the logic but I have started to understand.
As I mentioned before one of my servlets is dedicated for logging in. If password is correct a session is created (I don't store any object/data in sessions) and client (remoteUser) is notified that the password is accepted and session is created. What client does is to reach any other servlet in the same application. Other servlets get the session to check if it is created and valid (not timed out). For that purpose in those other servlets I get the session with:
HttpSession session = req.getSession(false); //false because this is not the place to create a session. sessions should only be created in the login servlet.
But this returns a null. So I have tried:
HttpSession session = req.getSession();
And checked with session.isNew(); and I it was a new session. So the session I have created in login servlet can't be called with req.getSession(); in another servlet.
PS: When session is created in login servlet: session.setMaxInactiveInterval(300); //5 minutes
Thanks a lot for any response!
When using Google App Engine, you have to specifically enable session support. See http://code.google.com/appengine/docs/java/config/appconfig.html#Enabling_Sessions.
I am currently doing a system on Google App Engine and am very new to it, I am developing using the Java plattform . I have a problem about sending the session object between servlets. I have already enabled sessions on the appengine.webxml. I can send the session object from my login page to a VIEW page but after which the session object cannot be passed any longer.
Any possible answers?
You do not need to "pass" a session object from one Servlet to another. The session object can always be retrieved via the HttpServletRequest e.g. like this HttpSession session = request.getSession();. In JSPs (I guess that's your view technology) you can access the session via the implicit variable session.
To make sure your session doesn't expire to early set an appropriate value for <session-timeout/> in your web.xml.