Fixing multitenant issue in certificate verification endpoint

4.x.x
Madawa Soysa 8 years ago
parent bfb2189466
commit a7e61318b8

@ -19,7 +19,7 @@
package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans;
public class ValidationResponce { public class ValidationResponse {
private String JWTToken; // X-JWT-Assertion private String JWTToken; // X-JWT-Assertion
private String deviceId; private String deviceId;

@ -1,3 +1,21 @@
/*
* Copyright (c) 2016-2017, 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.certificate.mgt.cert.jaxrs.api.impl; package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -6,7 +24,7 @@ import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdmin
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.CertificateList; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.CertificateList;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ValidationResponce; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ValidationResponse;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.CertificateMgtAPIUtils; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.CertificateMgtAPIUtils;
import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.RequestValidationUtil; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.RequestValidationUtil;
import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse;
@ -232,30 +250,41 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
deviceIdentifier.setId(challengeToken); deviceIdentifier.setId(challengeToken);
deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier);
//
// var claims = {"http://wso2.org/claims/enduserTenantId": adminUserTenantId,
// "http://wso2.org/claims/enduser": adminUsername};
Map<String, String> claims = new HashMap<>(); Map<String, String> claims = new HashMap<>();
claims.put("http://wso2.org/claims/enduserTenantId", String.valueOf(tenantedDeviceWrapper.getTenantId())); claims.put("http://wso2.org/claims/enduserTenantId",
claims.put("http://wso2.org/claims/enduser", tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner()); String.valueOf(tenantedDeviceWrapper.getTenantId()));
claims.put("http://wso2.org/claims/deviceIdentifier", tenantedDeviceWrapper.getDevice().getDeviceIdentifier()); claims.put("http://wso2.org/claims/enduser",
tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner() + "@"
+ tenantedDeviceWrapper.getTenantDomain());
claims.put("http://wso2.org/claims/deviceIdentifier",
tenantedDeviceWrapper.getDevice().getDeviceIdentifier());
claims.put("http://wso2.org/claims/deviceIdType", tenantedDeviceWrapper.getDevice().getType()); claims.put("http://wso2.org/claims/deviceIdType", tenantedDeviceWrapper.getDevice().getType());
JWTClientManagerService jwtClientManagerService = CertificateMgtAPIUtils.getJwtClientManagerService(); String jwdToken;
String jwdToken = jwtClientManagerService.getJWTClient().getJwtToken( try {
tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner(), claims); PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext()
.setTenantId(tenantedDeviceWrapper.getTenantId());
PrivilegedCarbonContext.getThreadLocalCarbonContext()
.setTenantDomain(tenantedDeviceWrapper.getTenantDomain());
JWTClientManagerService jwtClientManagerService = CertificateMgtAPIUtils
.getJwtClientManagerService();
jwdToken = jwtClientManagerService.getJWTClient()
.getJwtToken(tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner(), claims,
true);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
ValidationResponce validationResponce = new ValidationResponce(); ValidationResponse validationResponse = new ValidationResponse();
validationResponce.setDeviceId(challengeToken); validationResponse.setDeviceId(challengeToken);
validationResponce.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); validationResponse.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS);
validationResponce.setJWTToken(jwdToken); validationResponse.setJWTToken(jwdToken);
validationResponce.setTenantId(tenantedDeviceWrapper.getTenantId()); validationResponse.setTenantId(tenantedDeviceWrapper.getTenantId());
if (tenantedDeviceWrapper != null) { return Response.status(Response.Status.OK).entity(validationResponse).build();
return Response.status(Response.Status.OK).entity(validationResponce).build();
}
} }
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * Copyright (c) 2016-2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* *
* WSO2 Inc. licenses this file to you under the Apache License, * WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except * Version 2.0 (the "License"); you may not use this file except
@ -29,7 +29,7 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair; import org.apache.http.message.BasicNameValuePair;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;; import org.json.simple.parser.ParseException;
import org.wso2.carbon.identity.jwt.client.extension.constant.JWTConstants; import org.wso2.carbon.identity.jwt.client.extension.constant.JWTConstants;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig; import org.wso2.carbon.identity.jwt.client.extension.dto.JWTConfig;
@ -43,10 +43,11 @@ import java.security.KeyManagementException;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
;
/** /**
* this class represents an implementation of Token Client which is based on JWT * this class represents an implementation of Token Client which is based on JWT
*/ */
@ -69,7 +70,7 @@ public class JWTClient {
throws JWTClientException { throws JWTClientException {
List<NameValuePair> params = new ArrayList<>(); List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType())); params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType()));
String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient); String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, false);
if (assertion == null) { if (assertion == null) {
throw new JWTClientException("JWT is not configured properly for user : " + username); throw new JWTClientException("JWT is not configured properly for user : " + username);
} }
@ -84,7 +85,7 @@ public class JWTClient {
throws JWTClientException { throws JWTClientException {
List<NameValuePair> params = new ArrayList<>(); List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType())); params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType()));
String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient); String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, false);
if (assertion == null) { if (assertion == null) {
throw new JWTClientException("JWT is not configured properly for user : " + username); throw new JWTClientException("JWT is not configured properly for user : " + username);
} }
@ -104,7 +105,7 @@ public class JWTClient {
throws JWTClientException { throws JWTClientException {
List<NameValuePair> params = new ArrayList<>(); List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType())); params.add(new BasicNameValuePair(JWTConstants.GRANT_TYPE_PARAM_NAME, jwtConfig.getJwtGrantType()));
String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient); String assertion = JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, false);
if (assertion == null) { if (assertion == null) {
throw new JWTClientException("JWT is not configured properly for user : " + username); throw new JWTClientException("JWT is not configured properly for user : " + username);
} }
@ -188,13 +189,16 @@ public class JWTClient {
} }
public String getJwtToken(String username) throws JWTClientException { public String getJwtToken(String username) throws JWTClientException {
return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient); return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, false);
} }
public String getJwtToken(String username, Map<String, String> claims) throws JWTClientException { public String getJwtToken(String username, Map<String, String> claims) throws JWTClientException {
return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, claims); return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, claims, false);
} }
public String getJwtToken(String username, Map<String, String> claims, boolean isTenantMode) throws JWTClientException {
return JWTClientUtil.generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, claims, isTenantMode);
}
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * Copyright (c) 2016-2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* *
* WSO2 Inc. licenses this file to you under the Apache License, * WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except * Version 2.0 (the "License"); you may not use this file except
@ -33,7 +33,6 @@ import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.apache.solr.common.util.Hash;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.KeyStoreManager; import org.wso2.carbon.core.util.KeyStoreManager;
@ -49,14 +48,22 @@ import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.core.service.TenantRegistryLoader;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
import java.io.*; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.*; import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -200,15 +207,14 @@ public class JWTClientUtil {
tenantRegistryLoader.loadTenantRegistry(tenantId); tenantRegistryLoader.loadTenantRegistry(tenantId);
} }
public static String generateSignedJWTAssertion(String username, JWTConfig jwtConfig, boolean isDefaultJWTClient) public static String generateSignedJWTAssertion(String username, JWTConfig jwtConfig, boolean isDefaultJWTClient,
throws JWTClientException { boolean isMultiTenantMode) throws JWTClientException {
return generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, null); return generateSignedJWTAssertion(username, jwtConfig, isDefaultJWTClient, null, isMultiTenantMode);
} }
public static String generateSignedJWTAssertion(String username, JWTConfig jwtConfig, boolean isDefaultJWTClient, public static String generateSignedJWTAssertion(String username, JWTConfig jwtConfig, boolean isDefaultJWTClient,
Map<String, String> customClaims) throws JWTClientException { Map<String, String> customClaims, boolean isMultiTenantMode) throws JWTClientException {
try { try {
String subject = username;
long currentTimeMillis = System.currentTimeMillis(); long currentTimeMillis = System.currentTimeMillis();
// add the skew between servers // add the skew between servers
String iss = jwtConfig.getIssuer(); String iss = jwtConfig.getIssuer();
@ -246,26 +252,23 @@ public class JWTClientUtil {
String privateKeyAlias = jwtConfig.getPrivateKeyAlias(); String privateKeyAlias = jwtConfig.getPrivateKeyAlias();
String privateKeyPassword = jwtConfig.getPrivateKeyPassword(); String privateKeyPassword = jwtConfig.getPrivateKeyPassword();
KeyStore keyStore; KeyStore keyStore;
RSAPrivateKey rsaPrivateKey = null; RSAPrivateKey rsaPrivateKey;
if (keyStorePath != null && !keyStorePath.isEmpty()) { if (!isMultiTenantMode && (keyStorePath != null && !keyStorePath.isEmpty())) {
String keyStorePassword = jwtConfig.getKeyStorePassword(); String keyStorePassword = jwtConfig.getKeyStorePassword();
keyStore = loadKeyStore(new File(keyStorePath), keyStorePassword, "JKS"); keyStore = loadKeyStore(new File(keyStorePath), keyStorePassword, "JKS");
rsaPrivateKey = (RSAPrivateKey) keyStore.getKey(privateKeyAlias, privateKeyPassword.toCharArray()); rsaPrivateKey = (RSAPrivateKey) keyStore.getKey(privateKeyAlias, privateKeyPassword.toCharArray());
} else { } else {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
JWTClientUtil.loadTenantRegistry(tenantId); JWTClientUtil.loadTenantRegistry(tenantId);
if (!(MultitenantConstants.SUPER_TENANT_ID == tenantId) && !isDefaultJWTClient) { if (isMultiTenantMode || !(MultitenantConstants.SUPER_TENANT_ID == tenantId) && !isDefaultJWTClient) {
KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(tenantId); KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(tenantId);
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true); String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
String ksName = tenantDomain.trim().replace('.', '-'); String ksName = tenantDomain.trim().replace('.', '-');
String jksName = ksName + ".jks"; String jksName = ksName + ".jks";
rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getPrivateKey(jksName, tenantDomain); rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getPrivateKey(jksName, tenantDomain);
} else { } else {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(MultitenantConstants.SUPER_TENANT_ID);
KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID); KeyStoreManager tenantKeyStoreManager = KeyStoreManager.getInstance(MultitenantConstants.SUPER_TENANT_ID);
rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getDefaultPrivateKey(); rsaPrivateKey = (RSAPrivateKey) tenantKeyStoreManager.getDefaultPrivateKey();
PrivilegedCarbonContext.endTenantFlow();
} }
} }
JWSSigner signer = new RSASSASigner(rsaPrivateKey); JWSSigner signer = new RSASSASigner(rsaPrivateKey);

Loading…
Cancel
Save