diff options
author | Olli Tietäväinen <ollit@vaadin.com> | 2017-08-10 16:07:42 +0300 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-08-10 16:07:42 +0300 |
commit | 97fa55d3d447098bbf605054b1ccfa08a848dc3e (patch) | |
tree | ec2310b70cfd0167dfed9e398716e04df43569fc /server | |
parent | 62d50a66e0216eb5210e93ef39cce8dbdde0ca9f (diff) | |
download | vaadin-framework-97fa55d3d447098bbf605054b1ccfa08a848dc3e.tar.gz vaadin-framework-97fa55d3d447098bbf605054b1ccfa08a848dc3e.zip |
Use separate identifier for push connections (#9150)
By using a separate id we can avoid sending the sessions
CSRF token as a GET parameter when initializing a push connection.
Cherry-picked from #8700 to the 7.7 branch.
Diffstat (limited to 'server')
3 files changed, 58 insertions, 11 deletions
diff --git a/server/src/main/java/com/vaadin/server/VaadinSession.java b/server/src/main/java/com/vaadin/server/VaadinSession.java index 7014a5f1f5..8cb833e68f 100644 --- a/server/src/main/java/com/vaadin/server/VaadinSession.java +++ b/server/src/main/java/com/vaadin/server/VaadinSession.java @@ -508,8 +508,8 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { private void refreshLock() { assert lock == null || lock == service.getSessionLock( session) : "Cannot change the lock from one instance to another"; - assert hasLock(service, session); - lock = service.getSessionLock(session); + assert hasLock(service, session); + lock = service.getSessionLock(session); } public void setCommunicationManager( @@ -747,6 +747,8 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { private final String csrfToken = UUID.randomUUID().toString(); + private final String pushId = UUID.randomUUID().toString(); + /** * Generate an id for the given Connector. Connectors must not call this * method more than once, the first time they need an id. @@ -1008,12 +1010,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { getLogger().log(Level.SEVERE, "Exception while cleaning connector map for ui " + ui.getUIId(), - e); + e); } catch (AssertionError e) { getLogger().log(Level.SEVERE, "Exception while cleaning connector map for ui " + ui.getUIId(), - e); + e); } } } @@ -1089,7 +1091,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { } if (value != null && !type.isInstance(value)) { throw new IllegalArgumentException("value of type " + type.getName() - + " expected but got " + value.getClass().getName()); + + " expected but got " + value.getClass().getName()); } setAttribute(type.getName(), value); } @@ -1287,7 +1289,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { protected void setState(State state) { assert hasLock(); assert this.state.isValidChange(state) : "Invalid session state change " - + this.state + "->" + state; + + this.state + "->" + state; this.state = state; } @@ -1423,6 +1425,18 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { } /** + * Gets the push connection identifier for this session. Used when + * establishing a push connection with the client. + * + * @return the push connection identifier string + * @since 7.7.11 + */ + public String getPushId() { + assert hasLock(); + return pushId; + } + + /** * Override default deserialization logic to account for transient * {@link #pendingAccessQueue}. */ diff --git a/server/src/main/java/com/vaadin/server/communication/PushHandler.java b/server/src/main/java/com/vaadin/server/communication/PushHandler.java index 7cc41aeda3..2477a76d5c 100644 --- a/server/src/main/java/com/vaadin/server/communication/PushHandler.java +++ b/server/src/main/java/com/vaadin/server/communication/PushHandler.java @@ -91,10 +91,10 @@ public class PushHandler { } String requestToken = resource.getRequest() - .getParameter(ApplicationConstants.CSRF_TOKEN_PARAMETER); - if (!VaadinService.isCsrfTokenValid(session, requestToken)) { + .getParameter(ApplicationConstants.PUSH_ID_PARAMETER); + if (!isPushIdValid(session, requestToken)) { getLogger().log(Level.WARNING, - "Invalid CSRF token in new connection received from {0}", + "Invalid identifier in new connection received from {0}", resource.getRequest().getRemoteHost()); // Refresh on client side, create connection just for // sending a message @@ -473,6 +473,25 @@ public class PushHandler { } /** + * Checks whether a given push id matches the session's push id. + * + * @param session + * the vaadin session for which the check should be done + * @param requestPushId + * the push id provided in the request + * @return {@code true} if the id is valid, {@code false} otherwise + */ + private static boolean isPushIdValid(VaadinSession session, + String requestPushId) { + + String sessionPushId = session.getPushId(); + if (requestPushId == null || !requestPushId.equals(sessionPushId)) { + return false; + } + return true; + } + + /** * Called when a new push connection is requested to be opened by the client * * @since 7.5.0 diff --git a/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java index aa167d137f..9ef63c3138 100644 --- a/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/main/java/com/vaadin/server/communication/UIInitHandler.java @@ -220,7 +220,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { session.addUI(ui); if (initException != null) { ui.getSession().getCommunicationManager() - .handleConnectorRelatedException(ui, initException); + .handleConnectorRelatedException(ui, initException); } // Warn if the window can't be preserved if (embedId == null @@ -288,6 +288,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { if (session.getConfiguration().isXsrfProtectionEnabled()) { writer.write(getSecurityKeyUIDL(session)); } + writer.write(getPushIdUIDL(session)); new UidlWriter().write(uI, writer, false); writer.write("}"); @@ -310,7 +311,20 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { String seckey = session.getCsrfToken(); return "\"" + ApplicationConstants.UIDL_SECURITY_TOKEN_ID + "\":\"" - + seckey + "\","; + + seckey + "\","; + } + + /** + * Gets the push connection identifier as UIDL. + * + * @param session + * the vaadin session to which the security key belongs + * @return the push identifier UIDL + * @since 7.7.11 + */ + private static String getPushIdUIDL(VaadinSession session) { + return "\"" + ApplicationConstants.UIDL_PUSH_ID + "\":\"" + + session.getPushId() + "\","; } private static final Logger getLogger() { |