]> source.dussan.org Git - vaadin-framework.git/commitdiff
Backported #6094 to Vaadin 6.6
authorLeif Åstrand <leif@vaadin.com>
Tue, 23 Aug 2011 10:02:01 +0000 (10:02 +0000)
committerLeif Åstrand <leif@vaadin.com>
Tue, 23 Aug 2011 10:02:01 +0000 (10:02 +0000)
svn changeset:20556/svn branch:6.6

src/com/vaadin/terminal/gwt/server/PortletApplicationContext.java
src/com/vaadin/terminal/gwt/server/WebApplicationContext.java

index 49d40cbc6254287262c0764cdcfd9b14d24aaf27..79f223058821569d52be8b4dcb893b98092214ca 100644 (file)
@@ -95,6 +95,17 @@ public class PortletApplicationContext extends WebApplicationContext implements
         super.removeApplication(application);
     }
 
+    /**
+     * Reinitializing the session is not supported from portlets.
+     * 
+     * @see com.vaadin.terminal.gwt.server.WebApplicationContext#reinitializeSession()
+     */
+    @Override
+    public void reinitializeSession() {
+        throw new UnsupportedOperationException(
+                "Reinitializing the session is not supported from portlets");
+    }
+
     public void setPortletApplication(Portlet portlet, Application app) {
         portletToApplication.put(portlet, app);
     }
index dbb44d51d29e9447dc701b42d23dc92e63494b33..89b67738157288c478002da0a438262f75063b16 100644 (file)
@@ -5,8 +5,12 @@
 package com.vaadin.terminal.gwt.server;
 
 import java.io.File;
+import java.util.Enumeration;
+import java.util.HashMap;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionBindingEvent;
 import javax.servlet.http.HttpSessionBindingListener;
 
 import com.vaadin.Application;
@@ -26,6 +30,12 @@ import com.vaadin.Application;
 public class WebApplicationContext extends AbstractWebApplicationContext {
 
     protected transient HttpSession session;
+    private transient boolean reinitializingSession = false;
+
+    /**
+     * Stores a reference to the currentRequest. Null it not inside a request.
+     */
+    private transient Object currentRequest = null;
 
     /**
      * Creates a new Web Application Context.
@@ -35,6 +45,67 @@ public class WebApplicationContext extends AbstractWebApplicationContext {
 
     }
 
+    @Override
+    protected void startTransaction(Application application, Object request) {
+        currentRequest = request;
+        super.startTransaction(application, request);
+    }
+
+    @Override
+    protected void endTransaction(Application application, Object request) {
+        super.endTransaction(application, request);
+        currentRequest = null;
+    }
+
+    @Override
+    public void valueUnbound(HttpSessionBindingEvent event) {
+        if (!reinitializingSession) {
+            // Avoid closing the application if we are only reinitializing the
+            // session. Closing the application would cause the state to be lost
+            // and a new application to be created, which is not what we want.
+            super.valueUnbound(event);
+        }
+    }
+
+    /**
+     * Discards the current session and creates a new session with the same
+     * contents. The purpose of this is to introduce a new session key in order
+     * to avoid session fixation attacks.
+     */
+    @SuppressWarnings("unchecked")
+    public void reinitializeSession() {
+
+        HttpSession oldSession = getHttpSession();
+
+        // Stores all attributes (security key, reference to this context
+        // instance) so they can be added to the new session
+        HashMap<String, Object> attrs = new HashMap<String, Object>();
+        for (Enumeration<String> e = oldSession.getAttributeNames(); e
+                .hasMoreElements();) {
+            String name = e.nextElement();
+            attrs.put(name, oldSession.getAttribute(name));
+        }
+
+        // Invalidate the current session, set flag to avoid call to
+        // valueUnbound
+        reinitializingSession = true;
+        oldSession.invalidate();
+        reinitializingSession = false;
+
+        // Create a new session
+        HttpSession newSession = ((HttpServletRequest) currentRequest)
+                .getSession();
+
+        // Restores all attributes (security key, reference to this context
+        // instance)
+        for (String name : attrs.keySet()) {
+            newSession.setAttribute(name, attrs.get(name));
+        }
+
+        // Update the "current session" variable
+        session = newSession;
+    }
+
     /**
      * Gets the application context base directory.
      *