From 274d3e9aeb1414ba6cd4c61363c7d131e7c6c67c Mon Sep 17 00:00:00 2001
From: ayyoob
Date: Sat, 4 Feb 2017 20:51:56 +0530
Subject: [PATCH] used jwt grant type instead of saml
---
.../pom.xml | 4 +-
.../src/test/resources/sample.xml | 8 +-
.../devicemgt/app/modules/login.js | 6 +-
.../app/modules/oauth/token-handler-utils.js | 82 +++++++------------
.../app/modules/oauth/token-handlers.js | 45 ++++++++++
.../app/units/cdmf.unit.footer/footer.hbs | 4 +-
.../uuf-template-app/lib/modules/auth/auth.js | 70 ++++++++++++++++
.../pom.xml | 5 ++
.../grant/ExtendedJWTGrantHandler.java | 51 ++++++++++++
.../jwt/client/extension/JWTClient.java | 30 ++++++-
.../extension/constant/JWTConstants.java | 1 +
.../client/extension/dto/AccessTokenInfo.java | 9 ++
.../pom.xml | 4 +-
.../src/main/resources/conf/cdm-config.xml | 9 +-
.../src/main/resources/jwt.properties | 2 +-
pom.xml | 8 +-
16 files changed, 263 insertions(+), 75 deletions(-)
create mode 100644 components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml
index f8e67e64b9d..5a9ada7d421 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml
@@ -14,13 +14,13 @@
apimgt-extensions
org.wso2.carbon.devicemgt
- 2.0.14-SNAPSHOT
+ 2.0.16-SNAPSHOT
../pom.xml
4.0.0
org.wso2.carbon.apimgt.integration.client
- 2.0.14-SNAPSHOT
+ 2.0.16-SNAPSHOT
bundle
WSO2 Carbon - API Management Integration Client
WSO2 Carbon - API Management Integration Client
diff --git a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.device.type.deployer/src/test/resources/sample.xml b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.device.type.deployer/src/test/resources/sample.xml
index aa18e5d03b7..6542d9629b2 100644
--- a/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.device.type.deployer/src/test/resources/sample.xml
+++ b/components/device-mgt-extensions/org.wso2.carbon.device.mgt.extensions.device.type.deployer/src/test/resources/sample.xml
@@ -36,10 +36,10 @@
-
+
false
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/login.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/login.js
index d36e7af0ab8..166859f89b4 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/login.js
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/login.js
@@ -26,7 +26,11 @@ var onFail;
var utility = require("/app/modules/utility.js").utility;
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
if (context.input.samlToken) {
- apiWrapperUtil.setupTokenPairBySamlGrantType(context.user.username + '@' + context.user.domain, context.input.samlToken);
+ //apiWrapperUtil.setupTokenPairBySamlGrantType(context.user.username + '@' + context.user.domain, context.input.samlToken);
+ /**
+ * Since the user can be verified using the sso.client.js we can use JWT grant type to issue the token for the user.
+ */
+ apiWrapperUtil.setupTokenPairByJWTGrantType(context.user.username + '@' + context.user.domain, context.input.samlToken);
} else {
apiWrapperUtil.setupTokenPairByPasswordGrantType(context.input.username, context.input.password);
}
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-handler-utils.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-handler-utils.js
index b31febe79a2..109e67f7ac7 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-handler-utils.js
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/oauth/token-handler-utils.js
@@ -22,6 +22,7 @@ var utils = function () {
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var carbon = require("carbon");
+ var authModule = require("/lib/modules/auth/auth.js").module;
//noinspection JSUnresolvedVariable
var Base64 = Packages.org.apache.commons.codec.binary.Base64;
@@ -275,59 +276,34 @@ var utils = function () {
}
};
- publicMethods["getTokenPairAndScopesBySAMLGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
- if (!assertion || !encodedClientAppCredentials || !scopes) {
- log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml " +
- "grant type. No assertion, encoded client app credentials or scopes are " +
- "found - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
- return null;
- } else {
- var assertionXML = publicMethods.decode(assertion);
- /*
- TODO: make assertion extraction with proper parsing.
- Since Jaggery XML parser seem to add formatting which causes signature verification to fail.
- */
- var assertionStartMarker = "
- WSO2 Carbon Device Management Framework v2.0.6
- WSO2 CDMF v2.0.6 | © ,
+ WSO2 IoT Server 3.1.0
+ WSO2 IoT Server 3.1.0 | © ,
Inc. All Rights Reserved.
{{/zone}}
\ No newline at end of file
diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/lib/modules/auth/auth.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/lib/modules/auth/auth.js
index 93cffdbf862..fad0b27b99e 100644
--- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/lib/modules/auth/auth.js
+++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/lib/modules/auth/auth.js
@@ -565,6 +565,76 @@ var module = {};
}
};
+
+ /**
+ * saml token validation Service.
+ * @param request {Object} HTTP request
+ * @param response {Object} HTTP response
+ */
+ module.ssoLogin = function (samlToken) {
+ var samlResponse = samlToken;
+ var ssoClient = require("sso").client;
+ var samlResponseObj;
+
+ if (samlResponse) {
+ try {
+ samlResponseObj = ssoClient.getSamlObject(samlResponse);
+ } catch (e) {
+ log.error(e.message, e);
+ return;
+ }
+
+ // This is a login response.
+ var ssoConfigs = getSsoConfigurations();
+ var CarbonUtils = Packages.org.wso2.carbon.utils.CarbonUtils;
+ var keyStorePassword = CarbonUtils.getServerConfiguration().getFirstProperty("Security.TrustStore.Password");
+ var keyStoreName = CarbonUtils.getServerConfiguration().getFirstProperty("Security.TrustStore.Location");
+ var identityAlias = ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_IDENTITY_ALIAS];
+ var keyStoreParams = {
+ KEY_STORE_NAME: keyStoreName,
+ KEY_STORE_PASSWORD: keyStorePassword,
+ IDP_ALIAS: identityAlias
+ };
+ var rsEnabled = ssoConfigs[constants.APP_CONF_AUTH_MODULE_SSO_RESPONSE_SIGNING_ENABLED];
+ if (utils.parseBoolean(rsEnabled)) {
+ if (!ssoClient.validateSignature(samlResponseObj, keyStoreParams)) {
+ var msg = "Invalid signature found in the SAML response.";
+ log.error(msg);
+ return;
+ }
+ }
+
+ if (!ssoClient.validateSamlResponse(samlResponseObj, ssoConfigs, keyStoreParams)) {
+ var msg = "Invalid SAML response found.";
+ log.error(msg);
+ return;
+ }
+
+ /**
+ * @type {{sessionId: string, loggedInUser: string, sessionIndex: string, samlToken:
+ * string}}
+ */
+ var ssoSession = ssoClient.decodeSAMLLoginResponse(samlResponseObj, samlResponse,
+ session.getId());
+ if (ssoSession.sessionId) {
+ var ssoSessions = getSsoSessions();
+ ssoSessions[ssoSession.sessionId] = ssoSession;
+ if (ssoSession.sessionIndex) {
+ var carbonUser = (require("carbon")).server.tenantUser(ssoSession.loggedInUser);
+ utils.setCurrentUser(carbonUser.username, carbonUser.domain, carbonUser.tenantId);
+ module.loadTenant(ssoSession.loggedInUser);
+ var user = {user: module.getCurrentUser()};
+ return user;
+ }
+ } else {
+ var msg = "Cannot decode SAML login response.";
+ log.error(msg);
+ return;
+ }
+
+ }
+ };
+
/**
* Load current user tenant
* @param username logged user name
diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml
index 75239f0fb2a..7406555132b 100644
--- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml
+++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml
@@ -58,6 +58,10 @@
org.wso2.carbon.identity.framework
org.wso2.carbon.user.mgt
+
+ org.wso2.carbon.identity
+ org.wso2.carbon.identity.oauth2.grant.jwt
+
@@ -83,6 +87,7 @@
org.wso2.carbon.device.mgt.oauth.extensions.*
+ org.wso2.carbon.identity.oauth2.grant.jwt;version="${carbon.identity.jwt.grant.version.range}",
org.apache.commons.logging,
org.osgi.service.component,
org.wso2.carbon.identity.application.common.model;version="${carbon.identity.framework.version.range}",
diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java
new file mode 100644
index 00000000000..90bba018517
--- /dev/null
+++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
+ *
+ * WSO2 Inc. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.keymgt.ScopesIssuer;
+import org.wso2.carbon.base.MultitenantConstants;
+import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser;
+import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception;
+import org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler;
+import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
+import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
+
+/**
+ * This sets up user with tenant aware username.
+ */
+@SuppressWarnings("unused")
+public class ExtendedJWTGrantHandler extends JWTBearerGrantHandler {
+ private static Log log = LogFactory.getLog(ExtendedJWTGrantHandler.class);
+
+ @Override
+ public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
+ return ScopesIssuer.getInstance().setScopes(tokReqMsgCtx);
+ }
+
+ @Override
+ public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception {
+ /**
+ * This is added to skip per tenant IDP creation.
+ */
+ tokReqMsgCtx.getOauth2AccessTokenReqDTO().setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
+ return super.validateGrant(tokReqMsgCtx);
+ }
+}
diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java
index ad7d5470901..dc51a2c9df6 100644
--- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java
+++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/JWTClient.java
@@ -80,6 +80,25 @@ public class JWTClient {
return getTokenInfo(params, consumerKey, consumerSecret);
}
+ public AccessTokenInfo getAccessToken(String encodedAppcredential, String username, String scopes)
+ throws JWTClientException {
+ List params = new ArrayList<>();
+ params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType()));
+ String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient);
+ if (assertion == null) {
+ throw new JWTClientException("JWT is not configured properly for user : " + username);
+ }
+ params.add(new BasicNameValuePair(JWTConstants.JWT_PARAM_NAME, assertion));
+ if (scopes != null && !scopes.isEmpty()) {
+ params.add(new BasicNameValuePair(JWTConstants.SCOPE_PARAM_NAME, scopes));
+ }
+ String decodedKey[] = getDecodedKey(encodedAppcredential);
+ if (decodedKey.length != 2) {
+ throw new JWTClientException("Invalid app credential");
+ }
+ return getTokenInfo(params, decodedKey[0], decodedKey[1]);
+ }
+
public AccessTokenInfo getAccessToken(String consumerKey, String consumerSecret, String username, String scopes,
Map paramsMap)
throws JWTClientException {
@@ -137,9 +156,12 @@ public class JWTClient {
String accessToken = (String) jsonObject.get(JWTConstants.ACCESS_TOKEN_GRANT_TYPE_PARAM_NAME);
if (accessToken != null && !accessToken.isEmpty()) {
accessTokenInfo.setAccessToken(accessToken);
- accessTokenInfo.setRefreshToken((String) jsonObject.get(JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME));
+ accessTokenInfo.setRefreshToken((String) jsonObject.get(
+ JWTConstants.REFRESH_TOKEN_GRANT_TYPE_PARAM_NAME));
accessTokenInfo.setExpiresIn((Long) jsonObject.get(JWTConstants.OAUTH_EXPIRES_IN));
accessTokenInfo.setTokenType((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_TYPE));
+ accessTokenInfo.setScopes((String) jsonObject.get(JWTConstants.OAUTH_TOKEN_SCOPE));
+
}
return accessTokenInfo;
} catch (MalformedURLException e) {
@@ -161,7 +183,11 @@ public class JWTClient {
return new String(Base64.encodeBase64((consumerKey + ":" + consumerSecret).getBytes()));
}
- public String getJwtToken(String username) throws JWTClientException {
+ private String[] getDecodedKey(String encodedKey) {
+ return (new String(Base64.decodeBase64((encodedKey).getBytes()))).split(":");
+ }
+
+ public String getJwtToken(String username) throws JWTClientException {
return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient);
}
diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java
index ab6a4b142d1..998813054a3 100644
--- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java
+++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/constant/JWTConstants.java
@@ -23,6 +23,7 @@ package org.wso2.carbon.identity.jwt.client.extension.constant;
public class JWTConstants {
public static final String OAUTH_EXPIRES_IN = "expires_in";
public static final String OAUTH_TOKEN_TYPE = "token_type";
+ public static final String OAUTH_TOKEN_SCOPE = "scope";
public static final String JWT_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
public static final String GRANT_TYPE_PARAM_NAME = "grant_type";
public static final String REFRESH_TOKEN_GRANT_TYPE = "refresh_token";
diff --git a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java
index c1adb813fd4..a0240dc8189 100644
--- a/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java
+++ b/components/identity-extensions/org.wso2.carbon.identity.jwt.client.extension/src/main/java/org/wso2/carbon/identity/jwt/client/extension/dto/AccessTokenInfo.java
@@ -27,6 +27,7 @@ public class AccessTokenInfo {
private long expiresIn;
private String refreshToken;
private String accessToken;
+ private String scopes;
public String getTokenType() {
return tokenType;
@@ -59,4 +60,12 @@ public class AccessTokenInfo {
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
+
+ public String getScopes() {
+ return scopes;
+ }
+
+ public void setScopes(String scopes) {
+ this.scopes = scopes;
+ }
}
diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml
index 15c8f907397..e6c65be7614 100644
--- a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml
+++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml
@@ -22,13 +22,13 @@
org.wso2.carbon.devicemgt
apimgt-extensions-feature
- 2.0.14-SNAPSHOT
+ 2.0.16-SNAPSHOT
../pom.xml
4.0.0
org.wso2.carbon.apimgt.integration.client.feature
- 2.0.14-SNAPSHOT
+ 2.0.16-SNAPSHOT
pom
WSO2 Carbon - APIM Integration Client Feature
http://wso2.org
diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/cdm-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/cdm-config.xml
index e48531dd83a..c747b4354c6 100644
--- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/cdm-config.xml
+++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/cdm-config.xml
@@ -28,8 +28,8 @@
org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.GCMBasedPushNotificationProvider
-
-
+ org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider
+ org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider
https://localhost:9443
@@ -47,11 +47,6 @@
Simple
-
- android
- ios
- windows
-
diff --git a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties
index 3c384655811..b0d9a4c18d7 100644
--- a/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties
+++ b/features/jwt-client/org.wso2.carbon.identity.jwt.client.extension.feature/src/main/resources/jwt.properties
@@ -19,7 +19,7 @@
#issuer of the JWT
iss=wso2.org/products/iot
-TokenEndpoint=https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token
+TokenEndpoint=https://${iot.gateway.host}:${iot.gateway.https.port}/token
#audience of JWT claim
#comma seperated values
diff --git a/pom.xml b/pom.xml
index 1c40349604c..9bbaf653fa0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -909,6 +909,11 @@
org.wso2.carbon.identity.oauth.stub
${identity.inbound.auth.oauth.version}
+
+ org.wso2.carbon.identity
+ org.wso2.carbon.identity.oauth2.grant.jwt
+ ${carbon.identity.jwt.grant.version}
+
org.wso2.carbon.identity.framework
org.wso2.carbon.identity.application.authentication.framework
@@ -1769,7 +1774,8 @@
[5.0.0, 6.0.0)
5.3.1
5.3.0
-
+ 1.0.2
+ [1.0.2, 2.0.0)
[5.7.0, 6.0.0)
[5.2.0, 6.0.0)