From 21abaa8270bdc8b5b2403d52937429b796b79ff1 Mon Sep 17 00:00:00 2001 From: GPrathap Date: Wed, 25 Jan 2017 08:49:46 +0530 Subject: [PATCH] changed websocket token retrieval mechanism --- .../geo-dashboard/js/websocket.js | 5 ++-- .../analytics-view.js | 22 +++++++++----- .../analytics-view.js | 4 +-- .../analytics-view.js | 4 +-- .../analytics-view.js | 4 +-- .../SuperTenantSubscriptionEndpoint.java | 10 +++++-- .../endpoint/TenantSubscriptionEndpoint.java | 10 +++++-- .../endpoint/constants/Constants.java | 1 + .../oauth/OAuthTokenValdiator.java | 30 +++++++++++++++++-- 9 files changed, 63 insertions(+), 27 deletions(-) diff --git a/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/src/main/resources/carbonapps/GadgetGeoDashboard_1.0.0/geo-dashboard/js/websocket.js b/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/src/main/resources/carbonapps/GadgetGeoDashboard_1.0.0/geo-dashboard/js/websocket.js index 8f10a93342..78c404b923 100644 --- a/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/src/main/resources/carbonapps/GadgetGeoDashboard_1.0.0/geo-dashboard/js/websocket.js +++ b/components/analytics/iot-analytics/org.wso2.carbon.iot.geo.dashboard/src/main/resources/carbonapps/GadgetGeoDashboard_1.0.0/geo-dashboard/js/websocket.js @@ -702,14 +702,13 @@ function intializeWebsocketUrls() { .constance.TENANT_INDEX + ApplicationOptions.constance.PATH_SEPARATOR + data.user.domain + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions.constance .CEP_WEB_SOCKET_OUTPUT_ADAPTOR_NAME + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions.constance.VERSION - + "?deviceId=" + deviceId + "&deviceType=" + deviceType; + + "?deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + accessToken; alertWebSocketURL = 'wss://' + hostname + ':' + port + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions.constance .CEP_WEB_SOCKET_OUTPUT_ADAPTOR_WEBAPP_NAME + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions .constance.TENANT_INDEX + ApplicationOptions.constance.PATH_SEPARATOR + data.user.domain + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions.constance .CEP_ON_ALERT_WEB_SOCKET_OUTPUT_ADAPTOR_NAME + ApplicationOptions.constance.PATH_SEPARATOR + ApplicationOptions.constance.VERSION - + "?deviceId=" + deviceId + "&deviceType=" + deviceType; - document.cookie = "websocket-token=" + accessToken + "; path=/"; + + "?deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + accessToken; $("#proximity_alert").hide(); initializeWebSocket(); initializeOnAlertWebSocket(); diff --git a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js index c5186ac12c..e6611f1f6b 100644 --- a/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js +++ b/components/device-types/androidsense-plugin/org.wso2.carbon.device.mgt.iot.androidsense.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.android_sense.realtime.analytics-view/analytics-view.js @@ -22,13 +22,21 @@ function onRequest(context) { var device = context.unit.params.device; var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var constants = require("/app/modules/constants.js"); - var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss"); - var tokenPair = session.get(constants["TOKEN_PAIR"]); - if (tokenPair) { - var token = parse(tokenPair)["accessToken"]; - websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.android.sense/1.0.0?" + - "token="+ token +"&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - } + var jwtService = carbonServer.osgiService( + 'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService'); + var jwtClient = jwtService.getJWTClient(); + var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]); + var token = ""; + if (encodedClientKeys) { + var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; + var resp = tokenUtil.decode(encodedClientKeys).split(":"); + var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + } + websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.android.sense/1.0.0?" + + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; + } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js index e54cef4ec4..7aaad19c6b 100644 --- a/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js +++ b/components/device-types/arduino-plugin/org.wso2.carbon.device.mgt.iot.arduino.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.arduino.realtime.analytics-view/analytics-view.js @@ -36,9 +36,7 @@ function onRequest(context) { token = tokenPair.accessToken; } websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" - + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; - response.addCookie(websocketToken); + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js index e54cef4ec4..7aaad19c6b 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.realtime.analytics-view/analytics-view.js @@ -36,9 +36,7 @@ function onRequest(context) { token = tokenPair.accessToken; } websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" - + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; - response.addCookie(websocketToken); + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js index e54cef4ec4..7aaad19c6b 100644 --- a/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js +++ b/components/device-types/virtual-fire-alarm-plugin/org.wso2.carbon.device.mgt.iot.virtualfirealarm.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.virtual_firealarm.realtime.analytics-view/analytics-view.js @@ -36,9 +36,7 @@ function onRequest(context) { token = tokenPair.accessToken; } websocketEndpoint = websocketEndpoint + "/secured-websocket/org.wso2.iot.devices.temperature/1.0.0?" - + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type; - var websocketToken= {'name':'websocket-token','value': token, 'path':'/', "maxAge":18000}; - response.addCookie(websocketToken); + + "deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type + "&websocketToken=" + token; } return {"device": device, "websocketEndpoint": websocketEndpoint}; } \ No newline at end of file diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java index 672e9aedfe..28692319d6 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/SuperTenantSubscriptionEndpoint.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint; +import org.apache.commons.collections.map.HashedMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; @@ -38,6 +39,7 @@ import javax.websocket.OnOpen; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -63,10 +65,12 @@ public class SuperTenantSubscriptionEndpoint extends SubscriptionEndpoint { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: " + session.getId() + ", for the Stream:" + streamName); } - Map> httpHeaders; - httpHeaders = (Map>) config.getUserProperties().get(Constants.HTTP_HEADERS); + Map> sessionQueryParam = new HashedMap(); + List sessionQueryParamList = new LinkedList<>(); + sessionQueryParamList.add(session.getQueryString()); + sessionQueryParam.put(Constants.QUERY_STRING, sessionQueryParamList); Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); - AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(httpHeaders); + AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(sessionQueryParam); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java index 6203f8888d..099200c463 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/TenantSubscriptionEndpoint.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint; +import org.apache.commons.collections.map.HashedMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; @@ -37,6 +38,7 @@ import javax.websocket.OnOpen; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -63,10 +65,12 @@ public class TenantSubscriptionEndpoint extends SubscriptionEndpoint { if (log.isDebugEnabled()) { log.debug("WebSocket opened, for Session id: "+session.getId()+", for the Stream:"+streamName); } - Map> httpHeaders; - httpHeaders = (Map>) config.getUserProperties().get(Constants.HTTP_HEADERS); + Map> sessionQueryParam = new HashedMap(); + List sessionQueryParamList = new LinkedList<>(); + sessionQueryParamList.add(session.getQueryString()); + sessionQueryParam.put(Constants.QUERY_STRING, sessionQueryParamList); Authenticator authenticator = ServiceHolder.getWebsocketValidationService().getAuthenticator(); - AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(httpHeaders); + AuthenticationInfo authenticationInfo = authenticator.isAuthenticated(sessionQueryParam); if (authenticationInfo != null && authenticationInfo.isAuthenticated()) { Authorizer authorizer = ServiceHolder.getWebsocketValidationService().getAuthorizer(); boolean isAuthorized = authorizer.isAuthorized(authenticationInfo, session, streamName); diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java index 14b4e968c5..fb8b7d684d 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/endpoint/constants/Constants.java @@ -22,4 +22,5 @@ package org.wso2.carbon.device.mgt.output.adapter.websocket.endpoint.constants; public class Constants { public static final String HTTP_HEADERS = "HttpHeaders"; + public static final String QUERY_STRING = "queryString"; } diff --git a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java index 55566963ca..f41eb914e1 100644 --- a/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java +++ b/components/extensions/cdmf-transport-adapters/output/org.wso2.carbon.device.mgt.output.adapter.websocket/src/main/java/org/wso2/carbon/device/mgt/output/adapter/websocket/authentication/oauth/OAuthTokenValdiator.java @@ -45,7 +45,10 @@ public class OAuthTokenValdiator { private static final String COOKIE_KEYPAIR_SEPERATOR = ";"; private static final String COOKIE = "cookie"; private static final String TOKEN_TYPE = "bearer"; - private static final String TOKEN_IDENTIFIER = "websocket-token"; + private static final String TOKEN_IDENTIFIER = "websocketToken"; + private static final String QUERY_STRING_SEPERATOR = "&"; + private static final String QUERY_KEY_VALUE_SEPERATOR = "="; + private static final String QUERY_STRING = "queryString"; private static OAuthTokenValdiator oAuthTokenValdiator; @@ -59,7 +62,7 @@ public class OAuthTokenValdiator { * @return AuthenticationInfo with the validated results. */ public AuthenticationInfo validateToken(Map> webSocketConnectionProperties) { - String token = getToken(webSocketConnectionProperties); + String token = getTokenFromSession(webSocketConnectionProperties); if (token == null) { AuthenticationInfo authenticationInfo = new AuthenticationInfo(); authenticationInfo.setAuthenticated(false); @@ -168,4 +171,27 @@ public class OAuthTokenValdiator { log.error("WebSocket token should be specified in cookie"); return null; } + + /** + * Retrieving the token from the http session + * @param webSocketConnectionProperties WebSocket connection information including http headers + * @return retrieved token + */ + private String getTokenFromSession(Map> webSocketConnectionProperties) { + String queryString = webSocketConnectionProperties.get(QUERY_STRING).get(0); + if (queryString != null) { + String[] allQueryParamPairs = queryString.split(QUERY_STRING_SEPERATOR); + for (String keyValuePair : allQueryParamPairs) { + String[] queryParamPair = keyValuePair.split(QUERY_KEY_VALUE_SEPERATOR); + if (queryParamPair.length != 2) { + log.warn("Invalid query string [" + queryString + "] passed in."); + break; + } + if (queryParamPair[0].equals(TOKEN_IDENTIFIER)) { + return queryParamPair[1]; + } + } + } + return null; + } }