From fe2b6b5993bdb08909e60aa0646e336bbc54789b Mon Sep 17 00:00:00 2001 From: amalhub Date: Wed, 7 Dec 2016 14:30:23 +0530 Subject: [PATCH 01/13] IOTS-292: Adding verification services needed for gataway handler --- .../CertificateManagementAdminService.java | 75 +++++++++++++++++++ ...CertificateManagementAdminServiceImpl.java | 71 ++++++++++++++++++ .../api/util/CertificateMgtAPIUtils.java | 17 +++++ 3 files changed, 163 insertions(+) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java index b867998c189..a273a52fd20 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -316,4 +316,79 @@ public interface CertificateManagementAdminService { defaultValue = "12438035315552875930") @PathParam("serialNumber") String serialNumber); + /** + * Verify IOS Certificate for the API security filter + * + * @param certificate to be verified as a String + * @return Status of the certificate verification. + */ + @POST + @Path("/verify/ios") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Verify IOS SSL certificate", + notes = "Verify IOS Certificate for the API security filter.\n", + tags = "Certificate Management") + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Return the status of the IOS certificate verification.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class) + }) + @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") + Response verifyIOSCertificate( + @ApiParam( + name = "certificate", + value = "The properties to verify certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. (optional) \n" + + "pem: mdm-signature of the certificate", + required = true) EnrollmentCertificate certificate); + + /** + * Verify Android Certificate for the API security filter + * + * @param certificate to be verified as a String + * @return Status of the certificate verification. + */ + @POST + @Path("/verify/android") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Verify Android SSL certificate", + notes = "Verify Android Certificate for the API security filter.\n", + tags = "Certificate Management") + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Return the status of the Android certificate verification.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class) + }) + @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") + Response verifyAndroidCertificate( + @ApiParam( + name = "certificate", + value = "The properties to verify certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. (optional) \n" + + "pem: pem String of the certificate", + required = true) EnrollmentCertificate certificate); } diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java index e0f0852787c..0b7b7210e88 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -1,5 +1,6 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl; +import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdminService; @@ -11,9 +12,14 @@ 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.exception.CertificateManagementException; import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPException; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; +import org.wso2.carbon.certificate.mgt.core.scep.TenantedDeviceWrapper; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.certificate.mgt.core.service.PaginationResult; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; import javax.ws.rs.*; import javax.ws.rs.core.Response; @@ -25,6 +31,7 @@ import java.util.List; public class CertificateManagementAdminServiceImpl implements CertificateManagementAdminService { private static Log log = LogFactory.getLog(CertificateManagementAdminServiceImpl.class); + private static final String PROXY_AUTH_MUTUAL_HEADER = "proxy-mutual-auth-header"; /** * Save a list of certificates and relevant information in the database. @@ -138,4 +145,68 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem } } + @POST + @Path("/verify/ios") + public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + + "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { + try { + CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); + X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); + String challengeToken = certMgtService.extractChallengeToken(cert); + + if (challengeToken != null) { + challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); + + SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(challengeToken); + deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); + + if (tenantedDeviceWrapper != null) { + return Response.status(Response.Status.OK).entity("valid").build(); + } + } + } catch (SCEPException e) { + String msg = "Error occurred while extracting information from certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("invalid").build(); + } + + @POST + @Path("/verify/android") + public Response verifyAndroidCertificate(@ApiParam(name = "certificate", value = "Base64 encoded .pem file of the " + + "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { + CertificateResponse certificateResponse = null; + try { + CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); + if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { + certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); + } else { + X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); + if (clientCertificate != null) { + certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); + } + } + + if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse + .getCommonName().isEmpty()) { + return Response.status(Response.Status.OK).entity("valid").build(); + } + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("invalid").build(); + } } \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java index a96b013b7b5..06bc3169fea 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java @@ -20,6 +20,7 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; @@ -50,6 +51,22 @@ public class CertificateMgtAPIUtils { } + public static SCEPManager getSCEPManagerService() { + + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SCEPManager scepManagerService = (SCEPManager) + ctx.getOSGiService(SCEPManager.class, null); + + if (scepManagerService == null) { + String msg = "SCEPManagerImpl Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return scepManagerService; + } + + public static MediaType getResponseMediaType(String acceptHeader) { MediaType responseMediaType; if (acceptHeader == null || MediaType.WILDCARD.equals(acceptHeader)) { From d00817268e9385a9bc1d69d18dd60aa87b986250 Mon Sep 17 00:00:00 2001 From: amalhub Date: Wed, 7 Dec 2016 17:30:38 +0530 Subject: [PATCH 02/13] IOTS-292: Adding the api-mgt handler for gateway change --- .../org.wso2.carbon.apimgt.handlers/pom.xml | 42 +++ .../AuthenticationHandler.java | 227 ++++++++++++ .../invoker/RESTConstants.java | 26 ++ .../invoker/RESTInvoker.java | 343 ++++++++++++++++++ .../invoker/RESTResponse.java | 81 +++++ .../utils/AuthConstants.java | 35 ++ .../utils/CoreUtils.java | 140 +++++++ .../src/main/resources/api-filter-config.xml | 22 ++ components/apimgt-extensions/pom.xml | 1 + pom.xml | 4 + 10 files changed, 921 insertions(+) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTConstants.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTResponse.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml new file mode 100644 index 00000000000..b8133bc6d81 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml @@ -0,0 +1,42 @@ + + + + apimgt-extensions + org.wso2.carbon.devicemgt + 1.2.8-SNAPSHOT + + 4.0.0 + + org.wso2.carbon.apimgt.handlers + WSO2 Carbon - API Security Handler Component + + + + org.wso2.carbon + org.wso2.carbon.logging + ${carbon.kernel.version} + + + org.apache.synapse + synapse-core + ${org.apache.synapse.version} + + + org.apache.ws.security.wso2 + wss4j + ${org.apache.ws.security.wso2.version} + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + org.json.wso2 + json + ${commons-json.version} + + + + \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java new file mode 100644 index 00000000000..f5c5c800563 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java @@ -0,0 +1,227 @@ +/* + * 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.apimgt.handlers; + +import org.apache.axiom.soap.SOAP11Constants; +import org.apache.axiom.soap.SOAP12Constants; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.description.HandlerDescription; +import org.apache.axis2.description.Parameter; +import org.apache.axis2.engine.Handler; +import org.apache.axis2.namespace.Constants; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ws.security.WSConstants; +import org.apache.ws.security.WSSecurityException; +import org.apache.ws.security.util.Base64; +import org.json.JSONObject; +import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker; +import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse; +import org.wso2.carbon.apimgt.handlers.utils.AuthConstants; +import org.wso2.carbon.apimgt.handlers.utils.CoreUtils; + +import javax.xml.namespace.QName; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AuthenticationHandler implements Handler { + private static final Log log = LogFactory.getLog(AuthenticationHandler.class); + private static HandlerDescription EMPTY_HANDLER_METADATA = new HandlerDescription("API Security Handler"); + private HandlerDescription handlerDesc; + private ArrayList apiList; + private RESTInvoker restInvoker; + + /** + * Setting up configurations at the constructor + */ + public AuthenticationHandler() { + log.info("Engaging API Security Handler"); + apiList = CoreUtils.readApiFilterList(); + restInvoker = new RESTInvoker(); + this.handlerDesc = EMPTY_HANDLER_METADATA; + } + + /** + * Handles incoming http/s requests + * + * @param messageContext + * @return response + * @throws AxisFault + */ + public InvocationResponse invoke(MessageContext messageContext) throws AxisFault { + boolean validateRequest = messageContext.getTo() != null; + + if (validateRequest && isSecuredAPI(messageContext)) { + String ctxPath = messageContext.getTo().getAddress().trim(); + CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath); + Map headers = (Map) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS); + + if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { + String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); + + try { + CoreUtils.debugLog(log, "Verify Cert:\n", mdmSignature); + + URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/dynamic-client-web/register"); + String dcrContent = "{\n" + + "\"owner\":\"" + CoreUtils.getUsername() + "\",\n" + + "\"clientName\":\"emm\",\n" + + "\"grantType\":\"refresh_token password client_credentials\",\n" + + "\"tokenScope\":\"default\"\n" + + "}"; + Map drcHeaders = new HashMap(); + drcHeaders.put("Content-Type", "application/json"); + + RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null, + null, dcrContent); + CoreUtils.debugLog(log, "DCR response:", response.getContent()); + JSONObject jsonResponse = new JSONObject(response.getContent()); + String clientId = jsonResponse.getString("client_id"); + String clientSecret = jsonResponse.getString("client_secret"); + + URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/oauth2/token"); + String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" + + CoreUtils.getPassword() + "&scope=activity-view"; + String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); + Map tokenHeaders = new HashMap(); + tokenHeaders.put("Authorization", tokenBasicAuth); + tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); + + response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null, + null, tokenContent); + CoreUtils.debugLog(log, "Token response:", response.getContent()); + jsonResponse = new JSONObject(response.getContent()); + String accessToken = jsonResponse.getString("access_token"); + + URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); + Map certVerifyHeaders = new HashMap(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + String certVerifyContent = "{\n" + + "\"pem\":\"" + mdmSignature + "\",\n" + + "\"tenantId\": \"-1234\",\n" + + "\"serial\":\"\"\n" + + "}"; + + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + CoreUtils.debugLog(log, "Verify response:", response.getContent()); + + if (!response.getContent().contains("invalid")) { + return InvocationResponse.CONTINUE; + } + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); + return InvocationResponse.SUSPEND; + + } catch (Exception e) { + log.error("Error while processing certificate.", e); + setFaultCodeAndThrowAxisFault(messageContext, e); + return InvocationResponse.SUSPEND; + } + } else { + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required")); + return InvocationResponse.SUSPEND; + } + } else { + return InvocationResponse.CONTINUE; + } + + } + + /** + * API filter + * + * @param messageContext + * @return boolean + */ + private boolean isSecuredAPI(MessageContext messageContext) { + if (messageContext.getTransportIn() != null && + messageContext.getTransportIn().getName().toLowerCase().equals(AuthConstants.HTTPS)) { + for (String path : apiList) { + if (messageContext.getTo().getAddress().trim().contains(path)) { + return true; + } + } + } + return false; + } + + private void setFaultCodeAndThrowAxisFault(MessageContext msgContext, Exception e) throws AxisFault { + + msgContext.setProperty(AuthConstants.SEC_FAULT, Boolean.TRUE); + String soapVersionURI = msgContext.getEnvelope().getNamespace().getNamespaceURI(); + QName faultCode = null; + /* + * Get the faultCode from the thrown WSSecurity exception, if there is one + */ + if (e instanceof WSSecurityException) { + faultCode = ((WSSecurityException) e).getFaultCode(); + } + /* + * Otherwise default to InvalidSecurity + */ + if (faultCode == null) { + faultCode = new QName(WSConstants.INVALID_SECURITY.getNamespaceURI(), + WSConstants.INVALID_SECURITY.getLocalPart(), AuthConstants.WSSE); + } + + if (soapVersionURI.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) { + + throw new AxisFault(faultCode, e.getMessage(), e); + + } else if (soapVersionURI.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) { + + List subfaultCodes = new ArrayList(); + subfaultCodes.add(faultCode); + throw new AxisFault(Constants.FAULT_SOAP12_SENDER, subfaultCodes, e.getMessage(), e); + + } + + } + + public void cleanup() { + } + + public void init(HandlerDescription handlerDescription) { + this.handlerDesc = handlerDescription; + } + + public void flowComplete(MessageContext messageContext) { + } + + public HandlerDescription getHandlerDesc() { + return this.handlerDesc; + } + + public String getName() { + return "API security inflow handler"; + } + + public Parameter getParameter(String name) { + return this.handlerDesc.getParameter(name); + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTConstants.java new file mode 100644 index 00000000000..c1d0413a700 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTConstants.java @@ -0,0 +1,26 @@ +/* + * 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.apimgt.handlers.invoker; + +public class RESTConstants { + static String REST_CLIENT_CONFIG_ELEMENT = "restClientConfiguration"; + static String REST_CLIENT_MAX_TOTAL_CONNECTIONS = "maxTotalConnections"; + static String REST_CLIENT_MAX_CONNECTIONS_PER_ROUTE = "maxConnectionsPerRoute"; + static String REST_CLEINT_CONNECTION_TIMEOUT = "connectionTimeout"; + static String REST_CLEINT_SOCKET_TIMEOUT = "socketTimeout"; +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java new file mode 100644 index 00000000000..7873a7fc54e --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java @@ -0,0 +1,343 @@ +/* + * 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.apimgt.handlers.invoker; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.util.AXIOMUtil; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.*; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; +import org.wso2.carbon.apimgt.handlers.utils.AuthConstants; +import org.wso2.carbon.apimgt.handlers.utils.CoreUtils; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; +import java.util.Map; + +public class RESTInvoker { + + private static final Log log = LogFactory.getLog(RESTInvoker.class); + + private int maxTotalConnections = 100; + private int maxTotalConnectionsPerRoute = 100; + private int connectionTimeout = 120000; + private int socketTimeout = 120000; + + private CloseableHttpClient client = null; + private PoolingHttpClientConnectionManager connectionManager = null; + + public RESTInvoker() { + configureHttpClient(); + } + + private void parseConfiguration() { + String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); + String apiFilterConfigPath = carbonConfigDirPath + File.separator + + AuthConstants.AUTH_CONFIGURATION_FILE_NAME; + File configFile = new File(apiFilterConfigPath); + + try { + String configContent = FileUtils.readFileToString(configFile); + OMElement configElement = AXIOMUtil.stringToOM(configContent); + Iterator beans = configElement.getChildrenWithName( + new QName("http://www.springframework.org/schema/beans", "bean")); + + while (beans.hasNext()) { + OMElement bean = (OMElement) beans.next(); + String beanId = bean.getAttributeValue(new QName(null, "id")); + if (beanId.equals(RESTConstants.REST_CLIENT_CONFIG_ELEMENT)) { + Iterator beanProps = bean.getChildrenWithName( + new QName("http://www.springframework.org/schema/beans", "property")); + + while (beanProps.hasNext()) { + OMElement beanProp = (OMElement) beanProps.next(); + String beanName = beanProp.getAttributeValue(new QName(null, "name")); + if (RESTConstants.REST_CLIENT_MAX_TOTAL_CONNECTIONS.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + if (value != null && !value.trim().equals("")) { + maxTotalConnections = Integer.parseInt(value); + } + CoreUtils.debugLog(log, "Max total http connections ", maxTotalConnections); + } else if (RESTConstants.REST_CLIENT_MAX_CONNECTIONS_PER_ROUTE.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + if (value != null && !value.trim().equals("")) { + maxTotalConnectionsPerRoute = Integer.parseInt(value); + } + CoreUtils.debugLog(log, "Max total client connections per route ", maxTotalConnectionsPerRoute); + } else if (RESTConstants.REST_CLEINT_CONNECTION_TIMEOUT.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + if (value != null && !value.trim().equals("")) { + connectionTimeout = Integer.parseInt(value); + } + } else if (RESTConstants.REST_CLEINT_SOCKET_TIMEOUT.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + if (value != null && !value.trim().equals("")) { + socketTimeout = Integer.parseInt(value); + } + } + } + } + } + } catch (XMLStreamException e) { + log.error("Error in processing http connection settings, using default settings", e); + } catch (IOException e) { + log.error("Error in processing http connection settings, using default settings", e); + } + } + + private void configureHttpClient() { + + parseConfiguration(); + + RequestConfig defaultRequestConfig = RequestConfig.custom() + .setExpectContinueEnabled(true) + .setConnectTimeout(connectionTimeout) + .setSocketTimeout(socketTimeout) + .build(); + + connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setDefaultMaxPerRoute(maxTotalConnectionsPerRoute); + connectionManager.setMaxTotal(maxTotalConnections); + client = HttpClients.custom() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(defaultRequestConfig) + .build(); + + CoreUtils.debugLog(log, "REST client initialized with ", + "maxTotalConnection = ", maxTotalConnections, + "maxConnectionsPerRoute = ", maxTotalConnectionsPerRoute, + "connectionTimeout = ", connectionTimeout); + } + + public void closeHttpClient() { + IOUtils.closeQuietly(client); + IOUtils.closeQuietly(connectionManager); + } + + /** + * Invokes the http GET method + * + * @param uri endpoint/service url + * @param requestHeaders header list + * @param username username for authentication + * @param password password for authentication + * @return RESTResponse of the GET request (can be the response body or the response status code) + * @throws Exception + */ + public RESTResponse invokeGET(URI uri, Map requestHeaders, String username, String password) throws IOException { + + HttpGet httpGet = null; + CloseableHttpResponse response = null; + Header[] headers; + int httpStatus; + String contentType; + String output; + try { + httpGet = new HttpGet(uri); + if (requestHeaders != null && !requestHeaders.isEmpty()) { + Object keys[] = requestHeaders.keySet().toArray(); + for (Object header : keys) { + httpGet.setHeader(header.toString(), requestHeaders.get(header).toString()); + } + } + response = sendReceiveRequest(httpGet, username, password); + output = IOUtils.toString(response.getEntity().getContent()); + headers = response.getAllHeaders(); + httpStatus = response.getStatusLine().getStatusCode(); + contentType = response.getEntity().getContentType().getValue(); + if (log.isTraceEnabled()) { + log.trace("Invoked GET " + uri.toString() + " - Response message: " + output); + } + EntityUtils.consume(response.getEntity()); + } finally { + if (response != null) { + IOUtils.closeQuietly(response); + } + if (httpGet != null) { + httpGet.releaseConnection(); + } + } + return new RESTResponse(contentType, output, headers, httpStatus); + } + + + public RESTResponse invokePOST(URI uri, Map requestHeaders, String username, + String password, String payload) throws IOException { + + HttpPost httpPost = null; + CloseableHttpResponse response = null; + Header[] headers; + int httpStatus; + String contentType; + String output; + try { + httpPost = new HttpPost(uri); + httpPost.setEntity(new StringEntity(payload)); + if (requestHeaders != null && !requestHeaders.isEmpty()) { + Object keys[] = requestHeaders.keySet().toArray(); + for (Object header : keys) { + httpPost.setHeader(header.toString(), requestHeaders.get(header).toString()); + } + } + response = sendReceiveRequest(httpPost, username, password); + output = IOUtils.toString(response.getEntity().getContent()); + headers = response.getAllHeaders(); + httpStatus = response.getStatusLine().getStatusCode(); + contentType = response.getEntity().getContentType().getValue(); + if (log.isTraceEnabled()) { + log.trace("Invoked POST " + uri.toString() + + " - Input payload: " + payload + " - Response message: " + output); + } + EntityUtils.consume(response.getEntity()); + } finally { + if (response != null) { + IOUtils.closeQuietly(response); + } + if (httpPost != null) { + httpPost.releaseConnection(); + } + } + return new RESTResponse(contentType, output, headers, httpStatus); + } + + /** + * Invokes the http PUT method + * + * @param uri endpoint/service url + * @param requestHeaders header list + * @param username username for authentication + * @param password password for authentication + * @param payload payload body passed + * @return RESTResponse of the PUT request (can be the response body or the response status code) + * @throws Exception + */ + public RESTResponse invokePUT(URI uri, Map requestHeaders, String username, String password, + String payload) throws IOException { + + HttpPut httpPut = null; + CloseableHttpResponse response = null; + Header[] headers; + int httpStatus; + String contentType; + String output; + try { + httpPut = new HttpPut(uri); + httpPut.setEntity(new StringEntity(payload)); + if (requestHeaders != null && !requestHeaders.isEmpty()) { + Object keys[] = requestHeaders.keySet().toArray(); + for (Object header : keys) { + httpPut.setHeader(header.toString(), requestHeaders.get(header).toString()); + } + } + response = sendReceiveRequest(httpPut, username, password); + output = IOUtils.toString(response.getEntity().getContent()); + headers = response.getAllHeaders(); + httpStatus = response.getStatusLine().getStatusCode(); + contentType = response.getEntity().getContentType().getValue(); + if (log.isTraceEnabled()) { + log.trace("Invoked PUT " + uri.toString() + " - Response message: " + output); + } + EntityUtils.consume(response.getEntity()); + } finally { + if (response != null) { + IOUtils.closeQuietly(response); + } + if (httpPut != null) { + httpPut.releaseConnection(); + } + } + return new RESTResponse(contentType, output, headers, httpStatus); + } + + /** + * Invokes the http DELETE method + * + * @param uri endpoint/service url + * @param requestHeaders header list + * @param username username for authentication + * @param password password for authentication + * @return RESTResponse of the DELETE (can be the response status code or the response body) + * @throws Exception + */ + public RESTResponse invokeDELETE(URI uri, Map requestHeaders, String username, String password) throws IOException { + + HttpDelete httpDelete = null; + CloseableHttpResponse response = null; + Header[] headers; + int httpStatus; + String contentType; + String output; + try { + httpDelete = new HttpDelete(uri); + if (requestHeaders != null && !requestHeaders.isEmpty()) { + Object keys[] = requestHeaders.keySet().toArray(); + for (Object header : keys) { + httpDelete.setHeader(header.toString(), requestHeaders.get(header).toString()); + } + } + response = sendReceiveRequest(httpDelete, username, password); + output = IOUtils.toString(response.getEntity().getContent()); + headers = response.getAllHeaders(); + httpStatus = response.getStatusLine().getStatusCode(); + contentType = response.getEntity().getContentType().getValue(); + if (log.isTraceEnabled()) { + log.trace("Invoked DELETE " + uri.toString() + " - Response message: " + output); + } + EntityUtils.consume(response.getEntity()); + } finally { + if (response != null) { + IOUtils.closeQuietly(response); + } + if (httpDelete != null) { + httpDelete.releaseConnection(); + } + } + return new RESTResponse(contentType, output, headers, httpStatus); + } + + private CloseableHttpResponse sendReceiveRequest(HttpRequestBase requestBase, String username, String password) + throws IOException { + CloseableHttpResponse response; + if (username != null && !username.equals("") && password != null) { + String combinedCredentials = username + ":" + password; + byte[] encodedCredentials = Base64.encodeBase64(combinedCredentials.getBytes(StandardCharsets.UTF_8)); + requestBase.addHeader("Authorization", "Basic " + new String(encodedCredentials)); + + response = client.execute(requestBase); + } else { + response = client.execute(requestBase); + } + return response; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTResponse.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTResponse.java new file mode 100644 index 00000000000..7ce0389baac --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTResponse.java @@ -0,0 +1,81 @@ +/* + * 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.apimgt.handlers.invoker; + +import org.apache.http.Header; + +/** + * RESTResponse class holds the data retrieved from the HTTP invoke response. + */ +public class RESTResponse { + private String contentType; + private String content; + private Header[] headers; + private int httpStatus; + + /** + * Constructor + * + * @param contentType from the REST invoke response + * @param content from the REST invoke response + * @param headers from the REST invoke response + * @param httpStatus from the REST invoke response + */ + public RESTResponse(String contentType, String content, Header[] headers, int httpStatus) { + this.contentType = contentType; + this.content = content; + this.headers = headers; + this.httpStatus = httpStatus; + } + + /** + * Get the content type of the EST invoke response + * + * @return String content type of the response + */ + public String getContentType() { + return contentType; + } + + /** + * Get contents of the REST invoke response + * + * @return contents of the REST invoke response + */ + public String getContent() { + return content; + } + + /** + * Get headers of the REST invoke response + * + * @return headers of the REST invoke response + */ + public Header[] getHeaders() { + return headers; + } + + /** + * Get the HTTP Status code from REST invoke response + * + * @return int HTTP status code + */ + public int getHttpStatus() { + return httpStatus; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java new file mode 100644 index 00000000000..b7c9a00dfae --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java @@ -0,0 +1,35 @@ +/* + * 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.apimgt.handlers.utils; + +public class AuthConstants { + public static final String SEC_FAULT = "SECURITY_VALIDATION_FAILURE"; + public static final String HTTPS = "https"; + public static final String WSSE = "wsse"; + public static final String SSL_CERT_X509 = "ssl.client.auth.cert.X509"; + public static final String AUTH_CONFIGURATION_FILE_NAME = "api-filter-config.xml"; + public static final String API_FILTER_CONFIG_ELEMENT = "apiFilterConfig"; + public static final String API_LIST_PROPERTY = "apiList"; + public static final String HOST = "host"; + public static final String HTTPS_PORT = "httpsPort"; + public static final String USERNAME = "username"; + public static final String PASSWORD = "password"; + public static final String MDM_SIGNATURE = "mdm-signature"; + public static final String IOS = "ios"; + public static final String ANDROID = "android"; +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java new file mode 100644 index 00000000000..42a7fe9ea75 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java @@ -0,0 +1,140 @@ +/* + * 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.apimgt.handlers.utils; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.util.AXIOMUtil; +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +public class CoreUtils { + private static final Log log = LogFactory.getLog(CoreUtils.class); + private static String host = "localhost"; + private static int httpsPort = 9443; + private static String username = "admin"; + private static String password = "admin"; + + /** + * Reading configurations from api-filter-config.xml file + * + * @return ArrayList of api contexts + */ + public static ArrayList readApiFilterList() { + ArrayList apiList = new ArrayList(); + String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); + String apiFilterConfigPath = carbonConfigDirPath + File.separator + + AuthConstants.AUTH_CONFIGURATION_FILE_NAME; + File configFile = new File(apiFilterConfigPath); + + try { + String configContent = FileUtils.readFileToString(configFile); + OMElement configElement = AXIOMUtil.stringToOM(configContent); + Iterator beans = configElement.getChildrenWithName( + new QName("http://www.springframework.org/schema/beans", "bean")); + + while (beans.hasNext()) { + OMElement bean = (OMElement) beans.next(); + String beanId = bean.getAttributeValue(new QName(null, "id")); + if (beanId.equals(AuthConstants.API_FILTER_CONFIG_ELEMENT)) { + Iterator beanProps = bean.getChildrenWithName( + new QName("http://www.springframework.org/schema/beans", "property")); + + while (beanProps.hasNext()) { + OMElement beanProp = (OMElement) beanProps.next(); + String beanName = beanProp.getAttributeValue(new QName(null, "name")); + if (AuthConstants.API_LIST_PROPERTY.equals(beanName)) { + Iterator apiListSet = ((OMElement) beanProp.getChildrenWithLocalName("set").next()) + .getChildrenWithLocalName("value"); + while (apiListSet.hasNext()) { + String apiContext = ((OMElement) apiListSet.next()).getText(); + apiList.add(apiContext); + CoreUtils.debugLog(log, "Adding security to api: ", apiContext); + } + } else if (AuthConstants.HOST.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + host = value; + } else if (AuthConstants.HTTPS_PORT.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + if (value != null && !value.trim().equals("")) { + httpsPort = Integer.parseInt(value); + } + } else if (AuthConstants.USERNAME.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + username = value; + } else if (AuthConstants.PASSWORD.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + password = value; + } + } + } + } + } catch (IOException e) { + log.error("Error in reading api filter settings", e); + } catch (XMLStreamException e) { + log.error("Error in reading api filter settings", e); + } + return apiList; + } + + /** + * Universal debug log function + * + * @param logger Log object specific to the class + * @param message initial debug log message + * @param vars optional strings to be appended for the log + */ + public static void debugLog(Log logger, String message, Object ... vars) { + if(logger.isDebugEnabled()) { + if (vars.length < 1) { + logger.debug(message); + return; + } + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(message); + for (Object var : vars) { + stringBuilder.append(var.toString()); + } + logger.debug(stringBuilder.toString()); + } + } + + public static String getHost() { + return host; + } + + public static int getHttpsPort() { + return httpsPort; + } + + public static String getUsername() { + return username; + } + + public static String getPassword() { + return password; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml new file mode 100644 index 00000000000..8811ccb8e78 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + /services/echo + /abc + + + + + + + + \ No newline at end of file diff --git a/components/apimgt-extensions/pom.xml b/components/apimgt-extensions/pom.xml index 4086cf5a18e..8d486740eeb 100644 --- a/components/apimgt-extensions/pom.xml +++ b/components/apimgt-extensions/pom.xml @@ -38,6 +38,7 @@ org.wso2.carbon.apimgt.application.extension org.wso2.carbon.apimgt.application.extension.api org.wso2.carbon.apimgt.annotations + org.wso2.carbon.apimgt.handlers diff --git a/pom.xml b/pom.xml index ccb5bf93d3b..eeabd51d554 100644 --- a/pom.xml +++ b/pom.xml @@ -1930,6 +1930,10 @@ 1.6.1 + + + 2.1.7-wso2v7 + 1.5.11.wso2v15 From 610163d705e1e4ef575537a856f8d1c54ea31adf Mon Sep 17 00:00:00 2001 From: amalhub Date: Wed, 7 Dec 2016 18:48:20 +0530 Subject: [PATCH 03/13] IOTS-292: Adding IOS synapse config for gatway change --- .../src/main/resources/ios-synapse-config.xml | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml new file mode 100644 index 00000000000..cba71164e13 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 871970002aca8d89915d44c32a3658de725e3025 Mon Sep 17 00:00:00 2001 From: amalhub Date: Fri, 9 Dec 2016 11:47:58 +0530 Subject: [PATCH 04/13] IOTS-292: Adding android cert verification for gateway handler --- .../AuthenticationHandler.java | 164 +++++++++++++----- .../utils/AuthConstants.java | 5 +- 2 files changed, 118 insertions(+), 51 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java index f5c5c800563..770ffd1128e 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.ws.security.WSConstants; import org.apache.ws.security.WSSecurityException; import org.apache.ws.security.util.Base64; +import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker; import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse; @@ -37,7 +38,9 @@ import org.wso2.carbon.apimgt.handlers.utils.AuthConstants; import org.wso2.carbon.apimgt.handlers.utils.CoreUtils; import javax.xml.namespace.QName; +import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -68,52 +71,17 @@ public class AuthenticationHandler implements Handler { * @throws AxisFault */ public InvocationResponse invoke(MessageContext messageContext) throws AxisFault { - boolean validateRequest = messageContext.getTo() != null; - - if (validateRequest && isSecuredAPI(messageContext)) { + if (isSecuredAPI(messageContext)) { String ctxPath = messageContext.getTo().getAddress().trim(); CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath); Map headers = (Map) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS); + try { + if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { - if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { - String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); - - try { + String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); CoreUtils.debugLog(log, "Verify Cert:\n", mdmSignature); - URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/dynamic-client-web/register"); - String dcrContent = "{\n" + - "\"owner\":\"" + CoreUtils.getUsername() + "\",\n" + - "\"clientName\":\"emm\",\n" + - "\"grantType\":\"refresh_token password client_credentials\",\n" + - "\"tokenScope\":\"default\"\n" + - "}"; - Map drcHeaders = new HashMap(); - drcHeaders.put("Content-Type", "application/json"); - - RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null, - null, dcrContent); - CoreUtils.debugLog(log, "DCR response:", response.getContent()); - JSONObject jsonResponse = new JSONObject(response.getContent()); - String clientId = jsonResponse.getString("client_id"); - String clientSecret = jsonResponse.getString("client_secret"); - - URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/oauth2/token"); - String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" + - CoreUtils.getPassword() + "&scope=activity-view"; - String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); - Map tokenHeaders = new HashMap(); - tokenHeaders.put("Authorization", tokenBasicAuth); - tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); - - response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null, - null, tokenContent); - CoreUtils.debugLog(log, "Token response:", response.getContent()); - jsonResponse = new JSONObject(response.getContent()); - String accessToken = jsonResponse.getString("access_token"); - + String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); Map certVerifyHeaders = new HashMap(); @@ -125,7 +93,7 @@ public class AuthenticationHandler implements Handler { "\"serial\":\"\"\n" + "}"; - response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, null, certVerifyContent); CoreUtils.debugLog(log, "Verify response:", response.getContent()); @@ -136,14 +104,65 @@ public class AuthenticationHandler implements Handler { setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); return InvocationResponse.SUSPEND; - } catch (Exception e) { - log.error("Error while processing certificate.", e); - setFaultCodeAndThrowAxisFault(messageContext, e); + } else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) { + String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER).toString(); + CoreUtils.debugLog(log, "Verify subject DN: ", subjectDN); + String accessToken = getAccessToken(); + URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/android"); + Map certVerifyHeaders = new HashMap(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + String certVerifyContent = "{\n" + + "\"pem\":\"" + subjectDN + "\",\n" + + "\"tenantId\": \"-1234\",\n" + + "\"serial\":\"" + AuthConstants.PROXY_MUTUAL_AUTH_HEADER + "\"\n" + + "}"; + + RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + CoreUtils.debugLog(log, "Verify response:", response.getContent()); + if (!response.getContent().contains("invalid")) { + return InvocationResponse.CONTINUE; + } + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); + return InvocationResponse.SUSPEND; + + } else if (headers.containsKey(AuthConstants.ENCODED_PEM)) { + String encodedPem = headers.get(AuthConstants.ENCODED_PEM).toString(); + CoreUtils.debugLog(log, "Verify Cert:\n", encodedPem); + + String accessToken = getAccessToken(); + URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); + Map certVerifyHeaders = new HashMap(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + String certVerifyContent = "{\n" + + "\"pem\":\"" + encodedPem + "\",\n" + + "\"tenantId\": \"-1234\",\n" + + "\"serial\":\"\"\n" + + "}"; + + RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + CoreUtils.debugLog(log, "Verify response:", response.getContent()); + + if (!response.getContent().contains("invalid")) { + return InvocationResponse.CONTINUE; + } + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); + return InvocationResponse.SUSPEND; + } else { + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required")); return InvocationResponse.SUSPEND; } - } else { - log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required")); + } catch (Exception e) { + log.error("Error while processing certificate.", e); + setFaultCodeAndThrowAxisFault(messageContext, e); return InvocationResponse.SUSPEND; } } else { @@ -159,7 +178,7 @@ public class AuthenticationHandler implements Handler { * @return boolean */ private boolean isSecuredAPI(MessageContext messageContext) { - if (messageContext.getTransportIn() != null && + if (messageContext.getTo() != null && messageContext.getTransportIn() != null && messageContext.getTransportIn().getName().toLowerCase().equals(AuthConstants.HTTPS)) { for (String path : apiList) { if (messageContext.getTo().getAddress().trim().contains(path)) { @@ -170,6 +189,55 @@ public class AuthenticationHandler implements Handler { return false; } + /** + * Get access token to call admin certificate management service for cert validation. + * + * @return accessToken String + * @throws URISyntaxException + * @throws IOException + */ + private String getAccessToken() throws URISyntaxException, IOException, JSONException { + URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/dynamic-client-web/register"); + String dcrContent = "{\n" + + "\"owner\":\"" + CoreUtils.getUsername() + "\",\n" + + "\"clientName\":\"emm\",\n" + + "\"grantType\":\"refresh_token password client_credentials\",\n" + + "\"tokenScope\":\"default\"\n" + + "}"; + Map drcHeaders = new HashMap(); + drcHeaders.put("Content-Type", "application/json"); + + RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null, + null, dcrContent); + CoreUtils.debugLog(log, "DCR response:", response.getContent()); + JSONObject jsonResponse = new JSONObject(response.getContent()); + String clientId = jsonResponse.getString("client_id"); + String clientSecret = jsonResponse.getString("client_secret"); + + URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils + .getHttpsPort() + "/oauth2/token"); + String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" + + CoreUtils.getPassword() + "&scope=activity-view"; + String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); + Map tokenHeaders = new HashMap(); + tokenHeaders.put("Authorization", tokenBasicAuth); + tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); + + response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null, + null, tokenContent); + CoreUtils.debugLog(log, "Token response:", response.getContent()); + jsonResponse = new JSONObject(response.getContent()); + String accessToken = jsonResponse.getString("access_token"); + return accessToken; + } + + /** + * Thow error message to client + * @param msgContext + * @param e Exception + * @throws AxisFault + */ private void setFaultCodeAndThrowAxisFault(MessageContext msgContext, Exception e) throws AxisFault { msgContext.setProperty(AuthConstants.SEC_FAULT, Boolean.TRUE); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java index b7c9a00dfae..12bcda249a5 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java @@ -21,7 +21,6 @@ public class AuthConstants { public static final String SEC_FAULT = "SECURITY_VALIDATION_FAILURE"; public static final String HTTPS = "https"; public static final String WSSE = "wsse"; - public static final String SSL_CERT_X509 = "ssl.client.auth.cert.X509"; public static final String AUTH_CONFIGURATION_FILE_NAME = "api-filter-config.xml"; public static final String API_FILTER_CONFIG_ELEMENT = "apiFilterConfig"; public static final String API_LIST_PROPERTY = "apiList"; @@ -30,6 +29,6 @@ public class AuthConstants { public static final String USERNAME = "username"; public static final String PASSWORD = "password"; public static final String MDM_SIGNATURE = "mdm-signature"; - public static final String IOS = "ios"; - public static final String ANDROID = "android"; + public static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header"; + public static final String ENCODED_PEM = "encoded-pem"; } From 0bd298e6d70f1521c64666adc269877f487b1ea2 Mon Sep 17 00:00:00 2001 From: amalhub Date: Fri, 9 Dec 2016 11:56:51 +0530 Subject: [PATCH 05/13] IOTS-292: Code refactoring --- .../AuthenticationHandler.java | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java index 770ffd1128e..d8e779d658d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java @@ -76,6 +76,7 @@ public class AuthenticationHandler implements Handler { CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath); Map headers = (Map) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS); try { + RESTResponse response = null; if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); @@ -84,7 +85,7 @@ public class AuthenticationHandler implements Handler { String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); - Map certVerifyHeaders = new HashMap(); + Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); String certVerifyContent = "{\n" + @@ -93,24 +94,17 @@ public class AuthenticationHandler implements Handler { "\"serial\":\"\"\n" + "}"; - RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, null, certVerifyContent); CoreUtils.debugLog(log, "Verify response:", response.getContent()); - if (!response.getContent().contains("invalid")) { - return InvocationResponse.CONTINUE; - } - log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); - return InvocationResponse.SUSPEND; - } else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) { String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER).toString(); CoreUtils.debugLog(log, "Verify subject DN: ", subjectDN); String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/android"); - Map certVerifyHeaders = new HashMap(); + Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); String certVerifyContent = "{\n" + @@ -119,15 +113,9 @@ public class AuthenticationHandler implements Handler { "\"serial\":\"" + AuthConstants.PROXY_MUTUAL_AUTH_HEADER + "\"\n" + "}"; - RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, null, certVerifyContent); CoreUtils.debugLog(log, "Verify response:", response.getContent()); - if (!response.getContent().contains("invalid")) { - return InvocationResponse.CONTINUE; - } - log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); - return InvocationResponse.SUSPEND; } else if (headers.containsKey(AuthConstants.ENCODED_PEM)) { String encodedPem = headers.get(AuthConstants.ENCODED_PEM).toString(); @@ -136,7 +124,7 @@ public class AuthenticationHandler implements Handler { String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); - Map certVerifyHeaders = new HashMap(); + Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); String certVerifyContent = "{\n" + @@ -145,21 +133,22 @@ public class AuthenticationHandler implements Handler { "\"serial\":\"\"\n" + "}"; - RESTResponse response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, null, certVerifyContent); CoreUtils.debugLog(log, "Verify response:", response.getContent()); - if (!response.getContent().contains("invalid")) { - return InvocationResponse.CONTINUE; - } - log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); - return InvocationResponse.SUSPEND; } else { log.warn("Unauthorized request for api: " + ctxPath); setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required")); return InvocationResponse.SUSPEND; } + + if (response != null && !response.getContent().contains("invalid")) { + return InvocationResponse.CONTINUE; + } + log.warn("Unauthorized request for api: " + ctxPath); + setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); + return InvocationResponse.SUSPEND; } catch (Exception e) { log.error("Error while processing certificate.", e); setFaultCodeAndThrowAxisFault(messageContext, e); From 7e90fde46113a24f33236ed011204fae318c10cd Mon Sep 17 00:00:00 2001 From: amalhub Date: Fri, 9 Dec 2016 12:28:40 +0530 Subject: [PATCH 06/13] IOTS-292: Adding new filter configs --- .../AuthenticationHandler.java | 6 +++--- .../utils/AuthConstants.java | 2 ++ .../utils/CoreUtils.java | 16 ++++++++++++++++ .../src/main/resources/api-filter-config.xml | 2 ++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java index d8e779d658d..1c320410b66 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java @@ -84,7 +84,7 @@ public class AuthenticationHandler implements Handler { String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); + .getHttpsPort() + CoreUtils.getIosVerifyEndpoint()); Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); @@ -103,7 +103,7 @@ public class AuthenticationHandler implements Handler { CoreUtils.debugLog(log, "Verify subject DN: ", subjectDN); String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/android"); + .getHttpsPort() + CoreUtils.getAndroidVerifyEndpoint()); Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); @@ -123,7 +123,7 @@ public class AuthenticationHandler implements Handler { String accessToken = getAccessToken(); URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"); + .getHttpsPort() + CoreUtils.getAndroidVerifyEndpoint()); Map certVerifyHeaders = new HashMap<>(); certVerifyHeaders.put("Authorization", "Bearer " + accessToken); certVerifyHeaders.put("Content-Type", "application/json"); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java index 12bcda249a5..03a8780efc9 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/AuthConstants.java @@ -28,6 +28,8 @@ public class AuthConstants { public static final String HTTPS_PORT = "httpsPort"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; + public static final String IOS_VERIFY_ENDPOINT = "ios-verify-endpoint"; + public static final String ANDROID_VERIFY_ENDPOINT = "android-verify-endpoint"; public static final String MDM_SIGNATURE = "mdm-signature"; public static final String PROXY_MUTUAL_AUTH_HEADER = "proxy-mutual-auth-header"; public static final String ENCODED_PEM = "encoded-pem"; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java index 42a7fe9ea75..852e2529b7f 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java @@ -37,6 +37,8 @@ public class CoreUtils { private static int httpsPort = 9443; private static String username = "admin"; private static String password = "admin"; + private static String iosVerifyEndpoint = "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"; + private static String androidVerifyEndpoint = "/api/certificate-mgt/v1.0/admin/certificates/verify/android"; /** * Reading configurations from api-filter-config.xml file @@ -88,6 +90,12 @@ public class CoreUtils { } else if (AuthConstants.PASSWORD.equals(beanName)) { String value = beanProp.getAttributeValue(new QName(null, "value")); password = value; + } else if (AuthConstants.IOS_VERIFY_ENDPOINT.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + iosVerifyEndpoint = value; + } else if (AuthConstants.ANDROID_VERIFY_ENDPOINT.equals(beanName)) { + String value = beanProp.getAttributeValue(new QName(null, "value")); + androidVerifyEndpoint = value; } } } @@ -137,4 +145,12 @@ public class CoreUtils { public static String getPassword() { return password; } + + public static String getIosVerifyEndpoint() { + return iosVerifyEndpoint; + } + + public static String getAndroidVerifyEndpoint() { + return androidVerifyEndpoint; + } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml index 8811ccb8e78..fc6c2417599 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml @@ -18,5 +18,7 @@ + + \ No newline at end of file From a6649c1d52558e12cbc814e9cbbece822db54ea2 Mon Sep 17 00:00:00 2001 From: geethkokila Date: Mon, 19 Dec 2016 09:54:33 +0530 Subject: [PATCH 07/13] Partial commit for the git update --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index eeabd51d554..bcd15ec495a 100644 --- a/pom.xml +++ b/pom.xml @@ -1544,6 +1544,17 @@ jersey-core ${jersey.version} + + + org.apache.synapse + synapse-core + ${org.apache.synapse.version} + + + org.apache.ws.security.wso2 + wss4j + ${org.apache.ws.security.wso2.version} + From 200740eca60c6c50f893acea708744e8faa9f888 Mon Sep 17 00:00:00 2001 From: geethkokila Date: Mon, 19 Dec 2016 09:58:19 +0530 Subject: [PATCH 08/13] Partial commit for the git update --- .../APIMCertificateMGTExcepton.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/APIMCertificateMGTExcepton.java diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/APIMCertificateMGTExcepton.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/APIMCertificateMGTExcepton.java new file mode 100644 index 00000000000..9b11ab7faf3 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/APIMCertificateMGTExcepton.java @@ -0,0 +1,59 @@ +/* + * 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.apimgt.handlers; + +public class APIMCertificateMGTExcepton extends Exception{ + + private static final long serialVersionUID = -37676242646464497L; + + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public APIMCertificateMGTExcepton(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public APIMCertificateMGTExcepton(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public APIMCertificateMGTExcepton(String msg) { + super(msg); + setErrorMessage(msg); + } + + public APIMCertificateMGTExcepton() { + super(); + } + + public APIMCertificateMGTExcepton(Throwable cause) { + super(cause); + } +} + From 01cbf8ecd934a8a88b3ef13afebb42339455cf6d Mon Sep 17 00:00:00 2001 From: geethkokila Date: Mon, 19 Dec 2016 13:41:02 +0530 Subject: [PATCH 09/13] Partial commit --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 25bb565618f..c9ff92bc559 100644 --- a/pom.xml +++ b/pom.xml @@ -314,6 +314,12 @@ org.wso2.carbon.apimgt.application.extension.api ${carbon.device.mgt.version} + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.handlers + ${carbon.device.mgt.version} + From 23dc0e62ab21a3867139612a4152fb434f3f8688 Mon Sep 17 00:00:00 2001 From: geethkokila Date: Mon, 19 Dec 2016 13:41:21 +0530 Subject: [PATCH 10/13] Partial commit --- features/apimgt-extensions/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/features/apimgt-extensions/pom.xml b/features/apimgt-extensions/pom.xml index 0804d11989f..0c3ace13932 100644 --- a/features/apimgt-extensions/pom.xml +++ b/features/apimgt-extensions/pom.xml @@ -37,6 +37,7 @@ org.wso2.carbon.apimgt.webapp.publisher.feature org.wso2.carbon.apimgt.application.extension.feature + org.wso2.carbon.apimgt.handler.server.feature From 1b4857b7fd9a483b5966c7b4c9554420249dce19 Mon Sep 17 00:00:00 2001 From: geethkokila Date: Tue, 20 Dec 2016 11:19:58 +0530 Subject: [PATCH 11/13] Fixing conflicts --- .../org.wso2.carbon.certificate.mgt.core/pom.xml | 10 ++++++---- .../main/resources/jaggeryapps/devicemgt/jaggery.conf | 2 +- .../jaggeryapps/uuf-template-app/jaggery.conf | 2 +- .../uuf-template-app/lib/modules/auth/auth.js | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml index 3d6927cb7d4..cf23d12014a 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/pom.xml @@ -21,13 +21,13 @@ org.wso2.carbon.devicemgt certificate-mgt - 2.0.4-SNAPSHOT + 2.0.3-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.certificate.mgt.core - 2.0.4-SNAPSHOT + 2.0.3-SNAPSHOT bundle WSO2 Carbon - Certificate Management Core WSO2 Carbon - Certificate Management Core @@ -51,7 +51,8 @@ ${carbon.device.mgt.version} Device Management Core Bundle - org.wso2.carbon.certificate.mgt.core.internal + org.wso2.carbon.certificate.mgt.core.internal, + org.wso2.carbon.certificate.mgt.core.util org.osgi.framework, @@ -59,7 +60,7 @@ org.apache.commons.logging, javax.security.auth.x500, javax.xml.*, - javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional, + javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional, org.apache.commons.codec.binary, org.bouncycastle.asn1, org.bouncycastle.asn1.x500, @@ -97,6 +98,7 @@ !org.wso2.carbon.certificate.mgt.core.internal.*, + !org.wso2.carbon.certificate.mgt.core.util, org.wso2.carbon.certificate.mgt.core.* diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/jaggery.conf b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/jaggery.conf index fb71f60e969..832c1ab2528 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/jaggery.conf +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/jaggery.conf @@ -108,7 +108,7 @@ "contextParams" : [ { "name" : "Owasp.CsrfGuard.Config", - "value" : "/repository/conf/security/Owasp.CsrfGuard.Carbon.properties" + "value" : "/repository/conf/security/Owasp.CsrfGuard.dashboard.properties" } ] } \ 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/jaggery.conf b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/jaggery.conf index 7c5a2d41c9d..f97bae72cfc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/jaggery.conf +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/jaggery.conf @@ -71,7 +71,7 @@ "contextParams" : [ { "name" : "Owasp.CsrfGuard.Config", - "value" : "/repository/conf/security/Owasp.CsrfGuard.Carbon.properties" + "value" : "/repository/conf/security/Owasp.CsrfGuard.dashboard.properties" } ] } \ 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 2cf9771beab..a18d2efc501 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 @@ -520,7 +520,7 @@ var module = {}; response.sendError(500, msg); return; } - + /** * @type {{sessionId: string, loggedInUser: string, sessionIndex: string, samlToken: * string}} @@ -533,7 +533,7 @@ var module = {}; if (ssoSession.sessionIndex) { module.loadTenant(ssoSession.loggedInUser); var carbonUser = (require("carbon")).server.tenantUser(ssoSession.loggedInUser); - module.loadTenant(ssoSession.loggedInUser); + module.loadTenant(ssoSession.loggedInUser); utils.setCurrentUser(carbonUser.username, carbonUser.domain, carbonUser.tenantId); var scriptArgument = {input: {samlToken: ssoSession.samlToken}, user: module.getCurrentUser()}; handleEvent(OPERATION_LOGIN, EVENT_SUCCESS, scriptArgument); From 44c7383b1525abc085629345a7c0e6a50948b69b Mon Sep 17 00:00:00 2001 From: geethkokila Date: Fri, 6 Jan 2017 17:04:00 +0530 Subject: [PATCH 12/13] Adding support to send ios request the synapse gateway --- .../org.wso2.carbon.apimgt.handlers/pom.xml | 73 +++- .../AuthenticationHandler.java | 346 +++++++----------- .../beans/Certificate.java | 52 +++ .../beans/DCR.java | 61 +++ .../beans/ValidationResponce.java | 61 +++ .../config/IOTServerConfiguration.java | 118 ++++++ .../invoker/RESTInvoker.java | 141 +++---- .../utils/CoreUtils.java | 178 ++++----- .../utils/Utils.java | 154 ++++++++ .../src/main/resources/api-filter-config.xml | 24 -- .../src/main/resources/ios-synapse-config.xml | 138 ------- .../src/main/resources/iot-api-config.xml | 48 +++ .../pom.xml | 5 + .../CertificateManagementAdminService.java | 151 +++++--- .../jaxrs/api/beans/ValidationResponce.java | 61 +++ ...CertificateManagementAdminServiceImpl.java | 150 ++++++-- .../api/util/CertificateMgtAPIUtils.java | 16 + .../pom.xml | 8 +- .../pom.xml | 106 ++++++ .../src/main/resources/build.properties | 1 + .../main/resources/conf/iot-api-config.xml | 40 ++ .../src/main/resources/p2.inf | 2 + .../main/resources/conf/.cdm-config.xml.swp | Bin 16384 -> 0 bytes 23 files changed, 1297 insertions(+), 637 deletions(-) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/Certificate.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/DCR.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/ValidationResponce.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/config/IOTServerConfiguration.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/Utils.java delete mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml delete mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml create mode 100644 components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponce.java create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/pom.xml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/build.properties create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/conf/iot-api-config.xml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/p2.inf delete mode 100644 features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/.cdm-config.xml.swp diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml index b8133bc6d81..e707cbc5f36 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml @@ -1,32 +1,53 @@ + + apimgt-extensions org.wso2.carbon.devicemgt - 1.2.8-SNAPSHOT + 2.0.6-SNAPSHOT + ../pom.xml - 4.0.0 + 4.0.0 org.wso2.carbon.apimgt.handlers + 2.0.6-SNAPSHOT + bundle WSO2 Carbon - API Security Handler Component + WSO2 Carbon - API Management Security Handler Module + http://wso2.org + org.wso2.carbon org.wso2.carbon.logging - ${carbon.kernel.version} org.apache.synapse synapse-core - ${org.apache.synapse.version} org.apache.ws.security.wso2 wss4j - ${org.apache.ws.security.wso2.version} org.wso2.carbon.devicemgt @@ -35,8 +56,48 @@ org.json.wso2 json - ${commons-json.version} + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + 1.4.0 + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + WSO2 Carbon - API Security Handler Component + + org.apache.axiom.*, + javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional, + javax.xml.*, + org.apache.axis2.*, + org.apache.commons.*, + org.apache.http.*, + org.apache.http.util, + org.apache.ws.*;version="${org.apache.ws.security.wso2.version}", + org.json, + org.wso2.carbon.utils, + org.wso2.carbon.context, + com.google.gson, + org.w3c.dom, + org.apache.synapse, + org.apache.synapse.core.axis2, + org.apache.synapse.rest + + + + + + + \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java index 1c320410b66..1d4282f1a52 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/AuthenticationHandler.java @@ -17,268 +17,176 @@ */ package org.wso2.carbon.apimgt.handlers; -import org.apache.axiom.soap.SOAP11Constants; -import org.apache.axiom.soap.SOAP12Constants; -import org.apache.axis2.AxisFault; +import com.google.gson.Gson; import org.apache.axis2.context.MessageContext; import org.apache.axis2.description.HandlerDescription; -import org.apache.axis2.description.Parameter; -import org.apache.axis2.engine.Handler; -import org.apache.axis2.namespace.Constants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.ws.security.WSConstants; -import org.apache.ws.security.WSSecurityException; -import org.apache.ws.security.util.Base64; -import org.json.JSONException; -import org.json.JSONObject; +import org.apache.synapse.core.axis2.Axis2MessageContext; +import org.apache.synapse.rest.AbstractHandler; +import org.wso2.carbon.apimgt.handlers.beans.Certificate; +import org.wso2.carbon.apimgt.handlers.beans.ValidationResponce; +import org.wso2.carbon.apimgt.handlers.config.IOTServerConfiguration; import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker; import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse; import org.wso2.carbon.apimgt.handlers.utils.AuthConstants; -import org.wso2.carbon.apimgt.handlers.utils.CoreUtils; +import org.wso2.carbon.apimgt.handlers.utils.Utils; +import org.wso2.carbon.context.PrivilegedCarbonContext; -import javax.xml.namespace.QName; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -public class AuthenticationHandler implements Handler { +public class AuthenticationHandler extends AbstractHandler { private static final Log log = LogFactory.getLog(AuthenticationHandler.class); private static HandlerDescription EMPTY_HANDLER_METADATA = new HandlerDescription("API Security Handler"); private HandlerDescription handlerDesc; - private ArrayList apiList; private RESTInvoker restInvoker; + private IOTServerConfiguration iotServerConfiguration; + /** * Setting up configurations at the constructor */ public AuthenticationHandler() { - log.info("Engaging API Security Handler"); - apiList = CoreUtils.readApiFilterList(); + log.info("Engaging API Security Handler.........."); restInvoker = new RESTInvoker(); this.handlerDesc = EMPTY_HANDLER_METADATA; + this.iotServerConfiguration = Utils.initConfig(); } - /** - * Handles incoming http/s requests - * - * @param messageContext - * @return response - * @throws AxisFault - */ - public InvocationResponse invoke(MessageContext messageContext) throws AxisFault { - if (isSecuredAPI(messageContext)) { - String ctxPath = messageContext.getTo().getAddress().trim(); - CoreUtils.debugLog(log, "Authentication handler invoked by: ", ctxPath); - Map headers = (Map) messageContext.getProperty(MessageContext.TRANSPORT_HEADERS); - try { - RESTResponse response = null; - if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { - - String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); - CoreUtils.debugLog(log, "Verify Cert:\n", mdmSignature); - - String accessToken = getAccessToken(); - URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + CoreUtils.getIosVerifyEndpoint()); - Map certVerifyHeaders = new HashMap<>(); - certVerifyHeaders.put("Authorization", "Bearer " + accessToken); - certVerifyHeaders.put("Content-Type", "application/json"); - String certVerifyContent = "{\n" + - "\"pem\":\"" + mdmSignature + "\",\n" + - "\"tenantId\": \"-1234\",\n" + - "\"serial\":\"\"\n" + - "}"; - - response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, - null, certVerifyContent); - CoreUtils.debugLog(log, "Verify response:", response.getContent()); + @Override + public boolean handleRequest(org.apache.synapse.MessageContext messageContext) { + org.apache.axis2.context.MessageContext axisMC = ((Axis2MessageContext) messageContext).getAxis2MessageContext(); - } else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) { - String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER).toString(); - CoreUtils.debugLog(log, "Verify subject DN: ", subjectDN); - String accessToken = getAccessToken(); - URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + CoreUtils.getAndroidVerifyEndpoint()); - Map certVerifyHeaders = new HashMap<>(); - certVerifyHeaders.put("Authorization", "Bearer " + accessToken); - certVerifyHeaders.put("Content-Type", "application/json"); - String certVerifyContent = "{\n" + - "\"pem\":\"" + subjectDN + "\",\n" + - "\"tenantId\": \"-1234\",\n" + - "\"serial\":\"" + AuthConstants.PROXY_MUTUAL_AUTH_HEADER + "\"\n" + - "}"; + String ctxPath = messageContext.getTo().getAddress().trim(); - response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, - null, certVerifyContent); - CoreUtils.debugLog(log, "Verify response:", response.getContent()); - - } else if (headers.containsKey(AuthConstants.ENCODED_PEM)) { - String encodedPem = headers.get(AuthConstants.ENCODED_PEM).toString(); - CoreUtils.debugLog(log, "Verify Cert:\n", encodedPem); - - String accessToken = getAccessToken(); - URI certVerifyUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + CoreUtils.getAndroidVerifyEndpoint()); - Map certVerifyHeaders = new HashMap<>(); - certVerifyHeaders.put("Authorization", "Bearer " + accessToken); - certVerifyHeaders.put("Content-Type", "application/json"); - String certVerifyContent = "{\n" + - "\"pem\":\"" + encodedPem + "\",\n" + - "\"tenantId\": \"-1234\",\n" + - "\"serial\":\"\"\n" + - "}"; + if (log.isDebugEnabled()) { + log.debug("Authentication handler invoked by: " + ctxPath); + } + Map headers = (Map) axisMC.getProperty(MessageContext.TRANSPORT_HEADERS); + try { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + RESTResponse response; + if (headers.containsKey(AuthConstants.MDM_SIGNATURE)) { + + String mdmSignature = headers.get(AuthConstants.MDM_SIGNATURE).toString(); + if (log.isDebugEnabled()) { + log.debug("Verify Cert:\n" + mdmSignature); + } + String accessToken = Utils.getAccessToken(iotServerConfiguration); + + String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); + URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); + + Map certVerifyHeaders = new HashMap<>(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + + Certificate certificate = new Certificate(); + certificate.setPem(mdmSignature); + certificate.setTenantId(tenantId); + certificate.setSerial(""); + + Gson gson = new Gson(); + String certVerifyContent = gson.toJson(certificate); + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + + String str = response.getContent(); + if (str.contains("JWTToken")) { + ValidationResponce validationResponce = gson.fromJson(str, ValidationResponce.class); + // TODO: send the JWT token with user details. + // headers.put("X-JWT-Assertion", validationResponce.getJWTToken()); + } + if (log.isDebugEnabled()) { + log.debug("Verify response:" + response.getContent()); + log.debug("Response String : " + str); + } - response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, - null, certVerifyContent); - CoreUtils.debugLog(log, "Verify response:", response.getContent()); + } else if (headers.containsKey(AuthConstants.PROXY_MUTUAL_AUTH_HEADER)) { + String subjectDN = headers.get(AuthConstants.PROXY_MUTUAL_AUTH_HEADER).toString(); - } else { - log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("SSL required")); - return InvocationResponse.SUSPEND; + if (log.isDebugEnabled()) { + log.debug("Verify subject DN: " + subjectDN); } - - if (response != null && !response.getContent().contains("invalid")) { - return InvocationResponse.CONTINUE; + String accessToken = Utils.getAccessToken(iotServerConfiguration); + String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); + URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); + Map certVerifyHeaders = new HashMap<>(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + Certificate certificate = new Certificate(); + certificate.setPem(subjectDN); + certificate.setTenantId(tenantId); + certificate.setSerial(AuthConstants.PROXY_MUTUAL_AUTH_HEADER); + + Gson gson = new Gson(); + String certVerifyContent = gson.toJson(certificate); + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + if (log.isDebugEnabled()) { + log.debug("Verify response:" + response.getContent()); + } + } else if (headers.containsKey(AuthConstants.ENCODED_PEM)) { + String encodedPem = headers.get(AuthConstants.ENCODED_PEM).toString(); + if (log.isDebugEnabled()) { + log.debug("Verify Cert:\n" + encodedPem); + } + String accessToken = Utils.getAccessToken(iotServerConfiguration); + URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + "android"); + Map certVerifyHeaders = new HashMap<>(); + certVerifyHeaders.put("Authorization", "Bearer " + accessToken); + certVerifyHeaders.put("Content-Type", "application/json"); + + Certificate certificate = new Certificate(); + certificate.setPem(encodedPem); + certificate.setTenantId(tenantId); + certificate.setSerial(""); + Gson gson = new Gson(); + String certVerifyContent = gson.toJson(certificate); + response = restInvoker.invokePOST(certVerifyUrl, certVerifyHeaders, null, + null, certVerifyContent); + if (log.isDebugEnabled()) { + log.debug("Verify response:" + response.getContent()); } + } else { log.warn("Unauthorized request for api: " + ctxPath); - setFaultCodeAndThrowAxisFault(messageContext, new Exception("Unauthorized!")); - return InvocationResponse.SUSPEND; - } catch (Exception e) { - log.error("Error while processing certificate.", e); - setFaultCodeAndThrowAxisFault(messageContext, e); - return InvocationResponse.SUSPEND; + return false; } - } else { - return InvocationResponse.CONTINUE; - } - - } - - /** - * API filter - * - * @param messageContext - * @return boolean - */ - private boolean isSecuredAPI(MessageContext messageContext) { - if (messageContext.getTo() != null && messageContext.getTransportIn() != null && - messageContext.getTransportIn().getName().toLowerCase().equals(AuthConstants.HTTPS)) { - for (String path : apiList) { - if (messageContext.getTo().getAddress().trim().contains(path)) { - return true; - } + if (response != null && !response.getContent().contains("invalid")) { + return true; } - } - return false; - } - - /** - * Get access token to call admin certificate management service for cert validation. - * - * @return accessToken String - * @throws URISyntaxException - * @throws IOException - */ - private String getAccessToken() throws URISyntaxException, IOException, JSONException { - URI dcrUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/dynamic-client-web/register"); - String dcrContent = "{\n" + - "\"owner\":\"" + CoreUtils.getUsername() + "\",\n" + - "\"clientName\":\"emm\",\n" + - "\"grantType\":\"refresh_token password client_credentials\",\n" + - "\"tokenScope\":\"default\"\n" + - "}"; - Map drcHeaders = new HashMap(); - drcHeaders.put("Content-Type", "application/json"); - - RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null, - null, dcrContent); - CoreUtils.debugLog(log, "DCR response:", response.getContent()); - JSONObject jsonResponse = new JSONObject(response.getContent()); - String clientId = jsonResponse.getString("client_id"); - String clientSecret = jsonResponse.getString("client_secret"); - - URI tokenUrl = new URI(AuthConstants.HTTPS + "://" + CoreUtils.getHost() + ":" + CoreUtils - .getHttpsPort() + "/oauth2/token"); - String tokenContent = "grant_type=password&username=" + CoreUtils.getUsername() + "&password=" + - CoreUtils.getPassword() + "&scope=activity-view"; - String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); - Map tokenHeaders = new HashMap(); - tokenHeaders.put("Authorization", tokenBasicAuth); - tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); - - response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null, - null, tokenContent); - CoreUtils.debugLog(log, "Token response:", response.getContent()); - jsonResponse = new JSONObject(response.getContent()); - String accessToken = jsonResponse.getString("access_token"); - return accessToken; - } - - /** - * Thow error message to client - * @param msgContext - * @param e Exception - * @throws AxisFault - */ - private void setFaultCodeAndThrowAxisFault(MessageContext msgContext, Exception e) throws AxisFault { - - msgContext.setProperty(AuthConstants.SEC_FAULT, Boolean.TRUE); - String soapVersionURI = msgContext.getEnvelope().getNamespace().getNamespaceURI(); - QName faultCode = null; - /* - * Get the faultCode from the thrown WSSecurity exception, if there is one - */ - if (e instanceof WSSecurityException) { - faultCode = ((WSSecurityException) e).getFaultCode(); - } - /* - * Otherwise default to InvalidSecurity - */ - if (faultCode == null) { - faultCode = new QName(WSConstants.INVALID_SECURITY.getNamespaceURI(), - WSConstants.INVALID_SECURITY.getLocalPart(), AuthConstants.WSSE); - } - - if (soapVersionURI.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) { - - throw new AxisFault(faultCode, e.getMessage(), e); - - } else if (soapVersionURI.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) { - - List subfaultCodes = new ArrayList(); - subfaultCodes.add(faultCode); - throw new AxisFault(Constants.FAULT_SOAP12_SENDER, subfaultCodes, e.getMessage(), e); - + log.warn("Unauthorized request for api: " + ctxPath); + return false; + } catch (IOException e) { + log.error("Error while processing certificate.", e); + return false; + } catch (URISyntaxException e) { + log.error("Error while processing certificate.", e); + return false; + } catch (APIMCertificateMGTExcepton e) { + log.error("Error while processing certificate.", e); + return false; } } - public void cleanup() { + @Override + public boolean handleResponse(org.apache.synapse.MessageContext messageContext) { + return true; } - public void init(HandlerDescription handlerDescription) { - this.handlerDesc = handlerDescription; - } - - public void flowComplete(MessageContext messageContext) { - } - public HandlerDescription getHandlerDesc() { - return this.handlerDesc; - } - - public String getName() { - return "API security inflow handler"; - } + // TODO : take this from the url. + private String getDeviceType(String url) { + if (url.contains("ios")) { + return "ios"; + } else if (url.contains("android")) { + return "android"; + } else return null; - public Parameter getParameter(String name) { - return this.handlerDesc.getParameter(name); } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/Certificate.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/Certificate.java new file mode 100644 index 00000000000..3f0b65f0aeb --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/Certificate.java @@ -0,0 +1,52 @@ +/* + * 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.apimgt.handlers.beans; + +public class Certificate { + + private String pem; + private int tenantId; + private String serial; + + public String getPem() { + return pem; + } + + public void setPem(String pem) { + this.pem = pem; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } +} + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/DCR.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/DCR.java new file mode 100644 index 00000000000..88ae6de8ce0 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/DCR.java @@ -0,0 +1,61 @@ +/* + * 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.apimgt.handlers.beans; + +public class DCR { + + private String owner; + private String clientName; + private String grantType; + private String tokenScope; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantType) { + this.grantType = grantType; + } + + public String getTokenScope() { + return tokenScope; + } + + public void setTokenScope(String tokenScope) { + this.tokenScope = tokenScope; + } +} + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/ValidationResponce.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/ValidationResponce.java new file mode 100644 index 00000000000..5d698fb5a3c --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/beans/ValidationResponce.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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.apimgt.handlers.beans; + +public class ValidationResponce { + + private String JWTToken; // X-JWT-Assertion + private String deviceId; + private String deviceType; + private int tenantId; + + public String getJWTToken() { + return JWTToken; + } + + public void setJWTToken(String JWTToken) { + this.JWTToken = JWTToken; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } +} + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/config/IOTServerConfiguration.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/config/IOTServerConfiguration.java new file mode 100644 index 00000000000..71b430ff405 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/config/IOTServerConfiguration.java @@ -0,0 +1,118 @@ +/* + * 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.apimgt.handlers.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; +import java.util.List; + +@XmlRootElement(name = "ServerConfiguration") +public class IOTServerConfiguration { + + private String hostname; + private String verificationEndpoint; + private String username; + private String password; + private String dynamicClientRegistrationEndpoint; + private String oauthTokenEndpoint; + private List apis; + + @XmlElement(name = "Hostname", required = true) + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + @XmlElement(name = "VerificationEndpoint", required = true) + public String getVerificationEndpoint() { + return verificationEndpoint; + } + + public void setVerificationEndpoint(String verificationEndpoint) { + this.verificationEndpoint = verificationEndpoint; + } + + @XmlElement(name = "Username", required = true) + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @XmlElement(name = "Password", required = true) + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @XmlElement(name = "DynamicClientRegistrationEndpoint", required = true) + public String getDynamicClientRegistrationEndpoint() { + return dynamicClientRegistrationEndpoint; + } + + public void setDynamicClientRegistrationEndpoint(String dynamicClientRegistrationEndpoint) { + this.dynamicClientRegistrationEndpoint = dynamicClientRegistrationEndpoint; + } + + @XmlElement(name = "OauthTokenEndpoint", required = true) + public String getOauthTokenEndpoint() { + return oauthTokenEndpoint; + } + + public void setOauthTokenEndpoint(String oauthTokenEndpoint) { + this.oauthTokenEndpoint = oauthTokenEndpoint; + } + + @XmlElementWrapper(name="APIS") + @XmlElement(name = "ContextPath", required = true) + public List getApis() { + return apis; + } + + public void setApis(List apis) { + this.apis = apis; + } + + @XmlRootElement(name = "ContextPath") + public static class ContextPath { + + private String contextPath; + + @XmlValue() + public String getContextPath() { + return contextPath; + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + } +} + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java index 7873a7fc54e..95b4fdecca3 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/invoker/RESTInvoker.java @@ -61,64 +61,64 @@ public class RESTInvoker { configureHttpClient(); } - private void parseConfiguration() { - String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); - String apiFilterConfigPath = carbonConfigDirPath + File.separator + - AuthConstants.AUTH_CONFIGURATION_FILE_NAME; - File configFile = new File(apiFilterConfigPath); - - try { - String configContent = FileUtils.readFileToString(configFile); - OMElement configElement = AXIOMUtil.stringToOM(configContent); - Iterator beans = configElement.getChildrenWithName( - new QName("http://www.springframework.org/schema/beans", "bean")); - - while (beans.hasNext()) { - OMElement bean = (OMElement) beans.next(); - String beanId = bean.getAttributeValue(new QName(null, "id")); - if (beanId.equals(RESTConstants.REST_CLIENT_CONFIG_ELEMENT)) { - Iterator beanProps = bean.getChildrenWithName( - new QName("http://www.springframework.org/schema/beans", "property")); - - while (beanProps.hasNext()) { - OMElement beanProp = (OMElement) beanProps.next(); - String beanName = beanProp.getAttributeValue(new QName(null, "name")); - if (RESTConstants.REST_CLIENT_MAX_TOTAL_CONNECTIONS.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - if (value != null && !value.trim().equals("")) { - maxTotalConnections = Integer.parseInt(value); - } - CoreUtils.debugLog(log, "Max total http connections ", maxTotalConnections); - } else if (RESTConstants.REST_CLIENT_MAX_CONNECTIONS_PER_ROUTE.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - if (value != null && !value.trim().equals("")) { - maxTotalConnectionsPerRoute = Integer.parseInt(value); - } - CoreUtils.debugLog(log, "Max total client connections per route ", maxTotalConnectionsPerRoute); - } else if (RESTConstants.REST_CLEINT_CONNECTION_TIMEOUT.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - if (value != null && !value.trim().equals("")) { - connectionTimeout = Integer.parseInt(value); - } - } else if (RESTConstants.REST_CLEINT_SOCKET_TIMEOUT.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - if (value != null && !value.trim().equals("")) { - socketTimeout = Integer.parseInt(value); - } - } - } - } - } - } catch (XMLStreamException e) { - log.error("Error in processing http connection settings, using default settings", e); - } catch (IOException e) { - log.error("Error in processing http connection settings, using default settings", e); - } - } +// private void parseConfiguration() { +// String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); +// String apiFilterConfigPath = carbonConfigDirPath + File.separator + +// AuthConstants.AUTH_CONFIGURATION_FILE_NAME; +// File configFile = new File(apiFilterConfigPath); +// +// try { +// String configContent = FileUtils.readFileToString(configFile); +// OMElement configElement = AXIOMUtil.stringToOM(configContent); +// Iterator beans = configElement.getChildrenWithName( +// new QName("http://www.springframework.org/schema/beans", "bean")); +// +// while (beans.hasNext()) { +// OMElement bean = (OMElement) beans.next(); +// String beanId = bean.getAttributeValue(new QName(null, "id")); +// if (beanId.equals(RESTConstants.REST_CLIENT_CONFIG_ELEMENT)) { +// Iterator beanProps = bean.getChildrenWithName( +// new QName("http://www.springframework.org/schema/beans", "property")); +// +// while (beanProps.hasNext()) { +// OMElement beanProp = (OMElement) beanProps.next(); +// String beanName = beanProp.getAttributeValue(new QName(null, "name")); +// if (RESTConstants.REST_CLIENT_MAX_TOTAL_CONNECTIONS.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// if (value != null && !value.trim().equals("")) { +// maxTotalConnections = Integer.parseInt(value); +// } +// CoreUtils.debugLog(log, "Max total http connections ", maxTotalConnections); +// } else if (RESTConstants.REST_CLIENT_MAX_CONNECTIONS_PER_ROUTE.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// if (value != null && !value.trim().equals("")) { +// maxTotalConnectionsPerRoute = Integer.parseInt(value); +// } +// CoreUtils.debugLog(log, "Max total client connections per route ", maxTotalConnectionsPerRoute); +// } else if (RESTConstants.REST_CLEINT_CONNECTION_TIMEOUT.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// if (value != null && !value.trim().equals("")) { +// connectionTimeout = Integer.parseInt(value); +// } +// } else if (RESTConstants.REST_CLEINT_SOCKET_TIMEOUT.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// if (value != null && !value.trim().equals("")) { +// socketTimeout = Integer.parseInt(value); +// } +// } +// } +// } +// } +// } catch (XMLStreamException e) { +// log.error("Error in processing http connection settings, using default settings", e); +// } catch (IOException e) { +// log.error("Error in processing http connection settings, using default settings", e); +// } +// } private void configureHttpClient() { - parseConfiguration(); +// parseConfiguration(); RequestConfig defaultRequestConfig = RequestConfig.custom() .setExpectContinueEnabled(true) @@ -134,10 +134,17 @@ public class RESTInvoker { .setDefaultRequestConfig(defaultRequestConfig) .build(); - CoreUtils.debugLog(log, "REST client initialized with ", - "maxTotalConnection = ", maxTotalConnections, - "maxConnectionsPerRoute = ", maxTotalConnectionsPerRoute, - "connectionTimeout = ", connectionTimeout); + if(log.isDebugEnabled()){ + log.debug("REST client initialized with " + + "maxTotalConnection = " + maxTotalConnections + + "maxConnectionsPerRoute = " + maxTotalConnectionsPerRoute + + "connectionTimeout = " + connectionTimeout); + } +// +// CoreUtils.debugLog(log, "REST client initialized with ", +// "maxTotalConnection = ", maxTotalConnections, +// "maxConnectionsPerRoute = ", maxTotalConnectionsPerRoute, +// "connectionTimeout = ", connectionTimeout); } public void closeHttpClient() { @@ -176,8 +183,8 @@ public class RESTInvoker { headers = response.getAllHeaders(); httpStatus = response.getStatusLine().getStatusCode(); contentType = response.getEntity().getContentType().getValue(); - if (log.isTraceEnabled()) { - log.trace("Invoked GET " + uri.toString() + " - Response message: " + output); + if (log.isDebugEnabled()) { + log.debug("Invoked GET " + uri.toString() + " - Response message: " + output); } EntityUtils.consume(response.getEntity()); } finally { @@ -215,8 +222,8 @@ public class RESTInvoker { headers = response.getAllHeaders(); httpStatus = response.getStatusLine().getStatusCode(); contentType = response.getEntity().getContentType().getValue(); - if (log.isTraceEnabled()) { - log.trace("Invoked POST " + uri.toString() + + if (log.isDebugEnabled()) { + log.debug("Invoked POST " + uri.toString() + " - Input payload: " + payload + " - Response message: " + output); } EntityUtils.consume(response.getEntity()); @@ -265,8 +272,8 @@ public class RESTInvoker { headers = response.getAllHeaders(); httpStatus = response.getStatusLine().getStatusCode(); contentType = response.getEntity().getContentType().getValue(); - if (log.isTraceEnabled()) { - log.trace("Invoked PUT " + uri.toString() + " - Response message: " + output); + if (log.isDebugEnabled()) { + log.debug("Invoked PUT " + uri.toString() + " - Response message: " + output); } EntityUtils.consume(response.getEntity()); } finally { @@ -311,8 +318,8 @@ public class RESTInvoker { headers = response.getAllHeaders(); httpStatus = response.getStatusLine().getStatusCode(); contentType = response.getEntity().getContentType().getValue(); - if (log.isTraceEnabled()) { - log.trace("Invoked DELETE " + uri.toString() + " - Response message: " + output); + if (log.isDebugEnabled()) { + log.debug("Invoked DELETE " + uri.toString() + " - Response message: " + output); } EntityUtils.consume(response.getEntity()); } finally { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java index 852e2529b7f..605ad801e6d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/CoreUtils.java @@ -40,95 +40,95 @@ public class CoreUtils { private static String iosVerifyEndpoint = "/api/certificate-mgt/v1.0/admin/certificates/verify/ios"; private static String androidVerifyEndpoint = "/api/certificate-mgt/v1.0/admin/certificates/verify/android"; - /** - * Reading configurations from api-filter-config.xml file - * - * @return ArrayList of api contexts - */ - public static ArrayList readApiFilterList() { - ArrayList apiList = new ArrayList(); - String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); - String apiFilterConfigPath = carbonConfigDirPath + File.separator + - AuthConstants.AUTH_CONFIGURATION_FILE_NAME; - File configFile = new File(apiFilterConfigPath); - - try { - String configContent = FileUtils.readFileToString(configFile); - OMElement configElement = AXIOMUtil.stringToOM(configContent); - Iterator beans = configElement.getChildrenWithName( - new QName("http://www.springframework.org/schema/beans", "bean")); - - while (beans.hasNext()) { - OMElement bean = (OMElement) beans.next(); - String beanId = bean.getAttributeValue(new QName(null, "id")); - if (beanId.equals(AuthConstants.API_FILTER_CONFIG_ELEMENT)) { - Iterator beanProps = bean.getChildrenWithName( - new QName("http://www.springframework.org/schema/beans", "property")); - - while (beanProps.hasNext()) { - OMElement beanProp = (OMElement) beanProps.next(); - String beanName = beanProp.getAttributeValue(new QName(null, "name")); - if (AuthConstants.API_LIST_PROPERTY.equals(beanName)) { - Iterator apiListSet = ((OMElement) beanProp.getChildrenWithLocalName("set").next()) - .getChildrenWithLocalName("value"); - while (apiListSet.hasNext()) { - String apiContext = ((OMElement) apiListSet.next()).getText(); - apiList.add(apiContext); - CoreUtils.debugLog(log, "Adding security to api: ", apiContext); - } - } else if (AuthConstants.HOST.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - host = value; - } else if (AuthConstants.HTTPS_PORT.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - if (value != null && !value.trim().equals("")) { - httpsPort = Integer.parseInt(value); - } - } else if (AuthConstants.USERNAME.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - username = value; - } else if (AuthConstants.PASSWORD.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - password = value; - } else if (AuthConstants.IOS_VERIFY_ENDPOINT.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - iosVerifyEndpoint = value; - } else if (AuthConstants.ANDROID_VERIFY_ENDPOINT.equals(beanName)) { - String value = beanProp.getAttributeValue(new QName(null, "value")); - androidVerifyEndpoint = value; - } - } - } - } - } catch (IOException e) { - log.error("Error in reading api filter settings", e); - } catch (XMLStreamException e) { - log.error("Error in reading api filter settings", e); - } - return apiList; - } - - /** - * Universal debug log function - * - * @param logger Log object specific to the class - * @param message initial debug log message - * @param vars optional strings to be appended for the log - */ - public static void debugLog(Log logger, String message, Object ... vars) { - if(logger.isDebugEnabled()) { - if (vars.length < 1) { - logger.debug(message); - return; - } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(message); - for (Object var : vars) { - stringBuilder.append(var.toString()); - } - logger.debug(stringBuilder.toString()); - } - } +// /** +// * Reading configurations from api-filter-config.xml file +// * +// * @return ArrayList of api contexts +// */ +// public static ArrayList readApiFilterList() { +// ArrayList apiList = new ArrayList(); +// String carbonConfigDirPath = CarbonUtils.getCarbonConfigDirPath(); +// String apiFilterConfigPath = carbonConfigDirPath + File.separator + +// AuthConstants.AUTH_CONFIGURATION_FILE_NAME; +// File configFile = new File(apiFilterConfigPath); +// +// try { +// String configContent = FileUtils.readFileToString(configFile); +// OMElement configElement = AXIOMUtil.stringToOM(configContent); +// Iterator beans = configElement.getChildrenWithName( +// new QName("http://www.springframework.org/schema/beans", "bean")); +// +// while (beans.hasNext()) { +// OMElement bean = (OMElement) beans.next(); +// String beanId = bean.getAttributeValue(new QName(null, "id")); +// if (beanId.equals(AuthConstants.API_FILTER_CONFIG_ELEMENT)) { +// Iterator beanProps = bean.getChildrenWithName( +// new QName("http://www.springframework.org/schema/beans", "property")); +// +// while (beanProps.hasNext()) { +// OMElement beanProp = (OMElement) beanProps.next(); +// String beanName = beanProp.getAttributeValue(new QName(null, "name")); +// if (AuthConstants.API_LIST_PROPERTY.equals(beanName)) { +// Iterator apiListSet = ((OMElement) beanProp.getChildrenWithLocalName("set").next()) +// .getChildrenWithLocalName("value"); +// while (apiListSet.hasNext()) { +// String apiContext = ((OMElement) apiListSet.next()).getText(); +// apiList.add(apiContext); +// CoreUtils.debugLog(log, "Adding security to api: ", apiContext); +// } +// } else if (AuthConstants.HOST.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// host = value; +// } else if (AuthConstants.HTTPS_PORT.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// if (value != null && !value.trim().equals("")) { +// httpsPort = Integer.parseInt(value); +// } +// } else if (AuthConstants.USERNAME.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// username = value; +// } else if (AuthConstants.PASSWORD.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// password = value; +// } else if (AuthConstants.IOS_VERIFY_ENDPOINT.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// iosVerifyEndpoint = value; +// } else if (AuthConstants.ANDROID_VERIFY_ENDPOINT.equals(beanName)) { +// String value = beanProp.getAttributeValue(new QName(null, "value")); +// androidVerifyEndpoint = value; +// } +// } +// } +// } +// } catch (IOException e) { +// log.error("Error in reading api filter settings", e); +// } catch (XMLStreamException e) { +// log.error("Error in reading api filter settings", e); +// } +// return apiList; +// } +// +// /** +// * Universal debug log function +// * +// * @param logger Log object specific to the class +// * @param message initial debug log message +// * @param vars optional strings to be appended for the log +// */ +// public static void debugLog(Log logger, String message, Object ... vars) { +// if(logger.isDebugEnabled()) { +// if (vars.length < 1) { +// logger.debug(message); +// return; +// } +// StringBuilder stringBuilder = new StringBuilder(); +// stringBuilder.append(message); +// for (Object var : vars) { +// stringBuilder.append(var.toString()); +// } +// logger.debug(stringBuilder.toString()); +// } +// } public static String getHost() { return host; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/Utils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/Utils.java new file mode 100644 index 00000000000..416ae306ae9 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org.wso2.carbon.apimgt.handlers/utils/Utils.java @@ -0,0 +1,154 @@ +/* + * 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.apimgt.handlers.utils; + +import com.google.gson.Gson; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ws.security.util.Base64; +import org.json.JSONException; +import org.json.JSONObject; +import org.w3c.dom.Document; +import org.wso2.carbon.apimgt.handlers.APIMCertificateMGTExcepton; +import org.wso2.carbon.apimgt.handlers.beans.DCR; +import org.wso2.carbon.apimgt.handlers.config.IOTServerConfiguration; +import org.wso2.carbon.apimgt.handlers.invoker.RESTInvoker; +import org.wso2.carbon.apimgt.handlers.invoker.RESTResponse; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.Map; + +public class Utils { + + private static final Log log = LogFactory.getLog(Utils.class); + private static final String IOT_APIS_CONFIG_FILE = "iot-api-config.xml"; + private static String clientId; + private static String clientSecret; + + public static IOTServerConfiguration initConfig() { + try { + + String IOTServerAPIConfigurationPath = + CarbonUtils.getCarbonConfigDirPath() + File.separator + IOT_APIS_CONFIG_FILE; + File file = new File(IOTServerAPIConfigurationPath); + Document doc = Utils.convertToDocument(file); + + JAXBContext fileContext = JAXBContext.newInstance(IOTServerConfiguration.class); + Unmarshaller unmarshaller = fileContext.createUnmarshaller(); + return (IOTServerConfiguration) unmarshaller.unmarshal(doc); + + } catch (JAXBException | APIMCertificateMGTExcepton e) { + log.error("Error occurred while initializing Data Source config", e); + return null; + } + } + + public static Document convertToDocument(File file) throws APIMCertificateMGTExcepton { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + return docBuilder.parse(file); + } catch (Exception e) { + throw new APIMCertificateMGTExcepton("Error occurred while parsing file, while converting " + + "to a org.w3c.dom.Document", e); + } + } + + public static String getAccessToken(IOTServerConfiguration iotServerConfiguration) + throws APIMCertificateMGTExcepton { + try { + if (clientId == null || clientSecret == null) { + getClientSecretes(iotServerConfiguration); + } + URI tokenUrl = new URI(iotServerConfiguration.getOauthTokenEndpoint()); + String tokenContent = "grant_type=password&username=" + iotServerConfiguration.getUsername()+ "&password=" + + iotServerConfiguration.getPassword() + "&scope=activity-view"; + String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); + Map tokenHeaders = new HashMap(); + tokenHeaders.put("Authorization", tokenBasicAuth); + tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); + + RESTInvoker restInvoker = new RESTInvoker(); + RESTResponse response = restInvoker.invokePOST(tokenUrl, tokenHeaders, null, + null, tokenContent); + if(log.isDebugEnabled()) { + log.debug("Token response:" + response.getContent()); + } + JSONObject jsonResponse = new JSONObject(response.getContent()); + String accessToken = jsonResponse.getString("access_token"); + return accessToken; + + } catch (URISyntaxException e) { + throw new APIMCertificateMGTExcepton("Error occurred while trying to call oauth token endpoint", e); + } catch (JSONException e) { + throw new APIMCertificateMGTExcepton("Error occurred while converting the json to object", e); + } catch (IOException e) { + throw new APIMCertificateMGTExcepton("Error occurred while trying to call oauth token endpoint", e); + } + } + + private static void getClientSecretes(IOTServerConfiguration iotServerConfiguration) + throws APIMCertificateMGTExcepton { + try { + DCR dcr = new DCR(); + dcr.setOwner(iotServerConfiguration.getUsername()); + dcr.setClientName("IOT-API-MANAGER"); + dcr.setGrantType("refresh_token password client_credentials"); + dcr.setTokenScope("default"); + Gson gson = new Gson(); + String dcrContent = gson.toJson(dcr); + Map drcHeaders = new HashMap(); + drcHeaders.put("Content-Type", "application/json"); + URI dcrUrl = new URI(iotServerConfiguration.getDynamicClientRegistrationEndpoint()); + RESTInvoker restInvoker = new RESTInvoker(); + RESTResponse response = restInvoker.invokePOST(dcrUrl, drcHeaders, null, + null, dcrContent); + + if (log.isDebugEnabled()) { + log.debug("DCR response :" + response.getContent()); + } + JSONObject jsonResponse = new JSONObject(response.getContent()); + clientId = jsonResponse.getString("client_id"); + clientSecret = jsonResponse.getString("client_secret"); + } catch (JSONException e) { + throw new APIMCertificateMGTExcepton("Error occurred while converting the json to object", e); + } catch (IOException e) { + throw new APIMCertificateMGTExcepton("Error occurred while trying to call DCR endpoint", e); + } catch (URISyntaxException e) { + throw new APIMCertificateMGTExcepton("Error occurred while trying to call DCR endpoint", e); + } + + } + +} + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml deleted file mode 100644 index fc6c2417599..00000000000 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/api-filter-config.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - /services/echo - /abc - - - - - - - - - - \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml deleted file mode 100644 index cba71164e13..00000000000 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/ios-synapse-config.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml new file mode 100644 index 00000000000..c5447fb0e5b --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml @@ -0,0 +1,48 @@ + + + + + + https://localhost:9443/ + + + https://localhost:9443/api/certificate-mgt/v1.0/admin/certificates/verify/ + + + admin + admin + + + https://localhost:9443/dynamic-client-web/register + + + https://localhost:9443/oauth2/token + + + /services/echo + /abc + /ca + /authenticate + /enroll + /enrolled + /license + /checkin + /server + + \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml index 377b33ea3e0..4c572152a9b 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml @@ -149,6 +149,11 @@ org.wso2.carbon.certificate.mgt.core provided + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + provided + io.swagger swagger-annotations diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java index a273a52fd20..857f2ab2a6a 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -18,6 +18,7 @@ import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificat import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; +import javax.validation.constraints.Size; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -60,9 +61,9 @@ public interface CertificateManagementAdminService { tags = "Certificate Management", authorizations = { @Authorization( - value="permission", - scopes = { @AuthorizationScope(scope = "/device-mgt/certificates/manage", - description = "Manage certificates") } + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/certificates/manage", + description = "Manage certificates")} ) } ) @@ -131,9 +132,9 @@ public interface CertificateManagementAdminService { tags = "Certificate Management", authorizations = { @Authorization( - value="permission", - scopes = { @AuthorizationScope(scope = "/device-mgt/certificates/view", - description = "View certificates") } + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/certificates/view", + description = "View certificates")} ) } ) @@ -204,9 +205,9 @@ public interface CertificateManagementAdminService { tags = "Certificate Management", authorizations = { @Authorization( - value="permission", - scopes = { @AuthorizationScope(scope = "/device-mgt/certificates/view", - description = "View certificates") } + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/certificates/view", + description = "View certificates")} ) } ) @@ -285,9 +286,9 @@ public interface CertificateManagementAdminService { tags = "Certificate Management", authorizations = { @Authorization( - value="permission", - scopes = { @AuthorizationScope(scope = "/device-mgt/certificates/manage", - description = "Manage certificates") } + value = "permission", + scopes = {@AuthorizationScope(scope = "/device-mgt/certificates/manage", + description = "Manage certificates")} ) } ) @@ -316,43 +317,81 @@ public interface CertificateManagementAdminService { defaultValue = "12438035315552875930") @PathParam("serialNumber") String serialNumber); - /** - * Verify IOS Certificate for the API security filter - * - * @param certificate to be verified as a String - * @return Status of the certificate verification. - */ - @POST - @Path("/verify/ios") - @ApiOperation( - consumes = MediaType.APPLICATION_JSON, - produces = MediaType.APPLICATION_JSON, - httpMethod = "POST", - value = "Verify IOS SSL certificate", - notes = "Verify IOS Certificate for the API security filter.\n", - tags = "Certificate Management") - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "Return the status of the IOS certificate verification.", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body")}), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class) - }) - @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") - Response verifyIOSCertificate( - @ApiParam( - name = "certificate", - value = "The properties to verify certificate. It includes the following: \n" + - "serial: The unique ID of the certificate. (optional) \n" + - "pem: mdm-signature of the certificate", - required = true) EnrollmentCertificate certificate); +// /** +// * Verify IOS Certificate for the API security filter +// * +// * @param certificate to be verified as a String +// * @return Status of the certificate verification. +// */ +// @POST +// @Path("/verify/ios") +// @ApiOperation( +// consumes = MediaType.APPLICATION_JSON, +// produces = MediaType.APPLICATION_JSON, +// httpMethod = "POST", +// value = "Verify IOS SSL certificate", +// notes = "Verify IOS Certificate for the API security filter.\n", +// tags = "Certificate Management") +// @ApiResponses( +// value = { +// @ApiResponse( +// code = 200, +// message = "Return the status of the IOS certificate verification.", +// responseHeaders = { +// @ResponseHeader( +// name = "Content-Type", +// description = "The content type of the body")}), +// @ApiResponse( +// code = 400, +// message = "Bad Request. \n Invalid request or validation error.", +// response = ErrorResponse.class) +// }) +// Response verifyIOSCertificate( +// @ApiParam( +// name = "certificate", +// value = "The properties to verify certificate. It includes the following: \n" + +// "serial: The unique ID of the certificate. (optional) \n" + +// "pem: mdm-signature of the certificate", +// required = true) EnrollmentCertificate certificate); +// +// /** +// * Verify Android Certificate for the API security filter +// * +// * @param certificate to be verified as a String +// * @return Status of the certificate verification. +// */ +// @POST +// @Path("/verify/android") +// @ApiOperation( +// consumes = MediaType.APPLICATION_JSON, +// produces = MediaType.APPLICATION_JSON, +// httpMethod = "POST", +// value = "Verify Android SSL certificate", +// notes = "Verify Android Certificate for the API security filter.\n", +// tags = "Certificate Management") +// @ApiResponses( +// value = { +// @ApiResponse( +// code = 200, +// message = "Return the status of the Android certificate verification.", +// responseHeaders = { +// @ResponseHeader( +// name = "Content-Type", +// description = "The content type of the body")}), +// @ApiResponse( +// code = 400, +// message = "Bad Request. \n Invalid request or validation error.", +// response = ErrorResponse.class) +// }) +// Response verifyAndroidCertificate( +// @ApiParam( +// name = "certificate", +// value = "The properties to verify certificate. It includes the following: \n" + +// "serial: The unique ID of the certificate. (optional) \n" + +// "pem: pem String of the certificate", +// required = true) EnrollmentCertificate certificate); +// + /** * Verify Android Certificate for the API security filter @@ -361,7 +400,7 @@ public interface CertificateManagementAdminService { * @return Status of the certificate verification. */ @POST - @Path("/verify/android") + @Path("/verify/{type}") @ApiOperation( consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, @@ -383,8 +422,15 @@ public interface CertificateManagementAdminService { message = "Bad Request. \n Invalid request or validation error.", response = ErrorResponse.class) }) - @Permission(name = "Manage certificates", permission = "/device-mgt/certificates/manage") - Response verifyAndroidCertificate( + Response verifyCertificate( + @ApiParam( + name = "type", + value = "The device type, such as ios, android or windows.", + required = true, + allowableValues = "android, ios, windows") + @PathParam("type") + @Size(max = 45) + String type, @ApiParam( name = "certificate", value = "The properties to verify certificate. It includes the following: \n" + @@ -392,3 +438,4 @@ public interface CertificateManagementAdminService { "pem: pem String of the certificate", required = true) EnrollmentCertificate certificate); } + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponce.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponce.java new file mode 100644 index 00000000000..5a72112e4d6 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponce.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 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.beans; + +public class ValidationResponce { + + private String JWTToken; // X-JWT-Assertion + private String deviceId; + private String deviceType; + private int tenantId; + + public String getJWTToken() { + return JWTToken; + } + + public void setJWTToken(String JWTToken) { + this.JWTToken = JWTToken; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } +} + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java index 0b7b7210e88..0f62d9e72b8 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -1,12 +1,12 @@ package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl; -import io.swagger.annotations.ApiParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdminService; 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.ErrorResponse; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ValidationResponce; 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.core.dto.CertificateResponse; @@ -20,6 +20,8 @@ import org.wso2.carbon.certificate.mgt.core.service.PaginationResult; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import javax.ws.rs.*; import javax.ws.rs.core.Response; @@ -145,25 +147,119 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem } } +// @POST +// @Path("/verify/ios") +// public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + +// "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { +// try { +// CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); +// X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); +// String challengeToken = certMgtService.extractChallengeToken(cert); +// +// if (challengeToken != null) { +// challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); +// +// SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); +// DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); +// deviceIdentifier.setId(challengeToken); +// deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); +// TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); +// +// if (tenantedDeviceWrapper != null) { +// return Response.status(Response.Status.OK).entity("valid").build(); +// } +// } +// } catch (SCEPException e) { +// String msg = "Error occurred while extracting information from certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } catch (KeystoreException e) { +// String msg = "Error occurred while converting PEM file to X509Certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } +// return Response.status(Response.Status.OK).entity("invalid").build(); +// } +// +// @POST +// @Path("/verify/android") +// public Response verifyAndroidCertificate(@ApiParam(name = "certificate", value = "Base64 encoded .pem file of the " + +// "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { +// CertificateResponse certificateResponse = null; +// try { +// CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); +// if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { +// certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); +// } else { +// X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); +// if (clientCertificate != null) { +// certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); +// } +// } +// +// if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse +// .getCommonName().isEmpty()) { +// return Response.status(Response.Status.OK).entity("valid").build(); +// } +// } catch (KeystoreException e) { +// String msg = "Error occurred while converting PEM file to X509Certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } +// return Response.status(Response.Status.OK).entity("invalid").build(); +// } + @POST - @Path("/verify/ios") - public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + - "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { + @Path("/verify/{type}") + public Response verifyCertificate(@PathParam("type") String type, EnrollmentCertificate certificate) { try { CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); - X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); - String challengeToken = certMgtService.extractChallengeToken(cert); - if (challengeToken != null) { - challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS.equalsIgnoreCase(type)) { + X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); + String challengeToken = certMgtService.extractChallengeToken(cert); + + if (challengeToken != null) { + challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); + + SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(challengeToken); + deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); - SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); - DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); - deviceIdentifier.setId(challengeToken); - deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); - TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); + JWTClientManagerService jwtClientManagerService = CertificateMgtAPIUtils.getJwtClientManagerService(); + String jwdToken = jwtClientManagerService.getJWTClient().getJwtToken( + tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner()); - if (tenantedDeviceWrapper != null) { + ValidationResponce validationResponce = new ValidationResponce(); + validationResponce.setDeviceId(challengeToken); + validationResponce.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + validationResponce.setJWTToken(jwdToken); + validationResponce.setTenantId(tenantedDeviceWrapper.getTenantId()); + + if (tenantedDeviceWrapper != null) { + return Response.status(Response.Status.OK).entity(validationResponce).build(); + } + } + } + + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID.equalsIgnoreCase(type)) { + CertificateResponse certificateResponse = null; + if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { + certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); + } else { + X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); + if (clientCertificate != null) { + certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); + } + } + + if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse + .getCommonName().isEmpty()) { return Response.status(Response.Status.OK).entity("valid").build(); } } @@ -177,31 +273,7 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem log.error(msg, e); return Response.serverError().entity( new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); - } - return Response.status(Response.Status.OK).entity("invalid").build(); - } - - @POST - @Path("/verify/android") - public Response verifyAndroidCertificate(@ApiParam(name = "certificate", value = "Base64 encoded .pem file of the " + - "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { - CertificateResponse certificateResponse = null; - try { - CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); - if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { - certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); - } else { - X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); - if (clientCertificate != null) { - certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); - } - } - - if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse - .getCommonName().isEmpty()) { - return Response.status(Response.Status.OK).entity("valid").build(); - } - } catch (KeystoreException e) { + } catch (JWTClientException e) { String msg = "Error occurred while converting PEM file to X509Certificate."; log.error(msg, e); return Response.serverError().entity( diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java index 06bc3169fea..fc5264c4db4 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java @@ -24,6 +24,7 @@ import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import javax.ws.rs.core.MediaType; @@ -51,6 +52,21 @@ public class CertificateMgtAPIUtils { } + public static JWTClientManagerService getJwtClientManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) + ctx.getOSGiService(JWTClientManagerService.class, null); + + if (jwtClientManagerService == null) { + String msg = "JWTClientManagerService Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return jwtClientManagerService; + } + + public static SCEPManager getSCEPManagerService() { PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); diff --git a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml index 84d43cec1f3..4d3056bf11a 100644 --- a/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml +++ b/components/webapp-authenticator-framework/org.wso2.carbon.webapp.authenticator.framework/pom.xml @@ -17,7 +17,8 @@ ~ under the License. --> - + org.wso2.carbon.devicemgt webapp-authenticator-framework @@ -81,7 +82,8 @@ org.wso2.carbon.core.util, org.wso2.carbon.identity.base; version="${carbon.identity.imp.pkg.version}", org.wso2.carbon.identity.core.util; version="${carbon.identity.imp.pkg.version}", - org.wso2.carbon.identity.oauth2.*; version="${carbon.identity-inbound-auth-oauth.imp.pkg.version}", + org.wso2.carbon.identity.oauth2.*; + version="${carbon.identity-inbound-auth-oauth.imp.pkg.version}", org.wso2.carbon.tomcat.ext.valves, org.wso2.carbon.user.api, org.wso2.carbon.user.core.service, @@ -111,7 +113,7 @@ org.apache.http.impl.conn, javax.xml.soap; version="${javax.xml.soap.imp.pkg.version}", javax.xml.stream, - org.apache.axiom.*; version="${axiom.osgi.version.range}", + org.apache.axiom.*; version="${axiom.osgi.version.range}", org.wso2.carbon.registry.core.*, org.wso2.carbon.registry.common.*;version="${carbon.registry.imp.pkg.version.range}", org.wso2.carbon.registry.indexing.*; version="${carbon.registry.imp.pkg.version.range}", diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/pom.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/pom.xml new file mode 100644 index 00000000000..fceb11b4e1b --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/pom.xml @@ -0,0 +1,106 @@ + + + + + + + org.wso2.carbon.devicemgt + apimgt-extensions-feature + 2.0.6-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.apimgt.handler.server.feature + pom + 2.0.6-SNAPSHOT + WSO2 Carbon - Device Management - APIM handler Server Feature + http://wso2.org + This feature contains the handler for the api authentications + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.handlers + + + + + + + maven-resources-plugin + 2.6 + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.apimgt.handler.server + ../../../features/etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + org.eclipse.equinox.p2.type.group:false + + + + + org.wso2.carbon.devicemgt:org.wso2.carbon.apimgt.handlers:${carbon.device.mgt.version} + + + + + + + + + + + + diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/build.properties b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/build.properties new file mode 100644 index 00000000000..9c86577d768 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/conf/iot-api-config.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/conf/iot-api-config.xml new file mode 100644 index 00000000000..c9a210d3bf2 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/conf/iot-api-config.xml @@ -0,0 +1,40 @@ + + + + + + https://localhost:9443/ + + + https://localhost:9443/api/certificate-mgt/v1.0/admin/certificates/verify/ + + + admin + admin + + + https://localhost:9443/dynamic-client-web/register + + + https://localhost:9443/oauth2/token + + + /services + + \ No newline at end of file diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/p2.inf b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/p2.inf new file mode 100644 index 00000000000..e7c6acf89f2 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.handler.server.feature/src/main/resources/p2.inf @@ -0,0 +1,2 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.apimgt.handler.server_${feature.version}/conf/iot-api-config.xml,target:${installFolder}/../../conf/iot-api-config.xml,overwrite:true);\ diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/.cdm-config.xml.swp b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/src/main/resources/conf/.cdm-config.xml.swp deleted file mode 100644 index a8e6a11569ace238c1868963897a7820a82ec4ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHNO^hTr6)qOCKp-Rv;s6M68VT)+?W&pC9dYMKRs6fL&& zsk{81pY6}juWXmcE4yBoT(_@TNKaVSn>*KEdhy%B`hZwgl0}(N`Trtmz2<1j#k~Oy znxplrE43w#w4&3Iel}wwO`IN^-))D{lsZ0*$5J!{w$FXmoJ~?^kI^)XS>jakWIVCw ziCnXDbvqZ?P`48n@3Yu0N;ygFJ2T3K0}C>Xec17(*mL|~)>MD^#6FmXwXHOnhJlBb zfyb$kw`z!C5R;5zVC;G@r3)&Xz<*niZr-v2CgfnNY~;054ofCaqw8O!=PAb@q? zN#HFUO8f|T9(WY^`$gmdZvd|XF9UtxI`C!SZ;x2kkAYW!F>n*O2)zF(%lb9&8X$pP zpanbuyn_Rf-vB=WeBd_F1il3P8HXpo1bzlgfoFiP1CIcI1+Q-dKLs?$+6M@dJD?LT zXv(G7&^HpYSUsX=sTPjl# z#F7Wg3b;#ZcDI?I#WC)bjQETttyR}Km2;+kw?}8J)!E$jHa72W^*7ohuitYWoqIyr zT@ZDWj)#G#^#|ptJs50xIY)Q5yy58oji`Uup}gMh{)2K4#s!(^MKF=x0Fr7XF5EYS8A-tFFw+5LWS(sj0Wf)eyY)IlHAvvFUV0q1b=$jK zy3+Nhltk@h)t7qD7)uB+=UMy19pUB?UX?%?UU zF53=fTnsQ9=Q0jjR6V)Q$;`5EI)4Wj5`}ujRFxN*rSeeUTil7m)-+9{>-^!9{Po{j2`?>GNa-Rn*uKKt3&?0|XbYTZ66A6|li5onh@ebh#;aX@lJQ z?zs7@vpY#obpj;i{(3|*fq6vIDI;6Bqbw3;LwH1zi1})|k&uc>rWWcGiMOsmOe9!h z&v>Gz5W!oBgnY(RJueeo_C>GPxk4C+(U`D<2$z);f;GK*QE(R6gbW$0R;gF~(AK3J z?IH1o4f0%j=nb!sJKpH|{?3TpX>V`0dn0diNc!7kqu=XzYHf?B+oaw5e%@%gm(FR- zNWc>;6UJGJ{ll3K5}uq;kOIBX<#$A=nyS_hJVw#+A)yi4?5j5nn3$_x&`Hc7OC{lg z%wr6>m|RiCwFyF0z(c&7&*zvzcsns0Q^0`{MQ-9?!MWKRZZ_BKl|`XLnUNViByx;3 z4qAi#P=u$w6CBZ0R{*&$6_Hf^9KZ~3_+aX9emt6K0R;w&N0B+&1M16`K t;!CVPiLaO7^dV1fTOHctSouuBT0vQ^dV+hV?770SeBR?TC2O*+e*$B=U Date: Fri, 6 Jan 2017 17:09:46 +0530 Subject: [PATCH 13/13] Removing the hardcoded apis --- .../src/main/resources/iot-api-config.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml index c5447fb0e5b..fc65693d281 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml @@ -36,13 +36,5 @@ /services/echo - /abc - /ca - /authenticate - /enroll - /enrolled - /license - /checkin - /server \ No newline at end of file