I noticed that the jsessionId will get sent across to the server so in the filter I could actually get the expired session id from the cookies.
Is it ok to put a filter logic like the following?
Cookie jsessionCookie = getSessionIdCookies(request);
Session session = request.getSession(false);
if (session == null || !(jsessionCookie.getValue().equals(session.getId())) {
//this should be a timeout handling
....
} else {
// normal moving forward
}
Since the session == null could also because of a new request (which can be filtered out by setting particular filter rules), can I more rely on !(jsessionCookie.getValue().equals(session.getId())?
Or even change the request.getSession(false) to request.getSession() and just always compare the cookie with the session id?
Is there a better management practice for session timeout management?
You can register a HttpSessionListener on the ServletContext to get notified when a session is invalidated.
Related
I am working on a java application using spring security.
I want to avoid the session fixation, but the session fixation solution found on the docs seem not to be working as expected... here
So, I did this on my login
final HttpSession session = request.getSession(false);
if (session != null && !session.isNew()) {
session.invalidate();
}
Works great and changes the JSESSIONID everytime I call the login page...
But once I am logged in, I can call the login page again, get another JSESSIONID and still be logged in, I can just click on the back button and come back to the logged users area.
It does change the JSESSIONID, my question is, shouldnt it have a bigger effect? like invalidate my session or log me out?
When I call the log out form it does log the user out and works as expected, I am just wondering if changing the JSESSIONID has a real effect or does nto matter.
ANy idea?
I am using security 3.2
spring's session is mapped to JSESSIONID. so if a customer would have session state beans, they would be lost after changing JSESSIONID.
even though documentation tells
Spring Security protects against this automatically by creating a new
session when a user logs in
you can explicitly set configuration for session fixation by adding this
<security:session-management session-authentication-strategy-ref="fixation" />
and defining fixation bean with SessionFixationProtectionStrategy class
General question about java servlets and the best way to handle requests. If I hit my doGet method from a remote server request:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
....
<do work here>
....
kill(request);
}
private void kill(HttpServletRequest request) {
//How do I kill the user session here?
}
After I process the request at my end and generate my output to the requester, I want to basically "kill" their session. Currently, that session lingers and thus eats up memory. Then once the max is reached, all other calls are timed out.
I tried creating a HttpSession object using the request object, but got the same results:
HttpSession session = request.getSession();
session.invalidate();
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
is the proper way to go as suggested by the documentation. A new session will be created once the client sends a new request.
You mentioned that your sessions still take up memory. Do you have any other references to those objects on the session?
You also might want to have a look at: Servlet Session behavior and Session.invalidate
you can remove an attribute from a session using
session.removeAttribute("attribute name");
Try with
session = request.getSession(false); // so if no session is active no session is created
if (session != null)
session.setMaxInactiveInterval(1); // so it expires immediatly
If you dont want Session behavior i.e, having state between multiple requests. Why do you want to create/use session at all. Do not create session or do not store anything in the session.
To make sure that your code is not using session, write a request wrapper which will override getSession() methods.
Set a time-out period in web.xml
I have a Hibernate-based platform, built from stateless servlets (one is used to register a user and the rest to query the db).
I'm using Hibernate's sessions as follows:
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
if ((null == session) || (session.isOpen() == false)) {
session = HibernateUtil.getSessionFactory().openSession();
}
Currently I do not close the session at the end of the servlet in order to avoid openSession() call (trying to use opened sessions if possible).
What's the best practice ? when am I supposed to close these sessions ?
Can you please give an example ?
Thanks in advance !
The best practice is in most cases session-per-request. That is, open a session in the beginning of handling a request, and close it in the end. You can do that in a Servlet Filter, for example.
Having one session for the entire application is bad, because it will accumulate a lot of entities in its 1st level cache, which is a memory leak. It may also produce undeterministic results when multiple clients use it at the same time.
Your code, however, is not using one session for the entire application - it is using the "current session" concept, which opens a session and stores it in a context (a ThreadLocal for example). But if you don't close it, it will stay there forever. Plus, it will cause the same problems as described above, because threads are reused in a web application, and a new request will get an old, unclosed session at some point.
Its always better to open a new session for every request, and close the session once the request is processed. Like
Session session = HibernateUtil.getSessionFactory().openSession();
instead of
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
If we use the getCurrentSession() method , tansaction.commit() / rollback() closes the connection.
The best is to manage a hibernate session is to open a new session for every request.
It all depends on how you obtain the session.
if you use sessionFactory.getCurrentSession(), you'll obtain a
"current session" which is bound to the lifecycle of the transaction
and will be automatically flushed and closed when the transaction
ends (commit or rollback)
if you decide to use sessionFactory.openSession(), you'll have to
manage the session yourself and to flush and close it "manually".
if (!session.isOpen()) {
session = session.getSessionFactory().openSession();
session.beginTransaction();
}
I better recommend you to use spring framework. Cause in spring you can use #Transactional at method level and session will be automatically created and closed by transaction manager (unless you are using any open session in view interceptor) using AOP which is internally handled by framework.
#Autowired
EntityManager em;
#Transactinal
void save(User user){
em.persist(user);
}
thats all.spring is fun :D
I am using Spring Security 3.0 and created a custom filter to check for expired sessions.
My problem is that request.isRequestedSessionValid() returns true in my filter even after I let the session expire or log out. If I try to access any secured page, I do get redirected to my login page so I know that the session management works.
My understanding was that when a web session times out, the session is automatically invalidated and I also set invalidate-session in my logout element of Spring Security. How can the session still be valid? Am I checking the wrong value?
request.isRequestedSessionValid() can itself cause a session to be created, even after logout has been called. Use request.getSession(false) != null to check instead, which will ensure that a session is not created.
I've a JSP/Servlet Web App that consist of more than one servlet (and some JSPs)
I need to create an new HttpSession whenever the users access servlet A, knowing that, servlet A is the home page (i.e. he access it as the first servlet/page in the application).
So far so good, I can write the following code at the start of the servlet A:
HttpSession session = request.getSession(false);
if (session == null) {
logger.debug("starting new session...");
session = request.getSession();
// other stuff here
}
But the problem is, if the user didn't close his browser (even if he closes the tab - in Firefox for instance - the session will still be open), so when he try to open my site again, the last session will be re-used (in the range of session timeout of course), and this I don't need. I need that whenever he accesses Servlet A, he gets a brand new HttpSession.
But unfortunately, he may access this servlet twice per session based on some scenario!
It seems to me that you should not be using session for this purpose. Perhaps you can add a parameter to request (i.e. transaction id) and pass it around trough all your related requests, so when user would close page the transaction id would be gone. Then you can store any data associated with given transaction id in the http session or elsewhere and could also clean it after some time.
The spring framework has an abstraction called bean scope, which seem like a good fit for your scenario, so you can create a custom scope for your transaction (or user's session) and store all the data in some bean scoped with such custom scope.
You should store some information (attribute) in the session that it's been used. And if it has been, invalidate
HttpSession session = request.getSession();
Object isOld = session.getAttribute( "isOld" );
if ( isOld != null )
{
session.invalidate( );
// Recreate session
session = request.getSession( );
}
session.setAttribute( "isOld", new Object( ) );