summaryrefslogtreecommitdiffstats
path: root/server/src/com
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-09-28 14:58:37 +0300
committerVaadin Code Review <review@vaadin.com>2012-09-28 16:29:26 +0000
commitca59c93fb4dbc112e5deb5f5a4b10c0c730a4be4 (patch)
treeaea674d8f984b20eaf150725390f569d43f5f663 /server/src/com
parent9c31730847aebfe014b143b590ff6348d850a694 (diff)
downloadvaadin-framework-ca59c93fb4dbc112e5deb5f5a4b10c0c730a4be4.tar.gz
vaadin-framework-ca59c93fb4dbc112e5deb5f5a4b10c0c730a4be4.zip
Move reinitialize session to VaadinService (#9638)
This change adds reinitializeSession as a static method in VaadinService. The method is static because it affects the sessions of all VaadinService instances that are using the underlying session. Change-Id: Ia37567cb00e1f95aec344451299c99cb279a7275
Diffstat (limited to 'server/src/com')
-rw-r--r--server/src/com/vaadin/server/VaadinService.java63
-rw-r--r--server/src/com/vaadin/server/VaadinServiceSession.java1
-rw-r--r--server/src/com/vaadin/server/VaadinServletSession.java61
-rw-r--r--server/src/com/vaadin/server/WrappedHttpSession.java25
-rw-r--r--server/src/com/vaadin/server/WrappedPortletSession.java12
-rw-r--r--server/src/com/vaadin/server/WrappedSession.java20
6 files changed, 121 insertions, 61 deletions
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index 77a3018bb6..add32bf57b 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceLoader;
@@ -49,6 +50,9 @@ import com.vaadin.util.ReflectTools;
* @since 7.0
*/
public abstract class VaadinService implements Serializable {
+ private static final String REINITIALIZING_SESSION_MARKER = VaadinService.class
+ .getName() + ".reinitializing";
+
private static final Method SESSION_INIT_METHOD = ReflectTools.findMethod(
SessionInitListener.class, "sessionInit", SessionInitEvent.class);
@@ -271,6 +275,11 @@ public abstract class VaadinService implements Serializable {
}
public void fireSessionDestroy(VaadinServiceSession vaadinSession) {
+ // Ignore if the session is being moved to a different backing session
+ if (vaadinSession.getAttribute(REINITIALIZING_SESSION_MARKER) == Boolean.TRUE) {
+ return;
+ }
+
for (UI ui : new ArrayList<UI>(vaadinSession.getUIs())) {
vaadinSession.cleanupUI(ui);
}
@@ -619,4 +628,58 @@ public abstract class VaadinService implements Serializable {
public boolean preserveUIOnRefresh(UIProvider provider, UICreateEvent event) {
return provider.isPreservedOnRefresh(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.
+ * <p>
+ * Please note that this method makes certain assumptions about how data is
+ * stored in the underlying session and may thus not be compatible with some
+ * environments.
+ *
+ * @param request
+ * The Vaadin request for which the session should be
+ * reinitialized
+ */
+ public static void reinitializeSession(VaadinRequest request) {
+ WrappedSession oldSession = request.getWrappedSession();
+
+ // 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 (String name : oldSession.getAttributeNames()) {
+ Object value = oldSession.getAttribute(name);
+ if (value instanceof VaadinServiceSession) {
+ // set flag to avoid cleanup
+ VaadinServiceSession serviceSession = (VaadinServiceSession) value;
+ serviceSession.setAttribute(REINITIALIZING_SESSION_MARKER,
+ Boolean.TRUE);
+ }
+ attrs.put(name, value);
+ }
+
+ // Invalidate the current session
+ oldSession.invalidate();
+
+ // Create a new session
+ WrappedSession newSession = request.getWrappedSession();
+
+ // Restores all attributes (security key, reference to this context
+ // instance)
+ for (String name : attrs.keySet()) {
+ Object value = attrs.get(name);
+ newSession.setAttribute(name, value);
+
+ // Ensure VaadinServiceSession knows where it's stored
+ if (value instanceof VaadinServiceSession) {
+ VaadinServiceSession serviceSession = (VaadinServiceSession) value;
+ serviceSession.storeInSession(serviceSession.getService(),
+ newSession);
+ serviceSession
+ .setAttribute(REINITIALIZING_SESSION_MARKER, null);
+ }
+ }
+
+ }
}
diff --git a/server/src/com/vaadin/server/VaadinServiceSession.java b/server/src/com/vaadin/server/VaadinServiceSession.java
index c581a1930c..67b224df70 100644
--- a/server/src/com/vaadin/server/VaadinServiceSession.java
+++ b/server/src/com/vaadin/server/VaadinServiceSession.java
@@ -225,6 +225,7 @@ public class VaadinServiceSession implements HttpSessionBindingListener,
// closing
// Notify the service
service.fireSessionDestroy(this);
+ session = null;
}
/**
diff --git a/server/src/com/vaadin/server/VaadinServletSession.java b/server/src/com/vaadin/server/VaadinServletSession.java
index 78f58d64fe..aa31a19c1b 100644
--- a/server/src/com/vaadin/server/VaadinServletSession.java
+++ b/server/src/com/vaadin/server/VaadinServletSession.java
@@ -16,12 +16,7 @@
package com.vaadin.server;
-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;
/**
@@ -39,8 +34,6 @@ import javax.servlet.http.HttpSessionBindingListener;
@SuppressWarnings("serial")
public class VaadinServletSession extends VaadinServiceSession {
- private transient boolean reinitializingSession = false;
-
/**
* Create a servlet service session for the given servlet service
*
@@ -51,60 +44,6 @@ public class VaadinServletSession extends VaadinServiceSession {
super(service);
}
- @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.
- */
- public void reinitializeSession() {
- HttpServletRequest currentRequest = VaadinServletService
- .getCurrentServletRequest();
- if (currentRequest == null) {
- throw new IllegalStateException(
- "Can not reinitialize session outside normal request handling.");
- }
-
- 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 = 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
- storeInSession(VaadinService.getCurrent(), new WrappedHttpSession(
- newSession));
- }
-
/**
* Gets the http-session application is running in.
*
diff --git a/server/src/com/vaadin/server/WrappedHttpSession.java b/server/src/com/vaadin/server/WrappedHttpSession.java
index 1465588e08..e13a63635b 100644
--- a/server/src/com/vaadin/server/WrappedHttpSession.java
+++ b/server/src/com/vaadin/server/WrappedHttpSession.java
@@ -16,6 +16,11 @@
package com.vaadin.server;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
import javax.servlet.http.HttpSession;
/**
@@ -63,4 +68,24 @@ public class WrappedHttpSession implements WrappedSession {
return session;
}
+ @Override
+ public Set<String> getAttributeNames() {
+ Enumeration<String> attributeNames = session.getAttributeNames();
+ return enumerationToSet(attributeNames);
+ }
+
+ // Helper shared with WrappedPortletSession
+ static <T> Set<T> enumerationToSet(Enumeration<T> values) {
+ HashSet<T> set = new HashSet<T>();
+ while (values.hasMoreElements()) {
+ set.add(values.nextElement());
+ }
+ return Collections.unmodifiableSet(set);
+ }
+
+ @Override
+ public void invalidate() {
+ session.invalidate();
+ }
+
}
diff --git a/server/src/com/vaadin/server/WrappedPortletSession.java b/server/src/com/vaadin/server/WrappedPortletSession.java
index eb07eb38f6..03c1d7ba1f 100644
--- a/server/src/com/vaadin/server/WrappedPortletSession.java
+++ b/server/src/com/vaadin/server/WrappedPortletSession.java
@@ -16,6 +16,8 @@
package com.vaadin.server;
+import java.util.Set;
+
import javax.portlet.PortletSession;
/**
@@ -62,4 +64,14 @@ public class WrappedPortletSession implements WrappedSession {
public PortletSession getPortletSession() {
return session;
}
+
+ @Override
+ public Set<String> getAttributeNames() {
+ return WrappedHttpSession.enumerationToSet(session.getAttributeNames());
+ }
+
+ @Override
+ public void invalidate() {
+ session.invalidate();
+ }
}
diff --git a/server/src/com/vaadin/server/WrappedSession.java b/server/src/com/vaadin/server/WrappedSession.java
index 3973c257c8..34443239c7 100644
--- a/server/src/com/vaadin/server/WrappedSession.java
+++ b/server/src/com/vaadin/server/WrappedSession.java
@@ -16,6 +16,8 @@
package com.vaadin.server;
+import java.util.Set;
+
import javax.portlet.PortletSession;
import javax.servlet.http.HttpSession;
@@ -66,4 +68,22 @@ public interface WrappedSession {
* @see javax.portlet.PortletSession#setAttribute(String, Object)
*/
public void setAttribute(String name, Object value);
+
+ /**
+ * Gets the current set of attribute names stored in this session.
+ *
+ * @return an unmodifiable set of the current attribute names
+ *
+ * @see HttpSession#getAttributeNames()
+ * @see PortletSession#getAttributeNames()
+ */
+ public Set<String> getAttributeNames();
+
+ /**
+ * Invalidates this session then unbinds any objects bound to it.
+ *
+ * @see HttpSession#invalidate()
+ * @see PortletSession#invalidate()
+ */
+ public void invalidate();
}