Browse Source

Use separate identifier for push connections

Closes #8700
tags/8.1.0.alpha5^0
Aleksi Hietanen 7 years ago
parent
commit
a4a4d9e064

+ 6
- 6
client/src/main/java/com/vaadin/client/communication/AtmospherePushConnection.java View File

@@ -207,10 +207,10 @@ public class AtmospherePushConnection implements PushConnection {
String extraParams = UIConstants.UI_ID_PARAMETER + "="
+ connection.getConfiguration().getUIId();

String csrfToken = connection.getMessageHandler().getCsrfToken();
if (!csrfToken.equals(ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) {
extraParams += "&" + ApplicationConstants.CSRF_TOKEN_PARAMETER + "="
+ csrfToken;
String pushId = connection.getMessageHandler().getPushId();
if (pushId != null) {
extraParams += "&" + ApplicationConstants.PUSH_ID_PARAMETER + "="
+ pushId;
}

// uri is needed to identify the right connection when closing
@@ -526,7 +526,7 @@ public class AtmospherePushConnection implements PushConnection {
JavaScriptObject config)
/*-{
var self = this;
config.url = uri;
config.onOpen = $entry(function(response) {
self.@com.vaadin.client.communication.AtmospherePushConnection::onOpen(*)(response);
@@ -552,7 +552,7 @@ public class AtmospherePushConnection implements PushConnection {
config.onClientTimeout = $entry(function(request) {
self.@com.vaadin.client.communication.AtmospherePushConnection::onClientTimeout(*)(request);
});
return $wnd.vaadinPush.atmosphere.subscribe(config);
}-*/;


+ 19
- 0
client/src/main/java/com/vaadin/client/communication/MessageHandler.java View File

@@ -134,6 +134,9 @@ public class MessageHandler {
// will hold the CSRF token once received
private String csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE;

// holds the push identifier once received
private String pushId = null;

/** Timer for automatic redirect to SessionExpiredURL */
private Timer redirectTimer;

@@ -350,6 +353,12 @@ public class MessageHandler {
csrfToken = json
.getString(ApplicationConstants.UIDL_SECURITY_TOKEN_ID);
}

// Get push id if present
if (json.containsKey(ApplicationConstants.UIDL_PUSH_ID)) {
pushId = json.getString(ApplicationConstants.UIDL_PUSH_ID);
}

getLogger().info(" * Handling resources from server");

if (json.containsKey("resources")) {
@@ -1687,6 +1696,16 @@ public class MessageHandler {
return csrfToken;
}

/**
* Gets the push connection identifier for this session. Used when
* establishing a push connection with the client.
*
* @return the push connection identifier string
*/
public String getPushId() {
return pushId;
}

/**
* Checks whether state changes are currently being processed. Certain
* operations are not allowed when the internal state of the application

+ 13
- 0
server/src/main/java/com/vaadin/server/VaadinSession.java View File

@@ -744,6 +744,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.
@@ -1417,6 +1419,17 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
return csrfToken;
}

/**
* Gets the push connection identifier for this session. Used when
* establishing a push connection with the client.
*
* @return the push connection identifier string
*/
public String getPushId() {
assert hasLock();
return pushId;
}

/**
* Override default deserialization logic to account for transient
* {@link #pendingAccessQueue}.

+ 22
- 3
server/src/main/java/com/vaadin/server/communication/PushHandler.java View File

@@ -90,10 +90,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
@@ -479,6 +479,25 @@ public class PushHandler {
return Logger.getLogger(PushHandler.class.getName());
}

/**
* 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
*

+ 15
- 0
server/src/main/java/com/vaadin/server/communication/UIInitHandler.java View File

@@ -287,6 +287,9 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
if (session.getConfiguration().isXsrfProtectionEnabled()) {
writer.write(getSecurityKeyUIDL(session));
}
if (uI.getPushConfiguration().getPushMode().isEnabled()) {
writer.write(getPushIdUIDL(session));
}
new UidlWriter().write(uI, writer, false);
writer.write("}");

@@ -310,6 +313,18 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler {
+ seckey + "\",";
}

/**
* Gets the push connection identifier as UIDL.
*
* @param session
* the vaadin session to which the security key belongs
* @return the push identifier UIDL
*/
private static String getPushIdUIDL(VaadinSession session) {
return "\"" + ApplicationConstants.UIDL_PUSH_ID + "\":\""
+ session.getPushId() + "\",";
}

private static final Logger getLogger() {
return Logger.getLogger(UIInitHandler.class.getName());
}

+ 8
- 1
shared/src/main/java/com/vaadin/shared/ApplicationConstants.java View File

@@ -55,6 +55,8 @@ public class ApplicationConstants implements Serializable {

public static final String UIDL_SECURITY_TOKEN_ID = "Vaadin-Security-Key";

public static final String UIDL_PUSH_ID = "Vaadin-Push-ID";

@Deprecated
public static final String UPDATE_VARIABLE_INTERFACE = "v";
@Deprecated
@@ -80,7 +82,7 @@ public class ApplicationConstants implements Serializable {
/**
* Configuration parameter giving the (in some cases relative) URL to the
* web application context root.
*
*
* @since 8.0.3
*/
public static final String CONTEXT_ROOT_URL = "contextRootUrl";
@@ -122,6 +124,11 @@ public class ApplicationConstants implements Serializable {
*/
public static final String CSRF_TOKEN_PARAMETER = "v-csrfToken";

/**
* Name of the parameter used to transmit the push connection identifier.
*/
public static final String PUSH_ID_PARAMETER = "v-pushId";

/**
* The name of the parameter used to transmit RPC invocations
*

Loading…
Cancel
Save