airavata-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From scnakand...@apache.org
Subject [1/2] airavata git commit: using security classes from the services security module in airavata-services
Date Tue, 02 May 2017 17:54:09 GMT
Repository: airavata
Updated Branches:
  refs/heads/develop 28709245b -> f52352760


http://git-wip-us.apache.org/repos/asf/airavata/blob/f5235276/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/interceptor/SecurityModule.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/interceptor/SecurityModule.java
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/interceptor/SecurityModule.java
deleted file mode 100644
index 2eba1b4..0000000
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/interceptor/SecurityModule.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.airavata.api.server.security.interceptor;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.matcher.Matchers;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This does the plumbing work of integrating the interceptor with Guice framework for the
methods to be
- * intercepted upon their invocation.
- */
-public class SecurityModule extends AbstractModule {
-    private final static Logger logger = LoggerFactory.getLogger(SecurityModule.class);
-
-    public void configure(){
-        logger.info("Security module reached...");
-        SecurityInterceptor interceptor = new SecurityInterceptor();
-        //requestInjection(interceptor);
-
-        bindInterceptor(Matchers.any(), Matchers.annotatedWith(SecurityCheck.class), interceptor);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/airavata/blob/f5235276/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/oauth/DefaultOAuthClient.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/oauth/DefaultOAuthClient.java
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/oauth/DefaultOAuthClient.java
deleted file mode 100644
index 528fa17..0000000
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/oauth/DefaultOAuthClient.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.airavata.api.server.security.oauth;
-
-import org.apache.airavata.security.AiravataSecurityException;
-import org.apache.axis2.AxisFault;
-import org.apache.axis2.context.ConfigurationContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.wso2.carbon.identity.oauth2.stub.OAuth2TokenValidationServiceStub;
-import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO;
-import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationRequestDTO_OAuth2AccessToken;
-import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO;
-import org.wso2.carbon.utils.CarbonUtils;
-
-import java.rmi.RemoteException;
-
-/**
- * This is the default OAuth Client that talks to WSO2 IS's OAuth Authentication Server
- * to get the OAuth token validated.
- */
-public class DefaultOAuthClient {
-
-    private OAuth2TokenValidationServiceStub stub;
-    private final static Logger logger = LoggerFactory.getLogger(DefaultOAuthClient.class);
-    public static final String BEARER_TOKEN_TYPE = "bearer";
-
-    /**
-     * OAuth2TokenValidationService Admin Service Client
-     *
-     * @param auhorizationServerURL
-     * @param username
-     * @param password
-     * @param configCtx
-     * @throws Exception
-     */
-    public DefaultOAuthClient(String auhorizationServerURL, String username, String password,
-                              ConfigurationContext configCtx) throws AiravataSecurityException
{
-        try {
-            String serviceURL = auhorizationServerURL + "OAuth2TokenValidationService";
-            stub = new OAuth2TokenValidationServiceStub(configCtx, serviceURL);
-            CarbonUtils.setBasicAccessSecurityHeaders(username, password, true, stub._getServiceClient());
-        } catch (AxisFault e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error initializing OAuth client.");
-        }
-    }
-
-    /**
-     * Validates the OAuth 2.0 access token
-     *
-     * @param accessToken
-     * @return
-     * @throws Exception
-     */
-    public OAuth2TokenValidationResponseDTO validateAccessToken(String accessToken)
-            throws AiravataSecurityException {
-
-        try {
-            OAuth2TokenValidationRequestDTO oauthReq = new OAuth2TokenValidationRequestDTO();
-            OAuth2TokenValidationRequestDTO_OAuth2AccessToken token =
-                    new OAuth2TokenValidationRequestDTO_OAuth2AccessToken();
-            token.setIdentifier(accessToken);
-            token.setTokenType(BEARER_TOKEN_TYPE);
-            oauthReq.setAccessToken(token);
-            return stub.validate(oauthReq);
-        } catch (RemoteException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in validating the OAuth access token.");
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/airavata/blob/f5235276/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultPAPClient.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultPAPClient.java
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultPAPClient.java
deleted file mode 100644
index f82dff6..0000000
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultPAPClient.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.airavata.api.server.security.xacml;
-
-import org.apache.airavata.common.exception.ApplicationSettingsException;
-import org.apache.airavata.common.utils.ServerSettings;
-import org.apache.airavata.security.AiravataSecurityException;
-import org.apache.axis2.AxisFault;
-import org.apache.axis2.context.ConfigurationContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.wso2.carbon.identity.entitlement.stub.EntitlementPolicyAdminServiceStub;
-import org.wso2.carbon.identity.entitlement.stub.dto.PaginatedStatusHolder;
-import org.wso2.carbon.identity.entitlement.stub.dto.PolicyDTO;
-import org.wso2.carbon.identity.entitlement.stub.dto.StatusHolder;
-import org.wso2.carbon.identity.entitlement.common.EntitlementConstants;
-import org.wso2.carbon.identity.entitlement.stub.EntitlementPolicyAdminServiceEntitlementException;
-import org.wso2.carbon.utils.CarbonUtils;
-
-import java.rmi.RemoteException;
-
-/**
- * This publishes the airavata-default-xacml-policy.xml to the PDP via PAP API (of WSO2 Identity
Server)
- */
-public class DefaultPAPClient {
-
-    private final static Logger logger = LoggerFactory.getLogger(DefaultPAPClient.class);
-    private EntitlementPolicyAdminServiceStub entitlementPolicyAdminServiceStub;
-
-    public DefaultPAPClient(String auhorizationServerURL, String username, String password,
-                            ConfigurationContext configCtx) throws AiravataSecurityException
{
-        try {
-
-            String PDPURL = auhorizationServerURL + "EntitlementPolicyAdminService";
-            entitlementPolicyAdminServiceStub = new EntitlementPolicyAdminServiceStub(configCtx,
PDPURL);
-            CarbonUtils.setBasicAccessSecurityHeaders(username, password, true,
-                    entitlementPolicyAdminServiceStub._getServiceClient());
-        } catch (AxisFault e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error initializing XACML PEP client.");
-        }
-
-    }
-
-    public boolean isPolicyAdded(String policyName) {
-        try {
-            PolicyDTO policyDTO = entitlementPolicyAdminServiceStub.getPolicy(policyName,
false);
-        } catch (RemoteException e) {
-            logger.debug("Error in retrieving the policy.", e);
-            return false;
-        } catch (EntitlementPolicyAdminServiceEntitlementException e) {
-            logger.debug("Error in retrieving the policy.", e);
-            return false;
-        }
-        return true;
-    }
-
-    public void addPolicy(String policy) throws AiravataSecurityException {
-        new Thread() {
-            public void run() {
-                try {
-                    PolicyDTO policyDTO = new PolicyDTO();
-                    policyDTO.setPolicy(policy);
-                    entitlementPolicyAdminServiceStub.addPolicy(policyDTO);
-                    entitlementPolicyAdminServiceStub.publishToPDP(new String[]{ServerSettings.getAuthorizationPoliyName()},
-                            EntitlementConstants.PolicyPublish.ACTION_CREATE, null, false,
0);
-
-                    //Since policy publishing happens asynchronously, we need to retrieve
the status and verify.
-                    Thread.sleep(2000);
-                    PaginatedStatusHolder paginatedStatusHolder = entitlementPolicyAdminServiceStub.
-                            getStatusData(EntitlementConstants.Status.ABOUT_POLICY, ServerSettings.getAuthorizationPoliyName(),
-                                    EntitlementConstants.StatusTypes.PUBLISH_POLICY, "*",
1);
-                    StatusHolder statusHolder = paginatedStatusHolder.getStatusHolders()[0];
-                    if (statusHolder.getSuccess() && EntitlementConstants.PolicyPublish.ACTION_CREATE.equals(statusHolder.getTargetAction()))
{
-                        logger.info("Authorization policy is published successfully.");
-                    } else {
-                        throw new AiravataSecurityException("Failed to publish the authorization
policy.");
-                    }
-
-                    //enable the published policy
-                    entitlementPolicyAdminServiceStub.enableDisablePolicy(ServerSettings.getAuthorizationPoliyName(),
true);
-                    //Since policy enabling happens asynchronously, we need to retrieve the
status and verify.
-                    Thread.sleep(2000);
-                    paginatedStatusHolder = entitlementPolicyAdminServiceStub.
-                            getStatusData(EntitlementConstants.Status.ABOUT_POLICY, ServerSettings.getAuthorizationPoliyName(),
-                                    EntitlementConstants.StatusTypes.PUBLISH_POLICY, "*",
1);
-                    statusHolder = paginatedStatusHolder.getStatusHolders()[0];
-                    if (statusHolder.getSuccess() && EntitlementConstants.PolicyPublish.ACTION_ENABLE.equals(statusHolder.getTargetAction()))
{
-                        logger.info("Authorization policy is enabled successfully.");
-                    } else {
-                        throw new AiravataSecurityException("Failed to enable the authorization
policy.");
-                    }
-                } catch (RemoteException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (InterruptedException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (ApplicationSettingsException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (AiravataSecurityException e) {
-                    logger.error(e.getMessage(), e);
-                } catch (EntitlementPolicyAdminServiceEntitlementException e) {
-                    logger.error(e.getMessage(), e);
-                }
-            }
-        }.start();
-    }
-}

http://git-wip-us.apache.org/repos/asf/airavata/blob/f5235276/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultXACMLPEP.java
----------------------------------------------------------------------
diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultXACMLPEP.java
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultXACMLPEP.java
deleted file mode 100644
index e0ef142..0000000
--- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/security/xacml/DefaultXACMLPEP.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF 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.apache.airavata.api.server.security.xacml;
-
-import org.apache.airavata.common.utils.Constants;
-import org.apache.airavata.model.security.AuthzToken;
-import org.apache.airavata.security.AiravataSecurityException;
-import org.apache.axis2.AxisFault;
-import org.apache.axis2.context.ConfigurationContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.wso2.carbon.identity.entitlement.stub.EntitlementServiceException;
-import org.wso2.carbon.identity.entitlement.stub.EntitlementServiceStub;
-import org.wso2.carbon.utils.CarbonUtils;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.rmi.RemoteException;
-import java.util.Map;
-
-/**
- * This enforces XACML based fine grained authorization on the API calls, by authorizing
the API calls
- * through default PDP which is WSO2 Identity Server.
- */
-public class DefaultXACMLPEP {
-
-    private final static Logger logger = LoggerFactory.getLogger(DefaultXACMLPEP.class);
-    private EntitlementServiceStub entitlementServiceStub;
-
-    public DefaultXACMLPEP(String auhorizationServerURL, String username, String password,
-                           ConfigurationContext configCtx) throws AiravataSecurityException
{
-        try {
-
-            String PDPURL = auhorizationServerURL + "EntitlementService";
-            entitlementServiceStub = new EntitlementServiceStub(configCtx, PDPURL);
-            CarbonUtils.setBasicAccessSecurityHeaders(username, password, true, entitlementServiceStub._getServiceClient());
-        } catch (AxisFault e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error initializing XACML PEP client.");
-        }
-
-    }
-
-    /**
-     * Send the XACML authorization request to XAML PDP and return the authorization decision.
-     *
-     * @param authzToken
-     * @param metaData
-     * @return
-     */
-    public boolean getAuthorizationDecision(AuthzToken authzToken, Map<String, String>
metaData) throws AiravataSecurityException {
-        String decision;
-        try {
-            String subject = authzToken.getClaimsMap().get(Constants.USER_NAME);
-            //FIXME hacky way to fix OpenID -> CILogon issue in WSO2 IS
-            if(subject.startsWith("http://")){
-                subject = subject.substring(6);
-            }
-            String action = "/airavata/" + metaData.get(Constants.API_METHOD_NAME);
-            String decisionString = entitlementServiceStub.getDecisionByAttributes(subject,
null, action, null);
-            //parse the XML decision string and obtain the decision
-            decision = parseDecisionString(decisionString);
-            if (Constants.PERMIT.equals(decision)) {
-                return true;
-            } else {
-                logger.error("Authorization decision is: " + decision);
-                return false;
-            }
-        } catch (RemoteException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in authorizing the user.");
-        } catch (EntitlementServiceException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in authorizing the user.");
-        }
-    }
-
-    /**
-     * This parses the XML based authorization response by the PDP and returns the decision
string.
-     *
-     * @param decisionString
-     * @return
-     * @throws AiravataSecurityException
-     */
-    private String parseDecisionString(String decisionString) throws AiravataSecurityException
{
-        try {
-            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
-            InputStream inputStream = new ByteArrayInputStream(decisionString.getBytes("UTF-8"));
-            Document doc = docBuilderFactory.newDocumentBuilder().parse(inputStream);
-            Node resultNode = doc.getDocumentElement().getFirstChild();
-            Node decisionNode = resultNode.getFirstChild();
-            String decision = decisionNode.getTextContent();
-            return decision;
-        } catch (ParserConfigurationException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in parsing XACML authorization response.");
-        } catch (UnsupportedEncodingException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in parsing XACML authorization response.");
-        } catch (SAXException e) {
-            logger.error(e.getMessage(), e);
-            throw new AiravataSecurityException("Error in parsing XACML authorization response.");
-        } catch (IOException e) {
-            logger.error("Error in parsing XACML authorization response.");
-            throw new AiravataSecurityException("Error in parsing XACML authorization response.");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/airavata/blob/f5235276/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
new file mode 100644
index 0000000..b319540
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/KeyCloakSecurityManager.java
@@ -0,0 +1,289 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.airavata.service.security;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.Constants;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.credential.store.client.CredentialStoreClientFactory;
+import org.apache.airavata.credential.store.cpi.CredentialStoreService;
+import org.apache.airavata.credential.store.exception.CredentialStoreException;
+import org.apache.airavata.model.appcatalog.gatewayprofile.GatewayResourceProfile;
+import org.apache.airavata.model.credential.store.PasswordCredential;
+import org.apache.airavata.model.security.AuthzToken;
+import org.apache.airavata.registry.api.client.RegistryServiceClientFactory;
+import org.apache.airavata.registry.api.exception.RegistryServiceException;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.apache.airavata.security.util.TrustStoreManager;
+import org.apache.airavata.service.security.authzcache.*;
+import org.apache.airavata.registry.api.RegistryService;
+import org.apache.thrift.TException;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class KeyCloakSecurityManager implements AiravataSecurityManager {
+    private final static Logger logger = LoggerFactory.getLogger(KeyCloakSecurityManager.class);
+
+    private HashMap<String, String> rolePermissionConfig = new HashMap<>();
+
+
+    public KeyCloakSecurityManager() throws AiravataSecurityException {
+        rolePermissionConfig.put("admin", "/airavata/.*");
+        rolePermissionConfig.put("gateway-provider", "/airavata/.*");
+        rolePermissionConfig.put("admin-read-only", "/airavata/getSSHPubKey|/airavata/getAllGatewaySSHPubKeys"
+
+                "|/airavata/getAllGatewayPWDCredentials|/airavata/getApplicationModule|/airavata/getAllAppModules"
+
+                "|/airavata/getApplicationDeployment|/airavata/getAllApplicationDeployments|/airavata/getAppModuleDeployedResources"
+
+                "|/airavata/getStorageResource|/airavata/getAllStorageResourceNames|/airavata/getSCPDataMovement"
+
+                "|/airavata/getUnicoreDataMovement|/airavata/getGridFTPDataMovement|/airavata/getResourceJobManager"
+
+                "|/airavata/deleteResourceJobManager|/airavata/getGatewayResourceProfile|/airavata/getGatewayComputeResourcePreference"
+
+                "|/airavata/getGatewayStoragePreference|/airavata/getAllGatewayComputeResourcePreferences"
+
+                "|/airavata/getAllGatewayStoragePreferences|/airavata/getAllGatewayResourceProfiles|/airavata/getAPIVersion"
+
+                "|/airavata/getNotification|/airavata/getAllNotifications|/airavata/createProject|/airavata/updateProject"
+
+                "|/airavata/getProject|/airavata/deleteProject|/airavata/getUserProjects|/airavata/searchProjectsByProjectName"
+
+                "|/airavata/searchProjectsByProjectDesc|/airavata/searchExperimentsByName|/airavata/searchExperimentsByDesc"
+
+                "|/airavata/searchExperimentsByApplication|/airavata/searchExperimentsByStatus|/airavata/searchExperimentsByCreationTime"
+
+                "|/airavata/searchExperiments|/airavata/getExperimentStatistics|/airavata/getExperimentsInProject"
+
+                "|/airavata/getUserExperiments|/airavata/createExperiment|/airavata/deleteExperiment|/airavata/getExperiment"
+
+                "|/airavata/getDetailedExperimentTree|/airavata/updateExperiment|/airavata/updateExperimentConfiguration"
+
+                "|/airavata/updateResourceScheduleing|/airavata/validateExperiment|/airavata/launchExperiment"
+
+                "|/airavata/getExperimentStatus|/airavata/getExperimentOutputs|/airavata/getIntermediateOutputs"
+
+                "|/airavata/getJobStatuses|/airavata/getJobDetails|/airavata/cloneExperiment|/airavata/terminateExperiment"
+
+                "|/airavata/getApplicationInterface|/airavata/getAllApplicationInterfaceNames|/airavata/getAllApplicationInterfaces"
+
+                "|/airavata/getApplicationInputs|/airavata/getApplicationOutputs|/airavata/getAvailableAppInterfaceComputeResources"
+
+                "|/airavata/getComputeResource|/airavata/getAllComputeResourceNames|/airavata/getWorkflow|/airavata/getWorkflowTemplateId"
+
+                "|/airavata/isWorkflowExistWithName|/airavata/registerDataProduct|/airavata/getDataProduct|/airavata/registerReplicaLocation"
+
+                "|/airavata/getParentDataProduct|/airavata/getChildDataProducts");
+        rolePermissionConfig.put("gateway-user", "/airavata/getAPIVersion|/airavata/getNotification|/airavata/getAllNotifications|"
+
+                "/airavata/createProject|/airavata/updateProject|/airavata/getProject|/airavata/deleteProject|/airavata/getUserProjects|"
+
+                "/airavata/searchProjectsByProjectName|/airavata/searchProjectsByProjectDesc|/airavata/searchExperimentsByName|"
+
+                "/airavata/searchExperimentsByDesc|/airavata/searchExperimentsByApplication|/airavata/searchExperimentsByStatus|"
+
+                "/airavata/searchExperimentsByCreationTime|/airavata/searchExperiments|/airavata/getExperimentStatistics|"
+
+                "/airavata/getExperimentsInProject|/airavata/getUserExperiments|/airavata/createExperiment|/airavata/deleteExperiment|"
+
+                "/airavata/getExperiment|/airavata/getDetailedExperimentTree|/airavata/updateExperiment|/airavata/updateExperimentConfiguration|"
+
+                "/airavata/updateResourceScheduleing|/airavata/validateExperiment|/airavata/launchExperiment|/airavata/getExperimentStatus|"
+
+                "/airavata/getExperimentOutputs|/airavata/getIntermediateOutputs|/airavata/getJobStatuses|/airavata/getJobDetails|"
+
+                "/airavata/cloneExperiment|/airavata/terminateExperiment|/airavata/getApplicationInterface|/airavata/getAllApplicationInterfaceNames|"
+
+                "/airavata/getAllApplicationInterfaces|/airavata/getApplicationInputs|/airavata/getApplicationOutputs|"
+
+                "/airavata/getAvailableAppInterfaceComputeResources|/airavata/getComputeResource|/airavata/getAllComputeResourceNames|"
+
+                "/airavata/getWorkflow|/airavata/getWorkflowTemplateId|/airavata/isWorkflowExistWithName|/airavata/registerDataProduct|"
+
+                "/airavata/getDataProduct|/airavata/registerReplicaLocation|/airavata/getParentDataProduct|/airavata/getChildDataProducts");
+
+        initializeSecurityInfra();
+    }
+
+    /**
+     * Implement this method in your SecurityManager to perform necessary initializations
at the server startup.
+     *
+     * @throws AiravataSecurityException
+     */
+    @Override
+    public void initializeSecurityInfra() throws AiravataSecurityException {
+        try {
+            //initialize SSL context with the trust store that contains the public cert of
WSO2 Identity Server.
+            TrustStoreManager trustStoreManager = new TrustStoreManager();
+            trustStoreManager.initializeTrustStoreManager(ServerSettings.getTrustStorePath(),
+                    ServerSettings.getTrustStorePassword());
+        } catch (Exception e) {
+            throw new AiravataSecurityException(e.getMessage(), e);
+        }
+
+    }
+
+    /**
+     * Implement this method with the user authentication/authorization logic in your SecurityManager.
+     *
+     * @param authzToken : this includes OAuth token and user's claims
+     * @param metaData   : this includes other meta data needed for security enforcements.
+     * @return
+     * @throws AiravataSecurityException
+     */
+    @Override
+    public boolean isUserAuthorized(AuthzToken authzToken, Map<String, String> metaData)
throws AiravataSecurityException {
+        String subject = authzToken.getClaimsMap().get(Constants.USER_NAME);
+        String accessToken = authzToken.getAccessToken();
+        String gatewayId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID);
+        String action = "/airavata/" + metaData.get(Constants.API_METHOD_NAME);
+        try {
+            if (!ServerSettings.isAPISecured()) {
+                return true;
+            }
+
+            if (ServerSettings.isAuthzCacheEnabled()) {
+                //obtain an instance of AuthzCacheManager implementation.
+                AuthzCacheManager authzCacheManager = AuthzCacheManagerFactory.getAuthzCacheManager();
+
+                //check in the cache
+                AuthzCachedStatus authzCachedStatus = authzCacheManager.getAuthzCachedStatus(
+                        new AuthzCacheIndex(subject, gatewayId, accessToken, action));
+
+                if (AuthzCachedStatus.AUTHORIZED.equals(authzCachedStatus)) {
+                    logger.debug("Authz decision for: (" + subject + ", " + accessToken +
", " + action + ") is retrieved from cache.");
+                    return true;
+                } else if (AuthzCachedStatus.NOT_AUTHORIZED.equals(authzCachedStatus)) {
+                    logger.debug("Authz decision for: (" + subject + ", " + accessToken +
", " + action + ") is retrieved from cache.");
+                    return false;
+                } else if (AuthzCachedStatus.NOT_CACHED.equals(authzCachedStatus)) {
+                    logger.debug("Authz decision for: (" + subject + ", " + accessToken +
", " + action + ") is not in the cache. " +
+                            "Obtaining it from the authorization server.");
+                    String[] roles = getUserRolesFromOAuthToken(subject, accessToken, gatewayId);
+                    boolean authorizationDecision = hasPermission(roles, action);
+                    //cache the authorization decision
+                    long currentTime = System.currentTimeMillis();
+                    //TODO get the actual token expiration time
+                    authzCacheManager.addToAuthzCache(new AuthzCacheIndex(subject, gatewayId,
accessToken, action),
+                            new AuthzCacheEntry(authorizationDecision, currentTime + 1000
* 60 * 60, currentTime));
+                    return authorizationDecision;
+                } else {
+                    //undefined status returned from the authz cache manager
+                    throw new AiravataSecurityException("Error in reading from the authorization
cache.");
+                }
+            } else {
+                String[] roles = getUserRolesFromOAuthToken(subject, accessToken, gatewayId);
+                return hasPermission(roles, action);
+            }
+
+        } catch (ApplicationSettingsException e) {
+            e.printStackTrace();
+            throw new AiravataSecurityException(e.getMessage(), e);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new AiravataSecurityException(e.getMessage(), e);
+        }
+    }
+
+    private String[] getUserRolesFromOAuthToken(String username, String token, String gatewayId)
throws Exception {
+        GatewayResourceProfile gwrp = getRegistryServiceClient().getGatewayResourceProfile(gatewayId);
+        String identityServerRealm = gwrp.getIdentityServerTenant();
+        String openIdConnectUrl = getOpenIDConfigurationUrl(identityServerRealm);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, token));
+        String userInfoEndPoint = openIdConnectConfig.getString("userinfo_endpoint");
+        JSONObject userInfo = new JSONObject(getFromUrl(userInfoEndPoint, token));
+        if (!username.equals(userInfo.get("preferred_username"))) {
+            throw new AiravataSecurityException("Subject name and username for the token
doesn't match");
+        }
+        String userId = userInfo.getString("sub");
+
+        String userRoleMappingUrl = ServerSettings.getRemoteIDPServiceUrl() + "/admin/realms/"
+                + identityServerRealm + "/users/"
+                + userId + "/role-mappings/realm";
+        JSONArray roleMappings = new JSONArray(getFromUrl(userRoleMappingUrl, getAdminAccessToken(gatewayId)));
+        String[] roles = new String[roleMappings.length()];
+        for (int i = 0; i < roleMappings.length(); i++) {
+            roles[i] = (new JSONObject(roleMappings.get(i).toString())).get("name").toString();
+        }
+
+        return roles;
+    }
+
+    private String getOpenIDConfigurationUrl(String realm) throws ApplicationSettingsException
{
+        return ServerSettings.getRemoteIDPServiceUrl() + "/realms/" + realm + "/.well-known/openid-configuration";
+    }
+
+    public String getFromUrl(String urlToRead, String token) throws Exception {
+        StringBuilder result = new StringBuilder();
+        URL url = new URL(urlToRead);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setRequestMethod("GET");
+        if (token != null) {
+            String bearerAuth = "Bearer " + token;
+            conn.setRequestProperty("Authorization", bearerAuth);
+        }
+        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+        String line;
+        while ((line = rd.readLine()) != null) {
+            result.append(line);
+        }
+        rd.close();
+        return result.toString();
+    }
+
+    private String getAdminAccessToken(String gatewayId) throws Exception {
+        CredentialStoreService.Client csClient = getCredentialStoreServiceClient();
+        GatewayResourceProfile gwrp = getRegistryServiceClient().getGatewayResourceProfile(gatewayId);
+        String identityServerRealm = gwrp.getIdentityServerTenant();
+        String openIdConnectUrl = getOpenIDConfigurationUrl(identityServerRealm);
+        JSONObject openIdConnectConfig = new JSONObject(getFromUrl(openIdConnectUrl, null));
+        PasswordCredential credential = csClient.getPasswordCredential(gwrp.getIdentityServerPwdCredToken(),
gwrp.getGatewayID());
+        String username = credential.getLoginUserName();
+        String password = credential.getPassword();
+        String urlString = openIdConnectConfig.getString("token_endpoint");
+        StringBuilder result = new StringBuilder();
+        URL url = new URL(urlString);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        conn.setRequestMethod("POST");
+        conn.setDoOutput(true);
+        String postFields = "client_id=admin-cli&username=" + username + "&password="
+ password + "&grant_type=password";
+        conn.getOutputStream().write(postFields.getBytes());
+        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+        String line;
+        while ((line = rd.readLine()) != null) {
+            result.append(line);
+        }
+        rd.close();
+        JSONObject tokenInfo = new JSONObject(result.toString());
+        return tokenInfo.get("access_token").toString();
+    }
+
+
+    private boolean hasPermission(String[] roles, String apiMethod) {
+        for (int i = 0; i < roles.length; i++) {
+            String role = roles[i];
+            if (this.rolePermissionConfig.keySet().contains(role)) {
+                Pattern pattern = Pattern.compile(this.rolePermissionConfig.get(role));
+                Matcher matcher = pattern.matcher(apiMethod);
+                if (matcher.matches())
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    private RegistryService.Client getRegistryServiceClient() throws TException, ApplicationSettingsException
{
+        final int serverPort = Integer.parseInt(ServerSettings.getRegistryServerPort());
+        final String serverHost = ServerSettings.getRegistryServerHost();
+        try {
+            return RegistryServiceClientFactory.createRegistryClient(serverHost, serverPort);
+        } catch (RegistryServiceException e) {
+            throw new TException("Unable to create registry client...", e);
+        }
+    }
+
+    private CredentialStoreService.Client getCredentialStoreServiceClient() throws TException,
ApplicationSettingsException {
+        final int serverPort = Integer.parseInt(ServerSettings.getCredentialStoreServerPort());
+        final String serverHost = ServerSettings.getCredentialStoreServerHost();
+        try {
+            return CredentialStoreClientFactory.createAiravataCSClient(serverHost, serverPort);
+        } catch (CredentialStoreException e) {
+            throw new TException("Unable to create credential store client...", e);
+        }
+    }
+}
\ No newline at end of file


Mime
View raw message