used jwt grant type instead of saml

revert-70aa11f8
ayyoob 8 years ago
parent 559fe98cc9
commit 274d3e9aeb

@ -14,13 +14,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>2.0.14-SNAPSHOT</version>
<version>2.0.16-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client</artifactId>
<version>2.0.14-SNAPSHOT</version>
<version>2.0.16-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -36,10 +36,10 @@
</Feature>
</Features>
<!-- <Sensors table-id="SAMPLE_DEVICE_2">
<Sensors table-id="SAMPLE_DEVICE_2">
<Sensor code="CPU_Temperature">
<Name>temperature sensor fitted</Name>
<StreamDefinition>org.wso2.temperature.stream<StreamDefinition>
<StreamDefinition>org.wso2.temperature.stream</StreamDefinition>
<Description>this is a sensor</Description>
<SensorStaticProperties>
<Property name="unit">celcius</Property>
@ -48,7 +48,7 @@
</Sensor>
<Sensor code="DHT11_Temperature">
<Name>temperature sensor fitted</Name>
<StreamDefinition>org.wso2.temperature.stream<StreamDefinition>
<StreamDefinition>org.wso2.temperature.stream</StreamDefinition>
<Description>this is a sensor</Description>
<SensorStaticProperties>
<Property name="unit">celcius</Property>
@ -57,7 +57,7 @@
<Property name="model_number"/>
</SensorDynamicProperties>
</Sensor>
</Sensors> -->
</Sensors>
<ProvisioningConfig>
<SharedWithAllTenants>false</SharedWithAllTenants>

@ -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);
}

@ -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 = "<saml2:Assertion";
var assertionEndMarker = "<\/saml2:Assertion>";
var assertionStartIndex = assertionXML.indexOf(assertionStartMarker);
var assertionEndIndex = assertionXML.indexOf(assertionEndMarker);
var extractedAssertion;
if (assertionStartIndex == -1 || assertionEndIndex == -1) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access " +
"token by saml grant type. Issue in assertion format - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
return null;
} else {
extractedAssertion = assertionXML.
substring(assertionStartIndex, assertionEndIndex) + assertionEndMarker;
var encodedAssertion = publicMethods.encode(extractedAssertion);
// calling oauth provider token service endpoint
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
var requestPayload = "grant_type=" + deviceMgtProps["oauthProvider"]["appRegistration"]["samlGrantTypeName"]
+ "&" + "assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes;
var xhr = new XMLHttpRequest();
xhr.open("POST", requestURL, false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
xhr.send(requestPayload);
if (xhr["status"] == 200 && xhr["responseText"]) {
var responsePayload = parse(xhr["responseText"]);
var tokenData = {};
tokenData["accessToken"] = responsePayload["access_token"];
tokenData["refreshToken"] = responsePayload["refresh_token"];
tokenData["scopes"] = responsePayload["scope"];
return tokenData;
} else {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
"by password grant type - getTokenPairAndScopesBySAMLGrantType(x, y, z)");
return null;
}
}
}
};
publicMethods["getTokenPairAndScopesByJWTGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
if (!assertion || !encodedClientAppCredentials || !scopes) {
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by jwt " +
"grant type. No assertion, encoded client app credentials or scopes are " +
"found - getTokenPairAndScopesByJWTGrantType(x, y, z)");
return null;
} else {
var ssoLoginUser = authModule.ssoLogin(assertion);
if (!ssoLoginUser.user.username) {
return null;
}
var endUsername = ssoLoginUser.user.username + "@" + ssoLoginUser.user.domain;
var JWTClientManagerServicePackagePath =
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
//noinspection JSUnresolvedFunction
var jwtClient = JWTClientManagerService.getJWTClient();
// returning access token by JWT grant type
var tokenInfo = jwtClient.getAccessToken(encodedClientAppCredentials,
endUsername, scopes);
var tokenData = {};
tokenData["accessToken"] = tokenInfo.getAccessToken();
tokenData["refreshToken"] = tokenInfo.getRefreshToken();
tokenData["scopes"] = tokenInfo.getScopes();
return tokenData;
}
};
publicMethods["getNewTokenPairByRefreshToken"] = function (refreshToken, encodedClientAppCredentials, scopes) {
if (!refreshToken || !encodedClientAppCredentials) {

@ -121,6 +121,51 @@ var handlers = function () {
}
};
publicMethods["setupTokenPairByJWTGrantType"] = function (username, samlToken) {
//samlToken is used to validate then if the user is a valid user then token is issued with JWT Grant Type.
if (!username || !samlToken) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
"saml grant type. Either username of logged in user, samlToken or both are missing " +
"as input - setupTokenPairBySamlGrantType(x, y)");
} else {
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
privateMethods.setUpEncodedTenantBasedWebSocketClientAppCredentials(username);
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
if (!encodedClientAppCredentials) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
"by saml grant type. Encoded client credentials are " +
"missing - setupTokenPairBySamlGrantType(x, y)");
} else {
var tokenData;
var arrayOfScopes = devicemgtProps["scopes"];
arrayOfScopes = arrayOfScopes.concat(utility.getDeviceTypesScopesList());
var stringOfScopes = "";
arrayOfScopes.forEach(function (entry) {
stringOfScopes += entry + " ";
});
// accessTokenPair will include current access token as well as current refresh token
tokenData = tokenUtil.
getTokenPairAndScopesByJWTGrantType(samlToken, encodedClientAppCredentials, stringOfScopes);
if (!tokenData) {
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up token " +
"pair by password grant type. Error in token " +
"retrieval - setupTokenPairBySamlGrantType(x, y)");
} else {
var tokenPair = {};
tokenPair["accessToken"] = tokenData["accessToken"];
tokenPair["refreshToken"] = tokenData["refreshToken"];
// setting up access token pair into session context as a string
session.put(constants["TOKEN_PAIR"], stringify(tokenPair));
var scopes = tokenData.scopes.split(" ");
// adding allowed scopes to the session
session.put(constants["ALLOWED_SCOPES"], scopes);
}
}
}
};
publicMethods["refreshTokenPair"] = function () {
var currentTokenPair = parse(session.get(constants["TOKEN_PAIR"]));
// currentTokenPair includes current access token as well as current refresh token

@ -17,8 +17,8 @@
}}
{{#zone "footer"}}
<p>
<span class="hidden-xs">WSO2 Carbon Device Management Framework v2.0.6</span>
<span class="visible-xs-inline">WSO2 CDMF v2.0.6</span> | &copy; <script>document.write(new Date().getFullYear());</script>,
<span class="hidden-xs">WSO2 IoT Server 3.1.0</span>
<span class="visible-xs-inline">WSO2 IoT Server 3.1.0</span> | &copy; <script>document.write(new Date().getFullYear());</script>,
<a href="http://wso2.com/" target="_blank"><i class="icon fw fw-wso2"></i> Inc</a>. All Rights Reserved.
</p>
{{/zone}}

@ -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

@ -58,6 +58,10 @@
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.user.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth2.grant.jwt</artifactId>
</dependency>
</dependencies>
<build>
@ -83,6 +87,7 @@
org.wso2.carbon.device.mgt.oauth.extensions.*
</Export-Package>
<Import-Package>
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}",

@ -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);
}
}

@ -80,6 +80,25 @@ public class JWTClient {
return getTokenInfo(params, consumerKey, consumerSecret);
}
public AccessTokenInfo getAccessToken(String encodedAppcredential, String username, String scopes)
throws JWTClientException {
List<NameValuePair> 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<String, String> 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);
}

@ -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";

@ -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;
}
}

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>apimgt-extensions-feature</artifactId>
<version>2.0.14-SNAPSHOT</version>
<version>2.0.16-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client.feature</artifactId>
<version>2.0.14-SNAPSHOT</version>
<version>2.0.16-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - APIM Integration Client Feature</name>
<url>http://wso2.org</url>

@ -28,8 +28,8 @@
<PushNotificationProviders>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.gcm.GCMBasedPushNotificationProvider</Provider>
<!--<Provider>org.wso2.carbon.device.mgt.mobile.impl.ios.apns.APNSBasedPushNotificationProvider</Provider>-->
<!--<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider>-->
<!--<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>-->
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.mqtt.MQTTBasedPushNotificationProvider</Provider>
<Provider>org.wso2.carbon.device.mgt.extensions.push.notification.provider.xmpp.XMPPBasedPushNotificationProvider</Provider>
</PushNotificationProviders>
<IdentityConfiguration>
<ServerUrl>https://localhost:9443</ServerUrl>
@ -47,11 +47,6 @@
<!--Simple -> Simple policy evaluation point-->
<!--Merged -> Merged policy evaluation point -->
<PolicyEvaluationPoint>Simple</PolicyEvaluationPoint>
<Platforms>
<Platform>android</Platform>
<Platform>ios</Platform>
<Platform>windows</Platform>
</Platforms>
</PolicyConfiguration>
<!--<TaskConfiguration>-->
<!--<Enable>true</Enable>-->

@ -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

@ -909,6 +909,11 @@
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
<version>${identity.inbound.auth.oauth.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.oauth2.grant.jwt</artifactId>
<version>${carbon.identity.jwt.grant.version}</version>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.application.authentication.framework</artifactId>
@ -1769,7 +1774,8 @@
<carbon.identity.framework.version.range>[5.0.0, 6.0.0)</carbon.identity.framework.version.range>
<identity.inbound.auth.oauth.version>5.3.1</identity.inbound.auth.oauth.version>
<identity.inbound.auth.saml.version>5.3.0</identity.inbound.auth.saml.version>
<carbon.identity.jwt.grant.version>1.0.2</carbon.identity.jwt.grant.version>
<carbon.identity.jwt.grant.version.range>[1.0.2, 2.0.0)</carbon.identity.jwt.grant.version.range>
<!-- Carbon Identity import version ranges -->
<carbon.identity.imp.pkg.version>[5.7.0, 6.0.0)</carbon.identity.imp.pkg.version>
<carbon.identity-inbound-auth-oauth.imp.pkg.version>[5.2.0, 6.0.0)</carbon.identity-inbound-auth-oauth.imp.pkg.version>

Loading…
Cancel
Save