This is an automated email from the ASF dual-hosted git repository. machristie pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/airavata.git
commit d19a697baaebecb7d8298f8fcb25751644846a49 Author: Marcus Christie <[email protected]> AuthorDate: Mon Jan 4 11:57:49 2021 -0500 AIRAVATA-3397 Make client trust store optional Client trust store is needed to secure connections to services with self-signed certs. Client trust store isn't needed when not using self-signed certs, for example Letsencrypt certs. --- .../core/impl/TenantManagementKeycloakImpl.java | 28 ++++++++++++++-------- .../service/security/KeyCloakSecurityManager.java | 15 +++++++----- .../security/KeyCloakSecurityManagerTest.java | 1 + .../scigap/develop/group_vars/all/vars.yml | 6 ++--- .../scigap/production/group_vars/all/vars.yml | 6 ++--- .../scigap/staging/group_vars/all/vars.yml | 6 ++--- .../templates/airavata-server.properties.j2 | 4 +++- dev-tools/ansible/roles/common/defaults/main.yml | 1 - dev-tools/ansible/roles/common/tasks/main.yml | 1 + .../airavata/common/utils/ApplicationSettings.java | 4 ++++ .../src/main/resources/airavata-server.properties | 4 ++-- .../registry/server/SharingRegistryServer.java | 4 +++- 12 files changed, 50 insertions(+), 30 deletions(-) diff --git a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java index e93d6c0..7baa89d 100644 --- a/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java +++ b/airavata-services/profile-service/iam-admin-services-core/src/main/java/org/apache/airavata/service/profile/iam/admin/services/core/impl/TenantManagementKeycloakImpl.java @@ -62,10 +62,7 @@ public class TenantManagementKeycloakImpl implements TenantManagementInterface { private static Keycloak getClient(String adminUrl, String realm, PasswordCredential AdminPasswordCreds) { - ResteasyClient resteasyClient = new ResteasyClientBuilder() - .connectionPoolSize(10) - .trustStore(loadKeyStore()) - .build(); + ResteasyClient resteasyClient = getResteasyClient(); return KeycloakBuilder.builder() .serverUrl(adminUrl) .realm(realm) @@ -78,10 +75,7 @@ public class TenantManagementKeycloakImpl implements TenantManagementInterface { private static Keycloak getClient(String adminUrl, String realm, String accessToken) { - ResteasyClient resteasyClient = new ResteasyClientBuilder() - .connectionPoolSize(10) - .trustStore(loadKeyStore()) - .build(); + ResteasyClient resteasyClient = getResteasyClient(); return KeycloakBuilder.builder() .serverUrl(adminUrl) .realm(realm) @@ -90,6 +84,19 @@ public class TenantManagementKeycloakImpl implements TenantManagementInterface { .build(); } + private static ResteasyClient getResteasyClient() { + + ResteasyClientBuilder builder = new ResteasyClientBuilder().connectionPoolSize(10); + try { + if (ServerSettings.isTrustStorePathDefined()) { + builder.trustStore(loadKeyStore()); + } + } catch (ApplicationSettingsException e) { + throw new RuntimeException("Failed to read application settings", e); + } + return builder.build(); + } + private static KeyStore loadKeyStore() { InputStream is = null; @@ -833,8 +840,9 @@ public class TenantManagementKeycloakImpl implements TenantManagementInterface { public static void main(String[] args) throws IamAdminServicesException, ApplicationSettingsException { TenantManagementKeycloakImpl tenantManagementKeycloak = new TenantManagementKeycloakImpl(); - ServerSettings.setSetting("trust.store", "./modules/configuration/server/src/main/resources/client_truststore.jks"); - ServerSettings.setSetting("trust.store.password", "airavata"); + // If testing with self-signed certificate, load certificate into modules/configuration/server/src/main/resources/client_truststore.jks and uncomment the following + // ServerSettings.setSetting("trust.store", "./modules/configuration/server/src/main/resources/client_truststore.jks"); + // ServerSettings.setSetting("trust.store.password", "airavata"); ServerSettings.setSetting("iam.server.url", ""); String accessToken = ""; String tenantId = ""; 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 index c8f3d71..607a2ee 100644 --- 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 @@ -203,10 +203,12 @@ public class KeyCloakSecurityManager implements AiravataSecurityManager { @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()); + //initialize SSL context with the trust store (if defined) that contains the public cert of WSO2 Identity Server. + if (ServerSettings.isTrustStorePathDefined()) { + TrustStoreManager trustStoreManager = new TrustStoreManager(); + trustStoreManager.initializeTrustStoreManager(ServerSettings.getTrustStorePath(), + ServerSettings.getTrustStorePassword()); + } } catch (Exception e) { throw new AiravataSecurityException(e.getMessage(), e); } @@ -540,8 +542,9 @@ public class KeyCloakSecurityManager implements AiravataSecurityManager { } public static void main(String[] args) throws AiravataSecurityException, ApplicationSettingsException { - ServerSettings.setSetting("trust.store", "./modules/configuration/server/src/main/resources/client_truststore.jks"); - ServerSettings.setSetting("trust.store.password", "airavata"); + // If testing with self-signed certificate, load certificate into modules/configuration/server/src/main/resources/client_truststore.jks and uncomment the following + // ServerSettings.setSetting("trust.store", "./modules/configuration/server/src/main/resources/client_truststore.jks"); + // ServerSettings.setSetting("trust.store.password", "airavata"); KeyCloakSecurityManager keyCloakSecurityManager = new KeyCloakSecurityManager(); final String tokenURL = "..."; final String clientId = "..."; diff --git a/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java b/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java index aa29b75..ee04534 100644 --- a/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java +++ b/airavata-services/services-security/src/test/java/org/apache/airavata/service/security/KeyCloakSecurityManagerTest.java @@ -77,6 +77,7 @@ public class KeyCloakSecurityManagerTest { @Before public void setUp() throws AiravataSecurityException, ApplicationSettingsException { new Expectations() {{ + mockServerSettings.isTrustStorePathDefined(); result = true; mockTrustStoreManager.initializeTrustStoreManager(anyString, anyString); mockServerSettings.isAPISecured(); result = true; mockServerSettings.getRegistryServerHost(); result = "localhost"; minTimes = 0; diff --git a/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml b/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml index 723214b..93f32ed 100644 --- a/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml +++ b/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml @@ -96,8 +96,8 @@ default_gateway: "default" # Credential and keystore related variables keystore_src_path: "{{inventory_dir}}/files/airavata.jks" keystore_passwd: "{{ vault_keystore_passwd }}" -client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" -client_truststore_passwd: "{{ vault_client_truststore_passwd }}" +# client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" +# client_truststore_passwd: "{{ vault_client_truststore_passwd }}" cred_keystore_src_path: "{{inventory_dir}}/files/airavata_sym.jks" cred_keystore_passwd: "{{ vault_cred_keystore_passwd }}" cred_keystore_alias: "airavata" @@ -225,4 +225,4 @@ credential_store_subnets: "{{ iu_subnets }}" rabbitmq_subnets: "{{ iu_subnets }}" db_subnets: "{{ iu_subnets }}" zabbix_subnets: "{{ iu_subnets }}" -monitoring_subnets: "{{ iu_subnets }}" \ No newline at end of file +monitoring_subnets: "{{ iu_subnets }}" diff --git a/dev-tools/ansible/inventories/scigap/production/group_vars/all/vars.yml b/dev-tools/ansible/inventories/scigap/production/group_vars/all/vars.yml index b69937d..c2617ad 100644 --- a/dev-tools/ansible/inventories/scigap/production/group_vars/all/vars.yml +++ b/dev-tools/ansible/inventories/scigap/production/group_vars/all/vars.yml @@ -92,8 +92,8 @@ default_gateway: "default" # Credential and keystore related variables keystore_src_path: "{{inventory_dir}}/files/airavata.jks" keystore_passwd: "{{ vault_keystore_passwd }}" -client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" -client_truststore_passwd: "{{ vault_client_truststore_passwd }}" +# client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" +# client_truststore_passwd: "{{ vault_client_truststore_passwd }}" cred_keystore_src_path: "{{inventory_dir}}/files/airavata_sym.jks" cred_keystore_passwd: "{{ vault_cred_keystore_passwd }}" cred_keystore_alias: "airavata" @@ -228,4 +228,4 @@ credential_store_subnets: "{{ iu_subnets }}" rabbitmq_subnets: "{{ iu_subnets }}" db_subnets: "{{ iu_subnets }}" zabbix_subnets: "{{ iu_subnets }}" -monitoring_subnets: "{{ iu_subnets }}" \ No newline at end of file +monitoring_subnets: "{{ iu_subnets }}" diff --git a/dev-tools/ansible/inventories/scigap/staging/group_vars/all/vars.yml b/dev-tools/ansible/inventories/scigap/staging/group_vars/all/vars.yml index bf85be1..4fa00f2 100644 --- a/dev-tools/ansible/inventories/scigap/staging/group_vars/all/vars.yml +++ b/dev-tools/ansible/inventories/scigap/staging/group_vars/all/vars.yml @@ -91,8 +91,8 @@ default_gateway: "default" # Credential and keystore related variables keystore_src_path: "{{inventory_dir}}/files/airavata.jks" keystore_passwd: "{{ vault_keystore_passwd }}" -client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" -client_truststore_passwd: "{{ vault_client_truststore_passwd }}" +# client_truststore_src_path: "{{inventory_dir}}/files/client_truststore.jks" +# client_truststore_passwd: "{{ vault_client_truststore_passwd }}" cred_keystore_src_path: "{{inventory_dir}}/files/airavata_sym.jks" cred_keystore_passwd: "{{ vault_cred_keystore_passwd }}" cred_keystore_alias: "airavata" @@ -210,4 +210,4 @@ registry_subnets: "{{ iu_subnets }}" credential_store_subnets: "{{ iu_subnets }}" rabbitmq_subnets: "{{ iu_subnets }}" db_subnets: "{{ iu_subnets }}" -zabbix_subnets: "{{ iu_subnets }}" \ No newline at end of file +zabbix_subnets: "{{ iu_subnets }}" diff --git a/dev-tools/ansible/roles/api-orch/templates/airavata-server.properties.j2 b/dev-tools/ansible/roles/api-orch/templates/airavata-server.properties.j2 index b8da617..4f1af00 100644 --- a/dev-tools/ansible/roles/api-orch/templates/airavata-server.properties.j2 +++ b/dev-tools/ansible/roles/api-orch/templates/airavata-server.properties.j2 @@ -285,9 +285,11 @@ TLS.client.timeout=10000 #### keystore configuration #### keystore.path={{ keystores_location }}/{{ keystore_src_path | basename }} keystore.password={{ keystore_passwd }} +{% if client_truststore_src_path is defined %} #### trust store configuration #### trust.store={{ keystores_location }}/{{ client_truststore_src_path | basename }} trust.store.password={{ client_truststore_passwd }} +{% endif %} #### authorization cache related configuration #### authz.cache.enabled=true authz.cache.manager.class=org.apache.airavata.service.security.authzcache.DefaultAuthzCacheManager @@ -335,4 +337,4 @@ thrift.client.pool.abandoned.removal.logged={{ thrift_client_pool_abandoned_remo ########################################################################### api.server.monitoring.enabled={{ api_server_monitoring_enabled }} api.server.monitoring.host={{ api_server_monitoring_host }} -api.server.monitoring.port={{ api_server_monitoring_port }} \ No newline at end of file +api.server.monitoring.port={{ api_server_monitoring_port }} diff --git a/dev-tools/ansible/roles/common/defaults/main.yml b/dev-tools/ansible/roles/common/defaults/main.yml index 881faeb..3337d48 100644 --- a/dev-tools/ansible/roles/common/defaults/main.yml +++ b/dev-tools/ansible/roles/common/defaults/main.yml @@ -19,7 +19,6 @@ # keystore_src_path: "airavata.jks" -client_truststore_src_path: "airavata.jks" cred_keystore_src_path: "airavata_sym.jks" apache_maven_version: "apache-maven-3.6.3" diff --git a/dev-tools/ansible/roles/common/tasks/main.yml b/dev-tools/ansible/roles/common/tasks/main.yml index f72118d..e2c1a2c 100644 --- a/dev-tools/ansible/roles/common/tasks/main.yml +++ b/dev-tools/ansible/roles/common/tasks/main.yml @@ -92,3 +92,4 @@ copy: src={{ client_truststore_src_path }} dest="{{ keystores_location }}/{{ client_truststore_src_path | basename }}" owner={{ user }} group={{ group }} + when: client_truststore_src_path is defined diff --git a/modules/commons/src/main/java/org/apache/airavata/common/utils/ApplicationSettings.java b/modules/commons/src/main/java/org/apache/airavata/common/utils/ApplicationSettings.java index 5b78ba4..7d7133c 100644 --- a/modules/commons/src/main/java/org/apache/airavata/common/utils/ApplicationSettings.java +++ b/modules/commons/src/main/java/org/apache/airavata/common/utils/ApplicationSettings.java @@ -370,6 +370,10 @@ public class ApplicationSettings { return getInstance().properties.containsKey(key); } + public static boolean isTrustStorePathDefined() throws ApplicationSettingsException { + return ApplicationSettings.isSettingDefined(TRUST_STORE_PATH); + } + public static String getTrustStorePath() throws ApplicationSettingsException { return getSetting(TRUST_STORE_PATH); } diff --git a/modules/configuration/server/src/main/resources/airavata-server.properties b/modules/configuration/server/src/main/resources/airavata-server.properties index ec18c3f..7800d19 100644 --- a/modules/configuration/server/src/main/resources/airavata-server.properties +++ b/modules/configuration/server/src/main/resources/airavata-server.properties @@ -311,8 +311,8 @@ TLS.client.timeout=10000 keystore.path=airavata.jks keystore.password=airavata #### trust store configuration #### -trust.store=client_truststore.jks -trust.store.password=airavata +# trust.store=client_truststore.jks +# trust.store.password=airavata #### remote authorization server url #### remote.oauth.authorization.server=https://idp.scigap.org:9443/services/ #### xacml based authorization policy #### diff --git a/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/server/SharingRegistryServer.java b/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/server/SharingRegistryServer.java index e24196b..010e3b9 100644 --- a/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/server/SharingRegistryServer.java +++ b/modules/sharing-registry/sharing-registry-server/src/main/java/org/apache/airavata/sharing/registry/server/SharingRegistryServer.java @@ -89,7 +89,9 @@ public class SharingRegistryServer implements IServer { new TSSLTransportFactory.TSSLTransportParameters(); TLSParams.requireClientAuth(true); TLSParams.setKeyStore(ServerSettings.getKeyStorePath(), ServerSettings.getKeyStorePassword()); - TLSParams.setTrustStore(ServerSettings.getTrustStorePath(), ServerSettings.getTrustStorePassword()); + if (ServerSettings.isTrustStorePathDefined()) { + TLSParams.setTrustStore(ServerSettings.getTrustStorePath(), ServerSettings.getTrustStorePassword()); + } TServerSocket TLSServerTransport = TSSLTransportFactory.getServerSocket( serverPort, ServerSettings.getTLSClientTimeout(), InetAddress.getByName(serverHost), TLSParams);
