You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sc...@apache.org on 2017/04/05 19:10:43 UTC
[19/50] [abbrv] airavata git commit: Add code for airavata-services
security
Add code for airavata-services security
Project: http://git-wip-us.apache.org/repos/asf/airavata/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/6e5530c1
Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/6e5530c1
Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/6e5530c1
Branch: refs/heads/develop
Commit: 6e5530c1465825aef82132bf0ab3e32183178560
Parents: 0e9c08f
Author: Gourav Shenoy <sh...@gmail.com>
Authored: Mon Apr 3 22:24:26 2017 -0400
Committer: Gourav Shenoy <sh...@gmail.com>
Committed: Mon Apr 3 22:24:26 2017 -0400
----------------------------------------------------------------------
airavata-services/pom.xml | 5 +
airavata-services/services-security/pom.xml | 73 +++++
.../security/AiravataSecurityManager.java | 43 +++
.../DefaultAiravataSecurityManager.java | 273 +++++++++++++++++++
.../service/security/IdentityContext.java | 44 +++
.../apache/airavata/service/security/Main.java | 179 ++++++++++++
.../security/SecurityManagerFactory.java | 60 ++++
.../service/security/authzcache/AuthzCache.java | 61 +++++
.../security/authzcache/AuthzCacheEntry.java | 63 +++++
.../security/authzcache/AuthzCacheIndex.java | 90 ++++++
.../security/authzcache/AuthzCacheManager.java | 80 ++++++
.../authzcache/AuthzCacheManagerFactory.java | 60 ++++
.../security/authzcache/AuthzCachedStatus.java | 34 +++
.../authzcache/DefaultAuthzCacheManager.java | 106 +++++++
.../security/interceptor/SecurityCheck.java | 37 +++
.../interceptor/SecurityInterceptor.java | 83 ++++++
.../security/interceptor/SecurityModule.java | 43 +++
.../security/oauth/DefaultOAuthClient.java | 91 +++++++
.../security/xacml/DefaultPAPClient.java | 125 +++++++++
.../service/security/xacml/DefaultXACMLPEP.java | 133 +++++++++
20 files changed, 1683 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/pom.xml
----------------------------------------------------------------------
diff --git a/airavata-services/pom.xml b/airavata-services/pom.xml
index f4f701b..15b8b19 100644
--- a/airavata-services/pom.xml
+++ b/airavata-services/pom.xml
@@ -51,6 +51,11 @@
<artifactId>airavata-server-configuration</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-data-models</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<modules>
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/pom.xml
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/pom.xml b/airavata-services/services-security/pom.xml
index b2b6f49..b5afc26 100644
--- a/airavata-services/services-security/pom.xml
+++ b/airavata-services/services-security/pom.xml
@@ -16,4 +16,77 @@
<name>Airavata Services Security</name>
<url>http://airavata.apache.org/</url>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store-stubs</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-security</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>registry-api-stubs</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
+ <version>4.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.axis2.wso2</groupId>
+ <artifactId>axis2</artifactId>
+ <version>1.6.1.wso2v4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.utils</artifactId>
+ <version>4.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.identity.entitlement.stub</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.wso2.carbon</groupId>
+ <artifactId>org.wso2.carbon.identity.entitlement.common</artifactId>
+ <version>4.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>4.0</version>
+ </dependency>
+ <dependency>
+ <groupId>aopalliance</groupId>
+ <artifactId>aopalliance</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.oltu.oauth2</groupId>
+ <artifactId>org.apache.oltu.oauth2.client</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>1.9.13</version>
+ </dependency>
+ </dependencies>
+
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/AiravataSecurityManager.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/AiravataSecurityManager.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/AiravataSecurityManager.java
new file mode 100644
index 0000000..1bf5b0d
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/AiravataSecurityManager.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.model.security.AuthzToken;
+import org.apache.airavata.security.AiravataSecurityException;
+
+import java.util.Map;
+
+public interface AiravataSecurityManager {
+ /**
+ * Implement this method in your SecurityManager to perform necessary initializations at the server startup.
+ * @throws AiravataSecurityException
+ */
+ public void initializeSecurityInfra() throws AiravataSecurityException;
+
+ /**
+ * 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
+ */
+ public boolean isUserAuthorized(AuthzToken authzToken, Map<String, String> metaData) throws AiravataSecurityException;
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/DefaultAiravataSecurityManager.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/DefaultAiravataSecurityManager.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/DefaultAiravataSecurityManager.java
new file mode 100644
index 0000000..25fb0eb
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/DefaultAiravataSecurityManager.java
@@ -0,0 +1,273 @@
+/*
+ *
+ * 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.RegistryService;
+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.service.security.oauth.DefaultOAuthClient;
+import org.apache.airavata.service.security.xacml.DefaultPAPClient;
+import org.apache.airavata.service.security.xacml.DefaultXACMLPEP;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.ConfigurationContextFactory;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO;
+
+import java.io.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This enforces authentication and authorization on Airavata API calls.
+ */
+public class DefaultAiravataSecurityManager implements AiravataSecurityManager {
+ private final static Logger logger = LoggerFactory.getLogger(DefaultAiravataSecurityManager.class);
+
+ @Override
+ public void initializeSecurityInfra() throws AiravataSecurityException {
+ /* in the default security manager, this method checks if the xacml authorization policy is published,
+ * and if not, publish the policy to the PDP (of WSO2 Identity Server)
+ */
+ try {
+ if (ServerSettings.isAPISecured()) {
+ ConfigurationContext configContext =
+ ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
+ //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());
+ List<GatewayResourceProfile> gwProfiles = getRegistryServiceClient().getAllGatewayResourceProfiles();
+ //read the policy as a string
+ BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(
+ ServerSettings.getAuthorizationPoliyName() + ".xml")));
+ String line;
+ StringBuilder stringBuilder = new StringBuilder();
+ while ((line = bufferedReader.readLine()) != null) {
+ stringBuilder.append(line);
+ }
+ String defaultXACMLPolicy = stringBuilder.toString();
+ CredentialStoreService.Client csClient = getCredentialStoreServiceClient();
+
+ for(GatewayResourceProfile gwrp : gwProfiles){
+ if(gwrp.getIdentityServerPwdCredToken() != null && gwrp.getIdentityServerTenant() != null){
+ PasswordCredential credential = csClient.getPasswordCredential(gwrp.getIdentityServerPwdCredToken(), gwrp.getGatewayID());
+ String username = credential.getLoginUserName();
+ if(gwrp.getIdentityServerTenant() != null && !gwrp.getIdentityServerTenant().isEmpty())
+ username = username + "@" + gwrp.getIdentityServerTenant();
+ String password = credential.getPassword();
+ DefaultPAPClient PAPClient = new DefaultPAPClient(ServerSettings.getRemoteAuthzServerUrl(),
+ username, password, configContext);
+ boolean policyAdded = PAPClient.isPolicyAdded(ServerSettings.getAuthorizationPoliyName());
+ if (policyAdded) {
+ logger.debug("Authorization policy is already added in the authorization server.");
+ } else {
+ //publish the policy and enable it in a separate thread
+ PAPClient.addPolicy(defaultXACMLPolicy);
+ logger.debug("Authorization policy is published in the authorization server.");
+ }
+ }else{
+ logger.warn("Identity Server configuration missing for gateway : " + gwrp.getGatewayID());
+ }
+ }
+ }
+ } catch (AxisFault axisFault) {
+ logger.error(axisFault.getMessage(), axisFault);
+ throw new AiravataSecurityException("Error in initializing the configuration context for creating the " +
+ "PAP client.");
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in reading configuration when creating the PAP client.");
+ } catch (FileNotFoundException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in reading authorization policy.");
+ } catch (IOException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in reading the authorization policy.");
+ } catch (RegistryServiceException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in reading the Gateway Profiles from App Catalog.");
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in connecting to Credential Store Service.");
+ }
+ }
+
+ public boolean isUserAuthorized(AuthzToken authzToken, Map<String, String> metaData) throws AiravataSecurityException {
+ try {
+ String subject = authzToken.getClaimsMap().get(Constants.USER_NAME);
+ String accessToken = authzToken.getAccessToken();
+ String gatewayId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID);
+ String action = metaData.get(Constants.API_METHOD_NAME);
+
+ //if the authz cache is enabled, check in the cache if the authz decision is cached and if so, what the status is
+ 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.");
+
+ CredentialStoreService.Client csClient = getCredentialStoreServiceClient();
+ GatewayResourceProfile gwrp = getRegistryServiceClient().getGatewayResourceProfile(gatewayId);
+ PasswordCredential credential = csClient.getPasswordCredential(gwrp.getIdentityServerPwdCredToken(), gwrp.getGatewayID());
+ String username = credential.getLoginUserName();
+ if(gwrp.getIdentityServerTenant() != null && !gwrp.getIdentityServerTenant().isEmpty())
+ username = username + "@" + gwrp.getIdentityServerTenant();
+ String password = credential.getPassword();
+
+ //talk to Authorization Server, obtain the decision, cache it and return the result.
+ ConfigurationContext configContext =
+ ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
+
+ //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());
+
+ DefaultOAuthClient oauthClient = new DefaultOAuthClient(ServerSettings.getRemoteAuthzServerUrl(),
+ username, password, configContext);
+ OAuth2TokenValidationResponseDTO validationResponse = oauthClient.validateAccessToken(
+ authzToken.getAccessToken());
+ if(validationResponse.getValid()){
+ String authorizedUserName = validationResponse.getAuthorizedUser();
+ if(authorizedUserName.contains("@")){
+ authorizedUserName = authorizedUserName.split("@")[0];
+ }
+ if(subject.contains("@")){
+ subject = subject.split("@")[0];
+ }
+ //cannot impersonate users
+ if(!authorizedUserName.toLowerCase().equals(subject.toLowerCase()))
+ return false;
+
+ long expiryTimestamp = validationResponse.getExpiryTime();
+
+ //check for fine grained authorization for the API invocation, based on XACML.
+ DefaultXACMLPEP entitlementClient = new DefaultXACMLPEP(ServerSettings.getRemoteAuthzServerUrl(),
+ username, password, configContext);
+ boolean authorizationDecision = entitlementClient.getAuthorizationDecision(authzToken, metaData);
+
+ //cache the authorization decision
+ authzCacheManager.addToAuthzCache(new AuthzCacheIndex(subject, gatewayId, accessToken, action),
+ new AuthzCacheEntry(authorizationDecision, expiryTimestamp, System.currentTimeMillis()));
+
+ return authorizationDecision;
+ }else {
+ return false;
+ }
+
+
+ } else {
+ //undefined status returned from the authz cache manager
+ throw new AiravataSecurityException("Error in reading from the authorization cache.");
+ }
+ } else {
+ CredentialStoreService.Client csClient = getCredentialStoreServiceClient();
+ GatewayResourceProfile gwrp = getRegistryServiceClient().getGatewayResourceProfile(gatewayId);
+ PasswordCredential credential = csClient.getPasswordCredential(gwrp.getIdentityServerPwdCredToken(), gwrp.getGatewayID());
+ String username = credential.getLoginUserName();
+ if(gwrp.getIdentityServerTenant() != null && !gwrp.getIdentityServerTenant().isEmpty())
+ username = username + "@" + gwrp.getIdentityServerTenant();
+ String password = credential.getPassword();
+
+ //talk to Authorization Server, obtain the decision and return the result (authz cache is not enabled).
+ ConfigurationContext configContext =
+ ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
+
+ //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());
+
+ DefaultOAuthClient oauthClient = new DefaultOAuthClient(ServerSettings.getRemoteAuthzServerUrl(),
+ username, password, configContext);
+ OAuth2TokenValidationResponseDTO validationResponse = oauthClient.validateAccessToken(
+ authzToken.getAccessToken());
+ boolean isOAuthTokenValid = validationResponse.getValid();
+ //if XACML based authorization is enabled, check for role based authorization for the API invocation
+ DefaultXACMLPEP entitlementClient = new DefaultXACMLPEP(ServerSettings.getRemoteAuthzServerUrl(),
+ username, password, configContext);
+ boolean authorizationDecision = entitlementClient.getAuthorizationDecision(authzToken, metaData);
+
+ return (isOAuthTokenValid && authorizationDecision);
+ }
+
+ } catch (AxisFault axisFault) {
+ logger.error(axisFault.getMessage(), axisFault);
+ throw new AiravataSecurityException("Error in initializing the configuration context for creating the OAuth validation client.");
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in reading OAuth server configuration.");
+ } catch (RegistryServiceException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in accessing AppCatalog.");
+ } catch (TException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in connecting to Credential Store Service.");
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/IdentityContext.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/IdentityContext.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/IdentityContext.java
new file mode 100644
index 0000000..f11f63f
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/IdentityContext.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.model.security.AuthzToken;
+
+/**
+ * This provides a thread local container for AuthzToken through out the execution of a particular thread.
+ */
+public class IdentityContext {
+ private static ThreadLocal authzTokenContainer = new ThreadLocal();
+
+ public static void set(AuthzToken authzToken){
+ authzTokenContainer.set(authzToken);
+ }
+
+ public static void unset(){
+ authzTokenContainer.remove();
+ }
+
+ public static AuthzToken get(){
+ return (AuthzToken) authzTokenContainer.get();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/Main.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/Main.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/Main.java
new file mode 100644
index 0000000..dcc9478
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/Main.java
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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.utils.Constants;
+import org.apache.airavata.model.error.AuthenticationException;
+import org.apache.airavata.model.security.AuthzToken;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.apache.airavata.service.security.oauth.DefaultOAuthClient;
+import org.apache.airavata.service.security.xacml.DefaultXACMLPEP;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.ConfigurationContextFactory;
+import org.apache.oltu.oauth2.client.URLConnectionClient;
+import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
+import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
+import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
+import org.apache.oltu.oauth2.common.OAuth;
+import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.wso2.carbon.identity.oauth2.stub.dto.OAuth2TokenValidationResponseDTO;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Main {
+ private final static Logger logger = LoggerFactory.getLogger(Main.class);
+
+ private static String username = "scigap_admin";
+ private static String password = "sci9067@min";
+ private static String hostName = "https://idp.scigap.org:7443";
+// private static String clientId = "KUu0a74dFbrwvSxD3C_GhwKeNrQa";
+ private static String clientId = "O3iUdkkVYyHgzWPiVTQpY_tb96Ma";
+// private static String clientSecret = "UTKb9nDOPsuWB4lEX39TwhkW8qIa";
+ private static String clientSecret = "6Ck1jZoa2oRtrzodSqkUZ2iINkUa";
+
+ public static void main(String[] args) throws AuthenticationException, AiravataSecurityException, AxisFault {
+ String accessToken = authenticate("master@master.airavata", "master").getAccess_token();
+ ConfigurationContext configContext =
+ ConfigurationContextFactory.createConfigurationContextFromFileSystem(null, null);
+ DefaultOAuthClient defaultOAuthClient = new DefaultOAuthClient(hostName+"/services/",username,password, configContext);
+ OAuth2TokenValidationResponseDTO tokenValidationRequestDTO = defaultOAuthClient.validateAccessToken(accessToken);
+ String authorizedUser = tokenValidationRequestDTO.getAuthorizedUser();
+ AuthzToken authzToken = new AuthzToken();
+ authzToken.setAccessToken(accessToken);
+ Map<String, String> claimsMap = new HashMap<>();
+ claimsMap.put(Constants.USER_NAME, "scigap_admin");
+ claimsMap.put(Constants.API_METHOD_NAME, "/airavata/getAPIVersion");
+ authzToken.setClaimsMap(claimsMap);
+
+ DefaultXACMLPEP defaultXACMLPEP = new DefaultXACMLPEP(hostName+"/services/",username,password,configContext);
+ HashMap<String, String> metaDataMap = new HashMap();
+ boolean result = defaultXACMLPEP.getAuthorizationDecision(authzToken, metaDataMap);
+ System.out.println(result);
+ }
+
+ public static AuthResponse authenticate(String username,String password) throws AuthenticationException {
+ try {
+ OAuthClientRequest request = OAuthClientRequest.tokenLocation(hostName+"/oauth2/token").
+ setClientId(clientId).setClientSecret(clientSecret).
+ setGrantType(GrantType.PASSWORD).
+ setRedirectURI("").
+ setUsername(username).
+ setPassword(password).
+ setScope("openid").
+ buildBodyMessage();
+
+
+ URLConnectionClient ucc = new URLConnectionClient();
+
+ org.apache.oltu.oauth2.client.OAuthClient oAuthClient = new org.apache.oltu.oauth2.client.OAuthClient(ucc);
+ OAuthResourceResponse resp = oAuthClient.resource(request, OAuth.HttpMethod.POST, OAuthResourceResponse.class);
+
+ //converting JSON to object
+ ObjectMapper mapper = new ObjectMapper();
+ AuthResponse authResponse;
+ try{
+ authResponse = mapper.readValue(resp.getBody(), AuthResponse.class);
+ }catch (Exception e){
+ return null;
+ }
+
+ String accessToken = authResponse.getAccess_token();
+ if(accessToken != null && !accessToken.isEmpty()){
+ request = new OAuthBearerClientRequest(hostName + "/oauth2/userinfo?schema=openid").
+ buildQueryMessage();
+ ucc = new URLConnectionClient();
+ request.setHeader("Authorization","Bearer "+accessToken);
+ oAuthClient = new org.apache.oltu.oauth2.client.OAuthClient(ucc);
+ resp = oAuthClient.resource(request, OAuth.HttpMethod.GET,
+ OAuthResourceResponse.class);
+ Map<String,String> profile = mapper.readValue(resp.getBody(), Map.class);
+ return authResponse;
+ }
+ }catch (Exception ex){
+ throw new AuthenticationException(ex.getMessage());
+ }
+ return null;
+ }
+}
+
+class AuthResponse{
+
+ private String token_type;
+ private int expires_in;
+ private String refresh_token;
+ private String access_token;
+ public String id_token;
+ private String scope;
+
+
+ public String getToken_type() {
+ return token_type;
+ }
+
+ public void setToken_type(String token_type) {
+ this.token_type = token_type;
+ }
+
+ public int getExpires_in() {
+ return expires_in;
+ }
+
+ public void setExpires_in(int expires_in) {
+ this.expires_in = expires_in;
+ }
+
+ public String getRefresh_token() {
+ return refresh_token;
+ }
+
+ public void setRefresh_token(String refresh_token) {
+ this.refresh_token = refresh_token;
+ }
+
+ public String getAccess_token() {
+ return access_token;
+ }
+
+ public void setAccess_token(String access_token) {
+ this.access_token = access_token;
+ }
+
+ public String getId_token() {
+ return id_token;
+ }
+
+ public void setId_token(String id_token) {
+ this.id_token = id_token;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/SecurityManagerFactory.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/SecurityManagerFactory.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/SecurityManagerFactory.java
new file mode 100644
index 0000000..d4e05f0
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/SecurityManagerFactory.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.ServerSettings;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This initializes an instance of the appropriate security manager according to the
+ * configuration.
+ */
+public class SecurityManagerFactory {
+ private final static Logger logger = LoggerFactory.getLogger(SecurityManagerFactory.class);
+
+ public static AiravataSecurityManager getSecurityManager() throws AiravataSecurityException {
+ try {
+ Class secManagerImpl = Class.forName(ServerSettings.getSecurityManagerClassName());
+ AiravataSecurityManager securityManager = (AiravataSecurityManager) secManagerImpl.newInstance();
+ return securityManager;
+ } catch (ClassNotFoundException e) {
+ String error = "Security Manager class could not be found.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (ApplicationSettingsException e) {
+ String error = "Error in reading the configuration related to Security Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (InstantiationException e) {
+ String error = "Error in instantiating the Security Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (IllegalAccessException e) {
+ String error = "Error in instantiating the Security Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCache.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCache.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCache.java
new file mode 100644
index 0000000..a29efe6
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCache.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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.authzcache;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class AuthzCache extends LinkedHashMap<AuthzCacheIndex, AuthzCacheEntry> {
+
+ private static int MAX_SIZE;
+ private final static Logger logger = LoggerFactory.getLogger(AuthzCache.class);
+
+ private static AuthzCache authzCache = null;
+
+ public static AuthzCache getInstance() throws ApplicationSettingsException {
+ if (authzCache == null) {
+ synchronized (AuthzCache.class) {
+ if (authzCache == null) {
+ authzCache = new AuthzCache(ServerSettings.getCacheSize());
+ }
+ }
+ }
+ return authzCache;
+ }
+
+ private AuthzCache(int initialCapacity) {
+ super(initialCapacity);
+ MAX_SIZE = initialCapacity;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<AuthzCacheIndex, AuthzCacheEntry> eldest) {
+ if (size() > MAX_SIZE) {
+ logger.info("Authz cache max size exceeded. Removing the old entries.");
+ }
+ return size() > MAX_SIZE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheEntry.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheEntry.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheEntry.java
new file mode 100644
index 0000000..494126f
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheEntry.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.authzcache;
+
+/**
+ * Cache entry in the default authorization cache.
+ */
+public class AuthzCacheEntry {
+ //authorization decision for the authorization request associated with this cache entry.
+ private boolean decision;
+ //time to live value for the access token in seconds.
+ private long expiryTime;
+ //time stamp in milli seconds at the time this entry is put into the cache
+ private long entryTimestamp;
+
+ public AuthzCacheEntry(boolean decision, long expiryTime, long entryTimestamp) {
+ this.decision = decision;
+ this.expiryTime = expiryTime;
+ this.entryTimestamp = entryTimestamp;
+ }
+
+ public long getEntryTimestamp() {
+ return entryTimestamp;
+ }
+
+ public void setEntryTimestamp(long entryTimestamp) {
+ this.entryTimestamp = entryTimestamp;
+ }
+
+ public long getExpiryTime() {
+ return expiryTime;
+ }
+
+ public void setExpiryTime(long timestamp) {
+ this.expiryTime = timestamp;
+ }
+
+ public boolean getDecision() {
+ return decision;
+ }
+
+ public void setDecision(boolean decision) {
+ this.decision = decision;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheIndex.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheIndex.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheIndex.java
new file mode 100644
index 0000000..ddfecf2
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheIndex.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.authzcache;
+
+/**
+ * Cache index of the default authorization cache.
+ */
+public class AuthzCacheIndex {
+
+ private String subject;
+ private String oauthAccessToken;
+ private String action;
+ private String gatewayId;
+
+ public AuthzCacheIndex(String userName, String gatewayId, String accessToken, String actionString) {
+ this.subject = userName;
+ this.oauthAccessToken = accessToken;
+ this.action = actionString;
+ this.gatewayId = gatewayId;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ public String getOauthAccessToken() {
+ return oauthAccessToken;
+ }
+
+ public void setOauthAccessToken(String oauthAccessToken) {
+ this.oauthAccessToken = oauthAccessToken;
+ }
+
+ public String getGatewayId() {
+ return gatewayId;
+ }
+
+ public void setGatewayId(String gatewayId) {
+ this.gatewayId = gatewayId;
+ }
+
+ /*Equals and hash code methods are overridden since this is being used as an index of a map and that containsKey method
+ * should return true if the values of two index objects are equal.*/
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || other.getClass() != getClass()) {
+ return false;
+ }
+ return ((this.getSubject().equals(((AuthzCacheIndex) other).getSubject()))
+ && (this.getGatewayId().equals(((AuthzCacheIndex) other).getGatewayId()))
+ && (this.getOauthAccessToken().equals(((AuthzCacheIndex) other).getOauthAccessToken()))
+ && (this.getAction().equals(((AuthzCacheIndex) other).getAction())));
+ }
+
+ @Override
+ public int hashCode() {
+ return this.getSubject().hashCode() + this.getOauthAccessToken().hashCode() + this.getGatewayId().hashCode()
+ + this.getAction().hashCode();
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManager.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManager.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManager.java
new file mode 100644
index 0000000..b9de26b
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManager.java
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.authzcache;
+
+import org.apache.airavata.security.AiravataSecurityException;
+
+/**
+ * This is the interface through which security manager accesses the underlying caching implementation
+ * See the DefaultAuthzCacheManager.java for an example implementation of this interface.
+ */
+public interface AuthzCacheManager {
+ /**
+ * Returns the status of the cache w.r.t the given authorization request which is encapsulated in
+ * the AuthzCacheIndex.
+ *
+ * @param authzCacheIndex
+ * @return
+ */
+ public AuthzCachedStatus getAuthzCachedStatus(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException;
+
+ /**
+ * Add to cache the authorization decision pertaining to a given authorization request.
+ *
+ * @param authzCacheIndex
+ * @param authzCacheEntry
+ * @throws AiravataSecurityException
+ */
+ public void addToAuthzCache(AuthzCacheIndex authzCacheIndex, AuthzCacheEntry authzCacheEntry) throws AiravataSecurityException;
+
+ /**
+ * Check if a valid decision is cached for a given authorization request.
+ *
+ * @param authzCacheIndex
+ * @return
+ */
+ public boolean isAuthzDecisionCached(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException;
+
+ /**
+ * Returns the AuthzCacheEntry for a given authorization request.
+ *
+ * @param authzCacheIndex
+ * @return
+ * @throws AiravataSecurityException
+ */
+ public AuthzCacheEntry getAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException;
+
+ /**
+ * Removes the authorization cache entry for a given authorization request.
+ *
+ * @param authzCacheIndex
+ * @throws AiravataSecurityException
+ */
+ public void removeAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException;
+
+ /**
+ * Clear the authorization cache.
+ *
+ * @return
+ */
+ public void clearCache() throws AiravataSecurityException;
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManagerFactory.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManagerFactory.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManagerFactory.java
new file mode 100644
index 0000000..f5afabf
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCacheManagerFactory.java
@@ -0,0 +1,60 @@
+/*
+ *
+ * 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.authzcache;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.utils.ServerSettings;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This initializes the AuthzCacheManager implementation to be used as defined by the configuration.
+ */
+public class AuthzCacheManagerFactory {
+ private final static Logger logger = LoggerFactory.getLogger(AuthzCacheManagerFactory.class);
+
+ public static AuthzCacheManager getAuthzCacheManager() throws AiravataSecurityException {
+ try {
+ Class authzCacheManagerImpl = Class.forName(ServerSettings.getAuthzCacheManagerClassName());
+ AuthzCacheManager authzCacheManager = (AuthzCacheManager) authzCacheManagerImpl.newInstance();
+ return authzCacheManager;
+ } catch (ClassNotFoundException e) {
+ String error = "Authorization Cache Manager class could not be found.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (ApplicationSettingsException e) {
+ String error = "Error in reading the configuration related to Authorization Cache Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (InstantiationException e) {
+ String error = "Error in instantiating the Authorization Cache Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+ } catch (IllegalAccessException e) {
+ String error = "Error in instantiating the Authorization Cache Manager class.";
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException(error);
+
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCachedStatus.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCachedStatus.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCachedStatus.java
new file mode 100644
index 0000000..4472067
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/AuthzCachedStatus.java
@@ -0,0 +1,34 @@
+/*
+ *
+ * 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.authzcache;
+
+/**
+ * This enum defines the status of the authorization cache returned by the authorization cache manager
+ * when an authorization status is checked against an authorization request.
+ */
+public enum AuthzCachedStatus {
+ /*Authorization decision is cached for the given authrization request and the decision authorizes the request.*/
+ AUTHORIZED,
+ /*Authorization decision is cached for the given authorization request and the decision denies authorization.*/
+ NOT_AUTHORIZED,
+ /*Authorization decision is not either cached or the cached entry is invalid such that re-authorization is needed.*/
+ NOT_CACHED
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/DefaultAuthzCacheManager.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/DefaultAuthzCacheManager.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/DefaultAuthzCacheManager.java
new file mode 100644
index 0000000..50a0f39
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/authzcache/DefaultAuthzCacheManager.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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.authzcache;
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultAuthzCacheManager implements AuthzCacheManager {
+
+ private final static Logger logger = LoggerFactory.getLogger(DefaultAuthzCacheManager.class);
+
+ @Override
+ public AuthzCachedStatus getAuthzCachedStatus(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException {
+ if (isAuthzDecisionCached(authzCacheIndex)) {
+ AuthzCacheEntry cacheEntry = getAuthzCacheEntry(authzCacheIndex);
+ long expiryTime = cacheEntry.getExpiryTime();
+ long currentTime = System.currentTimeMillis();
+ long timePassed = (currentTime - cacheEntry.getEntryTimestamp()) / 1000;
+ if (expiryTime > timePassed) {
+ //access token is still valid. Hence, return the cached decision
+ if (cacheEntry.getDecision()) {
+ return AuthzCachedStatus.AUTHORIZED;
+ } else {
+ return AuthzCachedStatus.NOT_AUTHORIZED;
+ }
+ } else {
+ //access token has been expired. Hence, remove the entry and return.
+ removeAuthzCacheEntry(authzCacheIndex);
+ return AuthzCachedStatus.NOT_CACHED;
+ }
+ } else {
+ return AuthzCachedStatus.NOT_CACHED;
+ }
+ }
+
+ @Override
+ public void addToAuthzCache(AuthzCacheIndex authzCacheIndex, AuthzCacheEntry authzCacheEntry) throws AiravataSecurityException {
+ try {
+ AuthzCache.getInstance().put(authzCacheIndex, authzCacheEntry);
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in obtaining the authorization cache instance.");
+ }
+ }
+
+ @Override
+ public boolean isAuthzDecisionCached(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException {
+ try {
+ return AuthzCache.getInstance().containsKey(authzCacheIndex);
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in obtaining the authorization cache instance.");
+ }
+ }
+
+ @Override
+ public AuthzCacheEntry getAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException {
+ try {
+ return AuthzCache.getInstance().get(authzCacheIndex);
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in obtaining the authorization cache instance.");
+ }
+ }
+
+ @Override
+ public void removeAuthzCacheEntry(AuthzCacheIndex authzCacheIndex) throws AiravataSecurityException {
+ try {
+ AuthzCache.getInstance().remove(authzCacheIndex);
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in obtaining the authorization cache instance.");
+ }
+ }
+
+ @Override
+ public void clearCache() throws AiravataSecurityException {
+ try {
+ AuthzCache.getInstance().clear();
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AiravataSecurityException("Error in obtaining the authorization cache instance.");
+
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityCheck.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityCheck.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityCheck.java
new file mode 100644
index 0000000..b4abb6a
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityCheck.java
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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.interceptor;
+
+import com.google.inject.BindingAnnotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This is just the definition of the annotation used to mark the API methods to be intercepted.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+@BindingAnnotation
+public @interface SecurityCheck {
+}
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityInterceptor.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityInterceptor.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityInterceptor.java
new file mode 100644
index 0000000..ad7efa0
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityInterceptor.java
@@ -0,0 +1,83 @@
+/*
+ *
+ * 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.interceptor;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+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.model.error.AuthorizationException;
+import org.apache.airavata.model.security.AuthzToken;
+import org.apache.airavata.security.AiravataSecurityException;
+import org.apache.airavata.service.security.AiravataSecurityManager;
+import org.apache.airavata.service.security.IdentityContext;
+import org.apache.airavata.service.security.SecurityManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Interceptor of Airavata API calls for the purpose of applying security.
+ */
+public class SecurityInterceptor implements MethodInterceptor {
+ private final static Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class);
+
+ @Override
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ //obtain the authz token from the input parameters
+ AuthzToken authzToken = (AuthzToken) invocation.getArguments()[0];
+ //authorize the API call
+ HashMap<String, String> metaDataMap = new HashMap();
+ metaDataMap.put(Constants.API_METHOD_NAME, invocation.getMethod().getName());
+ authorize(authzToken, metaDataMap);
+ //set the user identity info in a thread local to be used in downstream execution.
+ IdentityContext.set(authzToken);
+ //let the method call procees upon successful authorization
+ Object returnObj = invocation.proceed();
+ //clean the identity context before the method call returns
+ IdentityContext.unset();
+ return returnObj;
+ }
+
+ private void authorize(AuthzToken authzToken, Map<String, String> metaData) throws AuthorizationException {
+ try {
+ boolean isAPISecured = ServerSettings.isAPISecured();
+ if (isAPISecured) {
+ AiravataSecurityManager securityManager = SecurityManagerFactory.getSecurityManager();
+ boolean isAuthz = securityManager.isUserAuthorized(authzToken, metaData);
+ if (!isAuthz) {
+ throw new AuthorizationException("User is not authenticated or authorized.");
+ }
+ }
+ } catch (AiravataSecurityException e) {
+ logger.error(e.getMessage(), e);
+ throw new AuthorizationException("Error in authenticating or authorizing user.");
+ } catch (ApplicationSettingsException e) {
+ logger.error(e.getMessage(), e);
+ throw new AuthorizationException("Internal error in authenticating or authorizing user.");
+ }
+ }
+}
+
+
http://git-wip-us.apache.org/repos/asf/airavata/blob/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityModule.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityModule.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityModule.java
new file mode 100644
index 0000000..7ec56b9
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/interceptor/SecurityModule.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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.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/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/oauth/DefaultOAuthClient.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/oauth/DefaultOAuthClient.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/oauth/DefaultOAuthClient.java
new file mode 100644
index 0000000..9f47dbd
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/oauth/DefaultOAuthClient.java
@@ -0,0 +1,91 @@
+/*
+ *
+ * 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.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/6e5530c1/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/xacml/DefaultPAPClient.java
----------------------------------------------------------------------
diff --git a/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/xacml/DefaultPAPClient.java b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/xacml/DefaultPAPClient.java
new file mode 100644
index 0000000..ecfd32b
--- /dev/null
+++ b/airavata-services/services-security/src/main/java/org/apache/airavata/service/security/xacml/DefaultPAPClient.java
@@ -0,0 +1,125 @@
+/*
+ *
+ * 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.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.common.EntitlementConstants;
+import org.wso2.carbon.identity.entitlement.stub.EntitlementPolicyAdminServiceEntitlementException;
+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.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();
+ }
+}