From 76a5d7fa4904119c7e69329e490ad8a09f61061a Mon Sep 17 00:00:00 2001 From: Stephen Crawford <65832608+scrawfor99@users.noreply.github.com> Date: Thu, 1 Jun 2023 10:03:13 -0400 Subject: [PATCH] Updates the style of all java files under the */dlic/util/ dir. (#2823) * rebase Signed-off-by: Stephen Crawford * Update java style under **/auth Signed-off-by: Stephen Crawford * Update Util dir Signed-off-by: Stephen Crawford * readd formatting Signed-off-by: Stephen Crawford --------- Signed-off-by: Stephen Crawford --- build.gradle | 54 +- .../SecurityBackwardsCompatibilityIT.java | 8 +- gradle/formatting.gradle | 129 ++- .../jwt/AbstractHTTPJwtAuthenticator.java | 24 +- .../auth/http/jwt/HTTPJwtAuthenticator.java | 113 ++- .../AuthenticatorUnavailableException.java | 33 +- .../keybyoidc/BadCredentialsException.java | 33 +- ...TTPJwtKeyByOpenIdConnectAuthenticator.java | 92 +- .../auth/http/jwt/keybyoidc/JwtVerifier.java | 177 ++-- .../auth/http/jwt/keybyoidc/KeyProvider.java | 5 +- .../http/jwt/keybyoidc/KeySetProvider.java | 2 +- .../http/jwt/keybyoidc/KeySetRetriever.java | 343 +++---- .../jwt/keybyoidc/SelfRefreshingKeySet.java | 587 ++++++------ .../json/OpenIdProviderConfiguration.java | 16 +- .../kerberos/HTTPSpnegoAuthenticator.java | 106 +- .../auth/http/kerberos/util/JaasKrbUtil.java | 344 +++---- .../auth/http/kerberos/util/KrbConstants.java | 45 +- .../http/saml/AuthTokenProcessorHandler.java | 96 +- .../auth/http/saml/HTTPSamlAuthenticator.java | 70 +- .../auth/http/saml/Saml2SettingsProvider.java | 81 +- .../http/saml/SamlHTTPMetadataResolver.java | 3 +- .../com/amazon/dlic/auth/ldap/LdapUser.java | 22 +- .../backend/LDAPAuthenticationBackend.java | 115 ++- .../backend/LDAPAuthorizationBackend.java | 364 ++++--- .../dlic/auth/ldap/util/ConfigConstants.java | 9 +- .../dlic/auth/ldap/util/LdapHelper.java | 28 +- .../com/amazon/dlic/auth/ldap/util/Utils.java | 12 +- .../ldap2/LDAPAuthenticationBackend2.java | 37 +- .../auth/ldap2/LDAPAuthorizationBackend2.java | 132 ++- .../ldap2/LDAPConnectionFactoryFactory.java | 74 +- .../dlic/auth/ldap2/LDAPUserSearcher.java | 63 +- .../util/SettingsBasedSSLConfigurator.java | 233 +++-- .../util/SettingsBasedSSLConfiguratorV4.java | 233 +++-- .../security/DefaultObjectMapper.java | 6 +- .../ConfigUpdateNodeResponse.java | 10 +- .../TransportConfigUpdateAction.java | 8 +- .../action/whoami/TransportWhoAmIAction.java | 6 +- .../action/whoami/WhoAmIRequestBuilder.java | 2 +- .../action/whoami/WhoAmIResponse.java | 8 +- .../security/auditlog/AuditLog.java | 2 +- .../security/auditlog/config/AuditConfig.java | 2 +- .../security/auth/AuthFailureListener.java | 6 +- .../security/auth/AuthenticationBackend.java | 14 +- .../security/auth/AuthorizationBackend.java | 4 +- .../security/auth/BackendRegistry.java | 12 +- .../security/auth/HTTPAuthenticator.java | 16 +- .../auth/blocking/ClientBlockRegistry.java | 6 +- .../HeapBasedClientBlockRegistry.java | 6 +- .../auth/limiting/AbstractRateLimiter.java | 6 +- .../limiting/AddressBasedRateLimiter.java | 6 +- .../limiting/UserNameBasedRateLimiter.java | 6 +- .../security/configuration/AdminDNs.java | 30 +- .../configuration/ClusterInfoHolder.java | 6 +- .../security/configuration/CompatConfig.java | 6 +- .../configuration/ConfigCallback.java | 2 +- ...onfigUpdateAlreadyInProgressException.java | 6 +- .../configuration/DlsFlsRequestValve.java | 4 +- .../configuration/DlsFlsValveImpl.java | 6 +- .../configuration/DlsQueryParser.java | 8 +- .../configuration/EmptyFilterLeafReader.java | 2 +- .../configuration/InvalidConfigException.java | 2 +- .../StaticResourceException.java | 6 +- .../security/filter/SecurityFilter.java | 22 +- .../security/filter/SecurityRestFilter.java | 12 +- .../security/http/HTTPBasicAuthenticator.java | 8 +- .../http/HTTPClientCertAuthenticator.java | 18 +- .../security/http/HTTPProxyAuthenticator.java | 6 +- .../security/http/RemoteIpDetector.java | 20 +- .../http/SecurityHttpServerTransport.java | 2 +- .../SecurityNonSslHttpServerTransport.java | 2 +- .../opensearch/security/http/XFFResolver.java | 14 +- .../proxy/HTTPExtendedProxyAuthenticator.java | 4 +- .../security/httpclient/HttpClient.java | 2 +- .../privileges/DocumentAllowList.java | 2 +- .../privileges/PrivilegesEvaluator.java | 10 +- .../PrivilegesEvaluatorResponse.java | 12 +- .../privileges/PrivilegesInterceptor.java | 4 +- .../SecurityIndexAccessEvaluator.java | 6 +- .../privileges/SnapshotRestoreEvaluator.java | 18 +- .../privileges/TermsAggregationEvaluator.java | 14 +- .../resolver/IndexResolverReplacer.java | 12 +- .../security/rest/DashboardsInfoAction.java | 8 +- .../security/rest/SecurityHealthAction.java | 14 +- .../security/rest/SecurityInfoAction.java | 14 +- .../security/rest/TenantInfoAction.java | 24 +- .../security/securityconf/ConfigModelV6.java | 72 +- .../security/securityconf/ConfigModelV7.java | 80 +- .../securityconf/DynamicConfigFactory.java | 44 +- .../securityconf/DynamicConfigModel.java | 18 +- .../securityconf/DynamicConfigModelV6.java | 58 +- .../securityconf/DynamicConfigModelV7.java | 54 +- .../securityconf/EvaluatedDlsFlsConfig.java | 4 +- .../security/securityconf/Hideable.java | 2 +- .../security/securityconf/Initializable.java | 2 +- .../securityconf/InternalUsersModel.java | 2 +- .../security/securityconf/Migration.java | 48 +- .../securityconf/StaticDefinable.java | 2 +- .../security/securityconf/impl/Meta.java | 16 +- .../impl/SecurityDynamicConfiguration.java | 60 +- .../securityconf/impl/v6/ActionGroupsV6.java | 8 +- .../securityconf/impl/v6/ConfigV6.java | 64 +- .../securityconf/impl/v6/InternalUserV6.java | 14 +- .../securityconf/impl/v6/RoleMappingsV6.java | 2 +- .../security/securityconf/impl/v6/RoleV6.java | 10 +- .../securityconf/impl/v7/ActionGroupsV7.java | 18 +- .../securityconf/impl/v7/ConfigV7.java | 112 +-- .../securityconf/impl/v7/InternalUserV7.java | 16 +- .../securityconf/impl/v7/RoleMappingsV7.java | 2 +- .../security/securityconf/impl/v7/RoleV7.java | 54 +- .../securityconf/impl/v7/TenantV7.java | 10 +- .../ssl/ExternalSecurityKeyStore.java | 30 +- .../ssl/OpenSearchSecuritySSLPlugin.java | 76 +- .../security/ssl/SecurityKeyStore.java | 8 +- .../security/ssl/SslExceptionHandler.java | 12 +- .../SecuritySSLNettyHttpServerTransport.java | 12 +- .../ssl/http/netty/ValidatingDispatcher.java | 14 +- .../ssl/rest/SecuritySSLInfoAction.java | 14 +- .../transport/DefaultPrincipalExtractor.java | 16 +- .../ssl/transport/PrincipalExtractor.java | 14 +- .../transport/SecuritySSLNettyTransport.java | 22 +- .../transport/SecuritySSLRequestHandler.java | 34 +- .../SecuritySSLTransportInterceptor.java | 12 +- .../ssl/util/CertificateValidator.java | 68 +- .../security/ssl/util/ExceptionUtils.java | 20 +- .../ssl/util/SSLCertificateHelper.java | 34 +- .../security/ssl/util/SSLConfigConstants.java | 52 +- .../security/ssl/util/SSLRequestHelper.java | 50 +- .../opensearch/security/ssl/util/Utils.java | 12 +- .../security/support/ConfigConstants.java | 24 +- .../security/support/HTTPHelper.java | 14 +- .../security/support/HeaderHelper.java | 6 +- .../opensearch/security/support/MapUtils.java | 6 +- .../security/support/ModuleInfo.java | 18 +- .../security/support/PemKeyReader.java | 86 +- .../support/ReflectiveAttributeAccessors.java | 4 +- .../security/support/SecurityJsonNode.java | 30 +- .../security/support/SecurityUtils.java | 20 +- .../support/SnapshotRestoreHelper.java | 18 +- .../security/support/SourceFieldsContext.java | 2 +- .../security/support/WildcardMatcher.java | 2 +- .../org/opensearch/security/tools/Hasher.java | 4 +- .../opensearch/security/tools/Migrater.java | 32 +- .../security/tools/SecurityAdmin.java | 202 ++-- .../DefaultInterClusterRequestEvaluator.java | 10 +- .../InterClusterRequestEvaluator.java | 8 +- .../transport/SecurityInterceptor.java | 8 +- .../transport/SecurityRequestHandler.java | 2 +- .../security/user/CustomAttributesAware.java | 2 +- .../org/opensearch/security/user/User.java | 34 +- .../ratetracking/HeapBasedRateTracker.java | 8 +- .../util/ratetracking/RateTracker.java | 6 +- .../ratetracking/SingleTryRateTracker.java | 6 +- .../http/jwt/HTTPJwtAuthenticatorTest.java | 149 +-- .../auth/http/jwt/keybyoidc/CxfTestTools.java | 6 +- ...wtKeyByOpenIdConnectAuthenticatorTest.java | 699 +++++++------- .../jwt/keybyoidc/KeySetRetrieverTest.java | 32 +- .../http/jwt/keybyoidc/MockIpdServer.java | 250 ++--- .../keybyoidc/SelfRefreshingKeySetTest.java | 135 ++- ...wtKeyByOpenIdConnectAuthenticatorTest.java | 361 ++++--- .../dlic/auth/http/jwt/keybyoidc/TestJwk.java | 152 +-- .../auth/http/jwt/keybyoidc/TestJwts.java | 157 +-- .../http/saml/HTTPSamlAuthenticatorTest.java | 471 +++++---- .../auth/http/saml/MockSamlIdpServer.java | 188 ++-- .../dlic/auth/ldap/LdapBackendIntegTest.java | 15 +- .../dlic/auth/ldap/LdapBackendTest.java | 904 +++++++++--------- .../auth/ldap/LdapBackendTestClientCert.java | 303 +++--- .../ldap/LdapBackendTestNewStyleConfig.java | 714 ++++++++------ .../com/amazon/dlic/auth/ldap/UtilsTest.java | 37 +- .../auth/ldap/srv/EmbeddedLDAPServer.java | 1 - .../amazon/dlic/auth/ldap/srv/LdapServer.java | 37 +- .../auth/ldap2/LdapBackendIntegTest2.java | 15 +- .../ldap2/LdapBackendTestClientCert2.java | 303 +++--- .../ldap2/LdapBackendTestNewStyleConfig2.java | 873 ++++++++++------- .../ldap2/LdapBackendTestOldStyleConfig2.java | 878 +++++++++-------- .../org/opensearch/node/PluginAwareNode.java | 4 +- .../opensearch/security/AggregationTests.java | 24 +- ...waysFalseInterClusterRequestEvaluator.java | 4 +- .../org/opensearch/security/ConfigTests.java | 40 +- .../org/opensearch/security/HealthTests.java | 12 +- .../security/HttpIntegrationTests.java | 220 ++--- .../security/IndexIntegrationTests.java | 236 ++--- .../InitializationIntegrationTests.java | 38 +- .../opensearch/security/IntegrationTests.java | 140 +-- .../opensearch/security/ResolveAPITests.java | 2 +- .../security/RolesInjectorIntegTest.java | 2 +- .../security/RolesValidationIntegTest.java | 2 +- .../security/SecurityAdminTests.java | 152 +-- .../security/SlowIntegrationTests.java | 40 +- .../security/SystemIntegratorsTests.java | 80 +- .../org/opensearch/security/TaskTests.java | 10 +- .../org/opensearch/security/UtilTests.java | 20 +- .../compliance/ComplianceAuditlogTest.java | 2 +- .../integration/BasicAuditlogTest.java | 4 +- .../HeapBasedClientBlockRegistryTest.java | 22 +- .../limiting/AddressBasedRateLimiterTest.java | 6 +- .../limiting/HeapBasedRateTrackerTest.java | 64 +- .../UserNameBasedRateLimiterTest.java | 6 +- .../ccstest/CrossClusterSearchTests.java | 8 +- .../security/ccstest/RemoteReindexTests.java | 36 +- .../dlic/dlsfls/AbstractDlsFlsTest.java | 12 +- .../dlic/dlsfls/CCReplicationTest.java | 2 +- .../security/dlic/dlsfls/DlsDateMathTest.java | 10 +- .../dlic/dlsfls/DlsTermLookupQueryTest.java | 4 +- .../dlic/dlsfls/FlsIndexingTests.java | 4 +- .../dlic/rest/api/AccountApiTest.java | 4 +- .../dlic/rest/api/ActionGroupsApiTest.java | 2 +- .../dlic/rest/api/AuditApiActionTest.java | 2 +- .../rest/api/DashboardsInfoActionTest.java | 2 +- .../dlic/rest/api/FlushCacheApiTest.java | 2 +- .../rest/api/GetConfigurationApiTest.java | 2 +- .../dlic/rest/api/IndexMissingTest.java | 2 +- .../dlic/rest/api/NodesDnApiTest.java | 2 +- .../dlic/rest/api/RoleBasedAccessTest.java | 2 +- .../dlic/rest/api/RolesMappingApiTest.java | 2 +- .../dlic/rest/api/SecurityApiAccessTest.java | 2 +- .../dlic/rest/api/SecurityConfigApiTest.java | 4 +- .../rest/api/SecurityHealthActionTest.java | 2 +- .../dlic/rest/api/SecurityInfoActionTest.java | 2 +- .../dlic/rest/api/TenantInfoActionTest.java | 4 +- .../dlic/rest/api/WhitelistApiTest.java | 2 +- .../security/filter/SecurityFilterTest.java | 2 +- .../HTTPExtendedProxyAuthenticatorTest.java | 24 +- .../test/TenancyMultitenancyEnabledTests.java | 4 +- .../SecurityIndexAccessEvaluatorTest.java | 6 +- .../impl/v7/IndexPatternTests.java | 10 +- .../setting/DeprecatedSettingsTest.java | 2 +- .../ssl/CertificateValidatorTest.java | 50 +- .../opensearch/security/ssl/OpenSSLTest.java | 24 +- .../security/ssl/TestPrincipalExtractor.java | 14 +- .../test/AbstractSecurityUnitTest.java | 4 +- .../helper/cluster/ClusterConfiguration.java | 28 +- .../test/helper/cluster/ClusterHelper.java | 4 +- .../security/test/helper/file/FileHelper.java | 12 +- .../security/test/helper/rest/RestHelper.java | 36 +- .../helper/rules/SecurityTestWatcher.java | 2 +- .../test/plugin/UserInjectorPlugin.java | 16 +- 236 files changed, 7670 insertions(+), 6451 deletions(-) diff --git a/build.gradle b/build.gradle index bd2eba30ba..94f62ab567 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ */ +import com.diffplug.gradle.spotless.JavaExtension import org.opensearch.gradle.test.RestIntegTestTask buildscript { @@ -51,7 +52,7 @@ plugins { id 'idea' id 'jacoco' id 'maven-publish' - id 'com.diffplug.spotless' version '6.18.0' + id 'com.diffplug.spotless' version '6.19.0' id 'checkstyle' id 'com.netflix.nebula.ospackage' version "11.1.0" id "org.gradle.test-retry" version "1.5.2" @@ -69,7 +70,56 @@ apply plugin: 'opensearch.opensearchplugin' apply plugin: 'opensearch.pluginzip' apply plugin: 'opensearch.rest-test' apply plugin: 'opensearch.testclusters' -apply from: 'gradle/formatting.gradle' +//apply from: 'gradle/formatting.gradle' + +spotless { + java { + // Normally this isn't necessary, but we have Java sources in + // non-standard places + target '**/com/amazon/dlic/**/*.java' + + removeUnusedImports() + eclipse().configFile rootProject.file('formatter/formatterConfig.xml') + trimTrailingWhitespace() + endWithNewline(); + + // note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports + importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') + + custom 'Refuse wildcard imports', { + // Wildcard imports can't be resolved; fail the build + if (it =~ /\s+import .*\*;/) { + throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") + } + } + + // See DEVELOPER_GUIDE.md for details of when to enable this. + if (System.getProperty('spotless.paddedcell') != null) { + paddedCell() + } + } + format 'misc', { + target '*.md', '*.gradle', '**/*.json', '**/*.yaml', '**/*.yml', '**/*.svg' + + trimTrailingWhitespace() + endWithNewline() + } + format('javaFoo', JavaExtension) { + + importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') + target '**/*.java' + targetExclude '**/com/amazon/dlic/**/*.java' + targetExclude('src/integrationTest/**') + + trimTrailingWhitespace() + endWithNewline(); + } + format("integrationTest", JavaExtension) { + target('src/integrationTest/java/**/*.java') + importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') + indentWithTabs(4) + } +} licenseFile = rootProject.file('LICENSE.txt') noticeFile = rootProject.file('NOTICE.txt') diff --git a/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java b/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java index 1afc1b88d5..d3c3658245 100644 --- a/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java +++ b/bwc-test/src/test/java/SecurityBackwardsCompatibilityIT.java @@ -12,17 +12,17 @@ import java.util.Set; import java.util.stream.Collectors; -import org.junit.Assume; +import com.google.common.collect.ImmutableMap; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; + +import org.opensearch.Version; import org.opensearch.client.Response; import org.opensearch.common.settings.Settings; import org.opensearch.rest.RestStatus; import org.opensearch.test.rest.OpenSearchRestTestCase; -import org.opensearch.Version; -import com.google.common.collect.ImmutableMap; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; diff --git a/gradle/formatting.gradle b/gradle/formatting.gradle index 1851438039..40ae51afb1 100644 --- a/gradle/formatting.gradle +++ b/gradle/formatting.gradle @@ -1,36 +1,95 @@ -allprojects { - project.apply plugin: "com.diffplug.spotless" - spotless { - java { - // Normally this isn't necessary, but we have Java sources in - // non-standard places - target '*/com/amazon/dlic/auth/**/*.java' - - removeUnusedImports() - eclipse().configFile rootProject.file('formatter/formatterConfig.xml') - trimTrailingWhitespace() - endWithNewline(); - - // note: you can use an empty string for all the imports you didn't specify explicitly, and '\\#` prefix for static imports - importOrder('java', 'javax', '', 'com.amazon', 'org.opensearch', '\\#') - - custom 'Refuse wildcard imports', { - // Wildcard imports can't be resolved; fail the build - if (it =~ /\s+import .*\*;/) { - throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") - } - } - - // See DEVELOPER_GUIDE.md for details of when to enable this. - if (System.getProperty('spotless.paddedcell') != null) { - paddedCell() - } - } - format 'misc', { - target '*.md', '*.gradle', '**/*.json', '**/*.yaml', '**/*.yml', '**/*.svg' - - trimTrailingWhitespace() - endWithNewline() - } - } +/* +* SPDX-License-Identifier: Apache-2.0 +* +* The OpenSearch Contributors require contributions made to +* this file be licensed under the Apache-2.0 license or a +* compatible open source license. +* +* Modifications Copyright OpenSearch Contributors. See +* GitHub history for details. +*/ + +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch 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. + */ + +import org.opensearch.gradle.BuildPlugin + +/* + * This script plugin configures formatting for Java source using Spotless + * for Gradle. Since the act of formatting existing source can interfere + * with developers' workflows, we don't automatically format all code + * (yet). Instead, we maintain a list of projects that are excluded from + * formatting, until we reach a point where we can comfortably format them + * in one go without too much disruption. + * + * Any new sub-projects must not be added to the exclusions list! + * + * To perform a reformat, run: + * + * ./gradlew spotlessApply + * + * To check the current format, run: + * + * ./gradlew spotlessJavaCheck + * + * This is also carried out by the `precommit` task. + * + * For more about Spotless, see: + * + * https://github.com/diffplug/spotless/tree/master/plugin-gradle + */ + +org.opensearch.gradle.BuildPlugin { + plugins.withType(BuildPlugin).whenPluginAdded { + project.apply plugin: "com.diffplug.spotless" + + spotless { + java { + // Normally this isn't necessary, but we have Java sources in + // non-standard places + target '**/*.java' + + removeUnusedImports() + eclipse().configFile rootProject.file('buildSrc/formatterConfig.xml') + trimTrailingWhitespace() + endWithNewline() + + custom 'Refuse wildcard imports', { + // Wildcard imports can't be resolved; fail the build + if (it =~ /\s+import .*\*;/) { + throw new AssertionError("Do not use wildcard imports. 'spotlessApply' cannot resolve this issue.") + } + } + + // See DEVELOPER_GUIDE.md for details of when to enable this. + if (System.getProperty('spotless.paddedcell') != null) { + paddedCell() + } + } + format 'misc', { + target '*.md', '*.gradle', '**/*.yaml', '**/*.yml', '**/*.svg' + + trimTrailingWhitespace() + endWithNewline() + } + } + + precommit.dependsOn 'spotlessJavaCheck' + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java index bef819effd..ffe9db81f2 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/AbstractHTTPJwtAuthenticator.java @@ -59,7 +59,7 @@ public abstract class AbstractHTTPJwtAuthenticator implements HTTPAuthenticator private final String requiredIssuer; public static final int DEFAULT_CLOCK_SKEW_TOLERANCE_SECONDS = 30; - private final int clockSkewToleranceSeconds ; + private final int clockSkewToleranceSeconds; public AbstractHTTPJwtAuthenticator(Settings settings, Path configPath) { jwtUrlParameter = settings.get("jwt_url_parameter"); @@ -83,8 +83,7 @@ public AbstractHTTPJwtAuthenticator(Settings settings, Path configPath) { @Override @SuppressWarnings("removal") - public AuthCredentials extractCredentials(RestRequest request, ThreadContext context) - throws OpenSearchSecurityException { + public AuthCredentials extractCredentials(RestRequest request, ThreadContext context) throws OpenSearchSecurityException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -186,8 +185,11 @@ public String extractSubject(JwtClaims claims) { // warning if (!(subjectObject instanceof String)) { log.warn( - "Expected type String for roles in the JWT for subject_key {}, but value was '{}' ({}). Will convert this value to String.", - subjectKey, subjectObject, subjectObject.getClass()); + "Expected type String for roles in the JWT for subject_key {}, but value was '{}' ({}). Will convert this value to String.", + subjectKey, + subjectObject, + subjectObject.getClass() + ); subject = String.valueOf(subjectObject); } else { subject = (String) subjectObject; @@ -207,8 +209,9 @@ public String[] extractRoles(JwtClaims claims) { if (rolesObject == null) { log.warn( - "Failed to get roles from JWT claims with roles_key '{}'. Check if this key is correct and available in the JWT payload.", - rolesKey); + "Failed to get roles from JWT claims with roles_key '{}'. Check if this key is correct and available in the JWT payload.", + rolesKey + ); return new String[0]; } @@ -218,8 +221,11 @@ public String[] extractRoles(JwtClaims claims) { // String but issue a warning if (!(rolesObject instanceof String) && !(rolesObject instanceof Collection)) { log.warn( - "Expected type String or Collection for roles in the JWT for roles_key {}, but value was '{}' ({}). Will convert this value to String.", - rolesKey, rolesObject, rolesObject.getClass()); + "Expected type String or Collection for roles in the JWT for roles_key {}, but value was '{}' ({}). Will convert this value to String.", + rolesKey, + rolesObject, + rolesObject.getClass() + ); } else if (rolesObject instanceof Collection) { roles = ((Collection) rolesObject).toArray(new String[0]); } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java index 16cc71ffbd..3468bb89af 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java @@ -68,7 +68,7 @@ public HTTPJwtAuthenticator(final Settings settings, final Path configPath) { try { String signingKey = settings.get("signing_key"); - if(signingKey == null || signingKey.length() == 0) { + if (signingKey == null || signingKey.length() == 0) { log.error("signingKey must not be null or empty. JWT authentication will not work"); } else { @@ -90,7 +90,7 @@ public HTTPJwtAuthenticator(final Settings settings, final Path configPath) { log.debug("No public ECDSA key, try other algos ({})", e.toString()); } - if(key != null) { + if (key != null) { _jwtParser = Jwts.parser().setSigningKey(key); } else { _jwtParser = Jwts.parser().setSigningKey(decoded); @@ -121,7 +121,6 @@ public HTTPJwtAuthenticator(final Settings settings, final Path configPath) { jwtParser = _jwtParser; } - @Override @SuppressWarnings("removal") public AuthCredentials extractCredentials(RestRequest request, ThreadContext context) throws OpenSearchSecurityException { @@ -152,25 +151,29 @@ private AuthCredentials extractCredentials0(final RestRequest request) { jwtToken = null; } - if((jwtToken == null || jwtToken.isEmpty()) && jwtUrlParameter != null) { + if ((jwtToken == null || jwtToken.isEmpty()) && jwtUrlParameter != null) { jwtToken = request.param(jwtUrlParameter); } else { - //just consume to avoid "contains unrecognized parameter" + // just consume to avoid "contains unrecognized parameter" request.param(jwtUrlParameter); } if (jwtToken == null || jwtToken.length() == 0) { - if(log.isDebugEnabled()) { - log.debug("No JWT token found in '{}' {} header", jwtUrlParameter==null?jwtHeaderName:jwtUrlParameter, jwtUrlParameter==null?"header":"url parameter"); + if (log.isDebugEnabled()) { + log.debug( + "No JWT token found in '{}' {} header", + jwtUrlParameter == null ? jwtHeaderName : jwtUrlParameter, + jwtUrlParameter == null ? "header" : "url parameter" + ); } return null; } final int index; - if((index = jwtToken.toLowerCase().indexOf(BEARER)) > -1) { //detect Bearer - jwtToken = jwtToken.substring(index+BEARER.length()); + if ((index = jwtToken.toLowerCase().indexOf(BEARER)) > -1) { // detect Bearer + jwtToken = jwtToken.substring(index + BEARER.length()); } else { - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debug("No Bearer scheme found in header"); } } @@ -181,16 +184,16 @@ private AuthCredentials extractCredentials0(final RestRequest request) { final String subject = extractSubject(claims, request); if (subject == null) { - log.error("No subject found in JWT token"); - return null; + log.error("No subject found in JWT token"); + return null; } final String[] roles = extractRoles(claims, request); final AuthCredentials ac = new AuthCredentials(subject, roles).markComplete(); - for(Entry claim: claims.entrySet()) { - ac.addAttribute("attr.jwt."+claim.getKey(), String.valueOf(claim.getValue())); + for (Entry claim : claims.entrySet()) { + ac.addAttribute("attr.jwt." + claim.getKey(), String.valueOf(claim.getValue())); } return ac; @@ -199,7 +202,7 @@ private AuthCredentials extractCredentials0(final RestRequest request) { log.error("Cannot authenticate user with JWT because of ", e); return null; } catch (Exception e) { - if(log.isDebugEnabled()) { + if (log.isDebugEnabled()) { log.debug("Invalid or expired JWT token.", e); } return null; @@ -208,7 +211,7 @@ private AuthCredentials extractCredentials0(final RestRequest request) { @Override public boolean reRequestAuthentication(final RestChannel channel, AuthCredentials creds) { - final BytesRestResponse wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED,""); + final BytesRestResponse wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED, ""); wwwAuthenticateResponse.addHeader("WWW-Authenticate", "Bearer realm=\"OpenSearch Security\""); channel.sendResponse(wwwAuthenticateResponse); return true; @@ -221,16 +224,21 @@ public String getType() { protected String extractSubject(final Claims claims, final RestRequest request) { String subject = claims.getSubject(); - if(subjectKey != null) { - // try to get roles from claims, first as Object to avoid having to catch the ExpectedTypeException + if (subjectKey != null) { + // try to get roles from claims, first as Object to avoid having to catch the ExpectedTypeException Object subjectObject = claims.get(subjectKey, Object.class); - if(subjectObject == null) { + if (subjectObject == null) { log.warn("Failed to get subject from JWT claims, check if subject_key '{}' is correct.", subjectKey); return null; } - // We expect a String. If we find something else, convert to String but issue a warning - if(!(subjectObject instanceof String)) { - log.warn("Expected type String for roles in the JWT for subject_key {}, but value was '{}' ({}). Will convert this value to String.", subjectKey, subjectObject, subjectObject.getClass()); + // We expect a String. If we find something else, convert to String but issue a warning + if (!(subjectObject instanceof String)) { + log.warn( + "Expected type String for roles in the JWT for subject_key {}, but value was '{}' ({}). Will convert this value to String.", + subjectKey, + subjectObject, + subjectObject.getClass() + ); } subject = String.valueOf(subjectObject); } @@ -239,34 +247,43 @@ protected String extractSubject(final Claims claims, final RestRequest request) @SuppressWarnings("unchecked") protected String[] extractRoles(final Claims claims, final RestRequest request) { - // no roles key specified - if(rolesKey == null) { - return new String[0]; - } - // try to get roles from claims, first as Object to avoid having to catch the ExpectedTypeException - final Object rolesObject = claims.get(rolesKey, Object.class); - if(rolesObject == null) { - log.warn("Failed to get roles from JWT claims with roles_key '{}'. Check if this key is correct and available in the JWT payload.", rolesKey); - return new String[0]; - } - - String[] roles = String.valueOf(rolesObject).split(","); - - // We expect a String or Collection. If we find something else, convert to String but issue a warning - if (!(rolesObject instanceof String) && !(rolesObject instanceof Collection)) { - log.warn("Expected type String or Collection for roles in the JWT for roles_key {}, but value was '{}' ({}). Will convert this value to String.", rolesKey, rolesObject, rolesObject.getClass()); - } else if (rolesObject instanceof Collection) { - roles = ((Collection) rolesObject).toArray(new String[0]); - } - - for (int i = 0; i < roles.length; i++) { - roles[i] = roles[i].trim(); - } - - return roles; + // no roles key specified + if (rolesKey == null) { + return new String[0]; + } + // try to get roles from claims, first as Object to avoid having to catch the ExpectedTypeException + final Object rolesObject = claims.get(rolesKey, Object.class); + if (rolesObject == null) { + log.warn( + "Failed to get roles from JWT claims with roles_key '{}'. Check if this key is correct and available in the JWT payload.", + rolesKey + ); + return new String[0]; + } + + String[] roles = String.valueOf(rolesObject).split(","); + + // We expect a String or Collection. If we find something else, convert to String but issue a warning + if (!(rolesObject instanceof String) && !(rolesObject instanceof Collection)) { + log.warn( + "Expected type String or Collection for roles in the JWT for roles_key {}, but value was '{}' ({}). Will convert this value to String.", + rolesKey, + rolesObject, + rolesObject.getClass() + ); + } else if (rolesObject instanceof Collection) { + roles = ((Collection) rolesObject).toArray(new String[0]); + } + + for (int i = 0; i < roles.length; i++) { + roles[i] = roles[i].trim(); + } + + return roles; } - private static PublicKey getPublicKey(final byte[] keyBytes, final String algo) throws NoSuchAlgorithmException, InvalidKeySpecException { + private static PublicKey getPublicKey(final byte[] keyBytes, final String algo) throws NoSuchAlgorithmException, + InvalidKeySpecException { X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory kf = KeyFactory.getInstance(algo); return kf.generatePublic(spec); diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/AuthenticatorUnavailableException.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/AuthenticatorUnavailableException.java index d9aa1aebb6..b17663b429 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/AuthenticatorUnavailableException.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/AuthenticatorUnavailableException.java @@ -12,27 +12,26 @@ package com.amazon.dlic.auth.http.jwt.keybyoidc; public class AuthenticatorUnavailableException extends RuntimeException { - private static final long serialVersionUID = -7007025852090301416L; + private static final long serialVersionUID = -7007025852090301416L; - public AuthenticatorUnavailableException() { - super(); - } + public AuthenticatorUnavailableException() { + super(); + } - public AuthenticatorUnavailableException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } + public AuthenticatorUnavailableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } - public AuthenticatorUnavailableException(String message, Throwable cause) { - super(message, cause); - } + public AuthenticatorUnavailableException(String message, Throwable cause) { + super(message, cause); + } - public AuthenticatorUnavailableException(String message) { - super(message); - } + public AuthenticatorUnavailableException(String message) { + super(message); + } - public AuthenticatorUnavailableException(Throwable cause) { - super(cause); - } + public AuthenticatorUnavailableException(Throwable cause) { + super(cause); + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/BadCredentialsException.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/BadCredentialsException.java index 12b9195c0e..0d705f98cf 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/BadCredentialsException.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/BadCredentialsException.java @@ -13,26 +13,25 @@ public class BadCredentialsException extends Exception { - private static final long serialVersionUID = 9092575587366580869L; + private static final long serialVersionUID = 9092575587366580869L; - public BadCredentialsException() { - super(); - } + public BadCredentialsException() { + super(); + } - public BadCredentialsException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - } + public BadCredentialsException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } - public BadCredentialsException(String message, Throwable cause) { - super(message, cause); - } + public BadCredentialsException(String message, Throwable cause) { + super(message, cause); + } - public BadCredentialsException(String message) { - super(message); - } + public BadCredentialsException(String message) { + super(message); + } - public BadCredentialsException(Throwable cause) { - super(cause); - } + public BadCredentialsException(Throwable cause) { + super(cause); + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java index b6738b725b..808abfc5ea 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticator.java @@ -20,48 +20,54 @@ public class HTTPJwtKeyByOpenIdConnectAuthenticator extends AbstractHTTPJwtAuthenticator { - //private final static Logger log = LogManager.getLogger(HTTPJwtKeyByOpenIdConnectAuthenticator.class); - - public HTTPJwtKeyByOpenIdConnectAuthenticator(Settings settings, Path configPath) { - super(settings, configPath); - } - - protected KeyProvider initKeyProvider(Settings settings, Path configPath) throws Exception { - int idpRequestTimeoutMs = settings.getAsInt("idp_request_timeout_ms", 5000); - int idpQueuedThreadTimeoutMs = settings.getAsInt("idp_queued_thread_timeout_ms", 2500); - - int refreshRateLimitTimeWindowMs = settings.getAsInt("refresh_rate_limit_time_window_ms", 10000); - int refreshRateLimitCount = settings.getAsInt("refresh_rate_limit_count", 10); - String jwksUri = settings.get("jwks_uri"); - - KeySetRetriever keySetRetriever; - if(jwksUri != null && !jwksUri.isBlank()) { - keySetRetriever = - new KeySetRetriever(getSSLConfig(settings, configPath), settings.getAsBoolean("cache_jwks_endpoint", false), jwksUri); - } else { - keySetRetriever = new KeySetRetriever(settings.get("openid_connect_url"), getSSLConfig(settings, configPath), settings.getAsBoolean("cache_jwks_endpoint", false)); - } - - keySetRetriever.setRequestTimeoutMs(idpRequestTimeoutMs); - - SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(keySetRetriever); - - selfRefreshingKeySet.setRequestTimeoutMs(idpRequestTimeoutMs); - selfRefreshingKeySet.setQueuedThreadTimeoutMs(idpQueuedThreadTimeoutMs); - selfRefreshingKeySet.setRefreshRateLimitTimeWindowMs(refreshRateLimitTimeWindowMs); - selfRefreshingKeySet.setRefreshRateLimitCount(refreshRateLimitCount); - - return selfRefreshingKeySet; - } - - private static SettingsBasedSSLConfigurator.SSLConfig getSSLConfig(Settings settings, Path configPath) - throws Exception { - return new SettingsBasedSSLConfigurator(settings, configPath, "openid_connect_idp").buildSSLConfig(); - } - - @Override - public String getType() { - return "jwt-key-by-oidc"; - } + // private final static Logger log = LogManager.getLogger(HTTPJwtKeyByOpenIdConnectAuthenticator.class); + + public HTTPJwtKeyByOpenIdConnectAuthenticator(Settings settings, Path configPath) { + super(settings, configPath); + } + + protected KeyProvider initKeyProvider(Settings settings, Path configPath) throws Exception { + int idpRequestTimeoutMs = settings.getAsInt("idp_request_timeout_ms", 5000); + int idpQueuedThreadTimeoutMs = settings.getAsInt("idp_queued_thread_timeout_ms", 2500); + + int refreshRateLimitTimeWindowMs = settings.getAsInt("refresh_rate_limit_time_window_ms", 10000); + int refreshRateLimitCount = settings.getAsInt("refresh_rate_limit_count", 10); + String jwksUri = settings.get("jwks_uri"); + + KeySetRetriever keySetRetriever; + if (jwksUri != null && !jwksUri.isBlank()) { + keySetRetriever = new KeySetRetriever( + getSSLConfig(settings, configPath), + settings.getAsBoolean("cache_jwks_endpoint", false), + jwksUri + ); + } else { + keySetRetriever = new KeySetRetriever( + settings.get("openid_connect_url"), + getSSLConfig(settings, configPath), + settings.getAsBoolean("cache_jwks_endpoint", false) + ); + } + + keySetRetriever.setRequestTimeoutMs(idpRequestTimeoutMs); + + SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(keySetRetriever); + + selfRefreshingKeySet.setRequestTimeoutMs(idpRequestTimeoutMs); + selfRefreshingKeySet.setQueuedThreadTimeoutMs(idpQueuedThreadTimeoutMs); + selfRefreshingKeySet.setRefreshRateLimitTimeWindowMs(refreshRateLimitTimeWindowMs); + selfRefreshingKeySet.setRefreshRateLimitCount(refreshRateLimitCount); + + return selfRefreshingKeySet; + } + + private static SettingsBasedSSLConfigurator.SSLConfig getSSLConfig(Settings settings, Path configPath) throws Exception { + return new SettingsBasedSSLConfigurator(settings, configPath, "openid_connect_idp").buildSSLConfig(); + } + + @Override + public String getType() { + return "jwt-key-by-oidc"; + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java index a337224cdc..5893d623a7 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/JwtVerifier.java @@ -29,107 +29,106 @@ public class JwtVerifier { - private final static Logger log = LogManager.getLogger(JwtVerifier.class); - - private final KeyProvider keyProvider; - private final int clockSkewToleranceSeconds; - private final String requiredIssuer; - private final String requiredAudience; - - public JwtVerifier(KeyProvider keyProvider, int clockSkewToleranceSeconds, String requiredIssuer, String requiredAudience) { - this.keyProvider = keyProvider; - this.clockSkewToleranceSeconds = clockSkewToleranceSeconds; - this.requiredIssuer = requiredIssuer; - this.requiredAudience = requiredAudience; - } - - public JwtToken getVerifiedJwtToken(String encodedJwt) throws BadCredentialsException { - try { - JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(encodedJwt); - JwtToken jwt = jwtConsumer.getJwtToken(); - - String escapedKid = jwt.getJwsHeaders().getKeyId(); - String kid = escapedKid; - if (!Strings.isNullOrEmpty(kid)) { - kid = StringEscapeUtils.unescapeJava(escapedKid); - } - JsonWebKey key = keyProvider.getKey(kid); - - // Algorithm is not mandatory for the key material, so we set it to the same as the JWT - if (key.getAlgorithm() == null && key.getPublicKeyUse() == PublicKeyUse.SIGN && key.getKeyType() == KeyType.RSA) - { - key.setAlgorithm(jwt.getJwsHeaders().getAlgorithm()); - } - - JwsSignatureVerifier signatureVerifier = getInitializedSignatureVerifier(key, jwt); - - - boolean signatureValid = jwtConsumer.verifySignatureWith(signatureVerifier); - - if (!signatureValid && Strings.isNullOrEmpty(kid)) { - key = keyProvider.getKeyAfterRefresh(null); - signatureVerifier = getInitializedSignatureVerifier(key, jwt); - signatureValid = jwtConsumer.verifySignatureWith(signatureVerifier); - } - - if (!signatureValid) { - throw new BadCredentialsException("Invalid JWT signature"); - } - - validateClaims(jwt); - - return jwt; - } catch (JwtException e) { - throw new BadCredentialsException(e.getMessage(), e); - } - } + private final static Logger log = LogManager.getLogger(JwtVerifier.class); + + private final KeyProvider keyProvider; + private final int clockSkewToleranceSeconds; + private final String requiredIssuer; + private final String requiredAudience; + + public JwtVerifier(KeyProvider keyProvider, int clockSkewToleranceSeconds, String requiredIssuer, String requiredAudience) { + this.keyProvider = keyProvider; + this.clockSkewToleranceSeconds = clockSkewToleranceSeconds; + this.requiredIssuer = requiredIssuer; + this.requiredAudience = requiredAudience; + } + + public JwtToken getVerifiedJwtToken(String encodedJwt) throws BadCredentialsException { + try { + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(encodedJwt); + JwtToken jwt = jwtConsumer.getJwtToken(); + + String escapedKid = jwt.getJwsHeaders().getKeyId(); + String kid = escapedKid; + if (!Strings.isNullOrEmpty(kid)) { + kid = StringEscapeUtils.unescapeJava(escapedKid); + } + JsonWebKey key = keyProvider.getKey(kid); + + // Algorithm is not mandatory for the key material, so we set it to the same as the JWT + if (key.getAlgorithm() == null && key.getPublicKeyUse() == PublicKeyUse.SIGN && key.getKeyType() == KeyType.RSA) { + key.setAlgorithm(jwt.getJwsHeaders().getAlgorithm()); + } + + JwsSignatureVerifier signatureVerifier = getInitializedSignatureVerifier(key, jwt); + + boolean signatureValid = jwtConsumer.verifySignatureWith(signatureVerifier); + + if (!signatureValid && Strings.isNullOrEmpty(kid)) { + key = keyProvider.getKeyAfterRefresh(null); + signatureVerifier = getInitializedSignatureVerifier(key, jwt); + signatureValid = jwtConsumer.verifySignatureWith(signatureVerifier); + } + + if (!signatureValid) { + throw new BadCredentialsException("Invalid JWT signature"); + } + + validateClaims(jwt); + + return jwt; + } catch (JwtException e) { + throw new BadCredentialsException(e.getMessage(), e); + } + } private void validateSignatureAlgorithm(JsonWebKey key, JwtToken jwt) throws BadCredentialsException { if (Strings.isNullOrEmpty(key.getAlgorithm())) { return; } - SignatureAlgorithm keyAlgorithm =SignatureAlgorithm.getAlgorithm(key.getAlgorithm()); + SignatureAlgorithm keyAlgorithm = SignatureAlgorithm.getAlgorithm(key.getAlgorithm()); SignatureAlgorithm tokenAlgorithm = SignatureAlgorithm.getAlgorithm(jwt.getJwsHeaders().getAlgorithm()); if (!keyAlgorithm.equals(tokenAlgorithm)) { - throw new BadCredentialsException("Algorithm of JWT does not match algorithm of JWK (" + keyAlgorithm + " != " + tokenAlgorithm + ")"); + throw new BadCredentialsException( + "Algorithm of JWT does not match algorithm of JWK (" + keyAlgorithm + " != " + tokenAlgorithm + ")" + ); } } + private JwsSignatureVerifier getInitializedSignatureVerifier(JsonWebKey key, JwtToken jwt) throws BadCredentialsException, + JwtException { - private JwsSignatureVerifier getInitializedSignatureVerifier(JsonWebKey key, JwtToken jwt) - throws BadCredentialsException, JwtException { - - validateSignatureAlgorithm(key, jwt); + validateSignatureAlgorithm(key, jwt); JwsSignatureVerifier result = JwsUtils.getSignatureVerifier(key, jwt.getJwsHeaders().getSignatureAlgorithm()); - if (result == null) { - throw new BadCredentialsException("Cannot verify JWT"); - } else { - return result; - } - } - - private void validateClaims(JwtToken jwt) throws JwtException { - JwtClaims claims = jwt.getClaims(); - - if (claims != null) { - JwtUtils.validateJwtExpiry(claims, clockSkewToleranceSeconds, false); - JwtUtils.validateJwtNotBefore(claims, clockSkewToleranceSeconds, false); - validateRequiredAudienceAndIssuer(claims); - } - } - - private void validateRequiredAudienceAndIssuer(JwtClaims claims) { - String audience = claims.getAudience(); - String issuer = claims.getIssuer(); - - if (!Strings.isNullOrEmpty(requiredAudience) && !requiredAudience.equals(audience)) { - throw new JwtException("Invalid audience"); - } - - if (!Strings.isNullOrEmpty(requiredIssuer) && !requiredIssuer.equals(issuer)) { - throw new JwtException("Invalid issuer"); - } - } + if (result == null) { + throw new BadCredentialsException("Cannot verify JWT"); + } else { + return result; + } + } + + private void validateClaims(JwtToken jwt) throws JwtException { + JwtClaims claims = jwt.getClaims(); + + if (claims != null) { + JwtUtils.validateJwtExpiry(claims, clockSkewToleranceSeconds, false); + JwtUtils.validateJwtNotBefore(claims, clockSkewToleranceSeconds, false); + validateRequiredAudienceAndIssuer(claims); + } + } + + private void validateRequiredAudienceAndIssuer(JwtClaims claims) { + String audience = claims.getAudience(); + String issuer = claims.getIssuer(); + + if (!Strings.isNullOrEmpty(requiredAudience) && !requiredAudience.equals(audience)) { + throw new JwtException("Invalid audience"); + } + + if (!Strings.isNullOrEmpty(requiredIssuer) && !requiredIssuer.equals(issuer)) { + throw new JwtException("Invalid issuer"); + } + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeyProvider.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeyProvider.java index 5eff7cb213..a0e76c918f 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeyProvider.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeyProvider.java @@ -14,6 +14,7 @@ import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; public interface KeyProvider { - public JsonWebKey getKey(String kid) throws AuthenticatorUnavailableException, BadCredentialsException; - public JsonWebKey getKeyAfterRefresh(String kid) throws AuthenticatorUnavailableException, BadCredentialsException; + public JsonWebKey getKey(String kid) throws AuthenticatorUnavailableException, BadCredentialsException; + + public JsonWebKey getKeyAfterRefresh(String kid) throws AuthenticatorUnavailableException, BadCredentialsException; } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetProvider.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetProvider.java index edbe39f020..53ea0237db 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetProvider.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetProvider.java @@ -15,5 +15,5 @@ @FunctionalInterface public interface KeySetProvider { - JsonWebKeys get() throws AuthenticatorUnavailableException; + JsonWebKeys get() throws AuthenticatorUnavailableException; } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java index f56c0dd90c..9ef50a4404 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetriever.java @@ -39,205 +39,218 @@ import org.opensearch.security.DefaultObjectMapper; - public class KeySetRetriever implements KeySetProvider { - private final static Logger log = LogManager.getLogger(KeySetRetriever.class); - private static final long CACHE_STATUS_LOG_INTERVAL_MS = 60L * 60L * 1000L; - - private String openIdConnectEndpoint; - private SSLConfig sslConfig; - private int requestTimeoutMs = 10000; - private CacheConfig cacheConfig; - private HttpCacheStorage oidcHttpCacheStorage; - private int oidcCacheHits = 0; - private int oidcCacheMisses = 0; - private int oidcCacheHitsValidated = 0; - private int oidcCacheModuleResponses = 0; - private long oidcRequests = 0; - private long lastCacheStatusLog = 0; - private String jwksUri; - - KeySetRetriever(String openIdConnectEndpoint, SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint) { - this.openIdConnectEndpoint = openIdConnectEndpoint; - this.sslConfig = sslConfig; - - configureCache(useCacheForOidConnectEndpoint); - } - - KeySetRetriever(SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint, String jwksUri) { - this.jwksUri = jwksUri; - this.sslConfig = sslConfig; - - configureCache(useCacheForOidConnectEndpoint); - } - - public JsonWebKeys get() throws AuthenticatorUnavailableException { - String uri = getJwksUri(); - - try (CloseableHttpClient httpClient = createHttpClient(null)) { - - HttpGet httpGet = new HttpGet(uri); - - RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) - .setConnectTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS).build(); - - httpGet.setConfig(requestConfig); - - try (CloseableHttpResponse response = httpClient.execute(httpGet)) { - if (response.getCode() < 200 || response.getCode() >= 300) { - throw new AuthenticatorUnavailableException("Error while getting " + uri + ": " + response.getReasonPhrase()); - } - - HttpEntity httpEntity = response.getEntity(); - - if (httpEntity == null) { - throw new AuthenticatorUnavailableException( - "Error while getting " + uri + ": Empty response entity"); - } + private final static Logger log = LogManager.getLogger(KeySetRetriever.class); + private static final long CACHE_STATUS_LOG_INTERVAL_MS = 60L * 60L * 1000L; - JsonWebKeys keySet = JwkUtils.readJwkSet(httpEntity.getContent()); + private String openIdConnectEndpoint; + private SSLConfig sslConfig; + private int requestTimeoutMs = 10000; + private CacheConfig cacheConfig; + private HttpCacheStorage oidcHttpCacheStorage; + private int oidcCacheHits = 0; + private int oidcCacheMisses = 0; + private int oidcCacheHitsValidated = 0; + private int oidcCacheModuleResponses = 0; + private long oidcRequests = 0; + private long lastCacheStatusLog = 0; + private String jwksUri; - return keySet; - } - } catch (IOException e) { - throw new AuthenticatorUnavailableException("Error while getting " + uri + ": " + e, e); - } + KeySetRetriever(String openIdConnectEndpoint, SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint) { + this.openIdConnectEndpoint = openIdConnectEndpoint; + this.sslConfig = sslConfig; - } + configureCache(useCacheForOidConnectEndpoint); + } - String getJwksUri() throws AuthenticatorUnavailableException { + KeySetRetriever(SSLConfig sslConfig, boolean useCacheForOidConnectEndpoint, String jwksUri) { + this.jwksUri = jwksUri; + this.sslConfig = sslConfig; - if (!Strings.isNullOrEmpty(jwksUri)) { - return jwksUri; - } + configureCache(useCacheForOidConnectEndpoint); + } - if (Strings.isNullOrEmpty(openIdConnectEndpoint)) { - throw new AuthenticatorUnavailableException("Either openid_connect_url or jwks_uri must be configured for OIDC Authentication backend"); - } + public JsonWebKeys get() throws AuthenticatorUnavailableException { + String uri = getJwksUri(); - try (CloseableHttpClient httpClient = createHttpClient(oidcHttpCacheStorage)) { + try (CloseableHttpClient httpClient = createHttpClient(null)) { - HttpGet httpGet = new HttpGet(openIdConnectEndpoint); + HttpGet httpGet = new HttpGet(uri); - RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) - .setConnectTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS).build(); + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) + .setConnectTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) + .build(); - httpGet.setConfig(requestConfig); + httpGet.setConfig(requestConfig); - HttpCacheContext httpContext = null; + try (CloseableHttpResponse response = httpClient.execute(httpGet)) { + if (response.getCode() < 200 || response.getCode() >= 300) { + throw new AuthenticatorUnavailableException("Error while getting " + uri + ": " + response.getReasonPhrase()); + } - if (oidcHttpCacheStorage != null) { - httpContext = new HttpCacheContext(); - } + HttpEntity httpEntity = response.getEntity(); - try (CloseableHttpResponse response = httpClient.execute(httpGet, httpContext)) { - if (httpContext != null) { - logCacheResponseStatus(httpContext); - } + if (httpEntity == null) { + throw new AuthenticatorUnavailableException("Error while getting " + uri + ": Empty response entity"); + } - if (response.getCode() < 200 || response.getCode() >= 300) { - throw new AuthenticatorUnavailableException( - "Error while getting " + openIdConnectEndpoint + ": " + response.getReasonPhrase()); - } + JsonWebKeys keySet = JwkUtils.readJwkSet(httpEntity.getContent()); - HttpEntity httpEntity = response.getEntity(); + return keySet; + } + } catch (IOException e) { + throw new AuthenticatorUnavailableException("Error while getting " + uri + ": " + e, e); + } - if (httpEntity == null) { - throw new AuthenticatorUnavailableException( - "Error while getting " + openIdConnectEndpoint + ": Empty response entity"); - } + } + + String getJwksUri() throws AuthenticatorUnavailableException { - OpenIdProviderConfiguration parsedEntity = DefaultObjectMapper.objectMapper.readValue(httpEntity.getContent(), - OpenIdProviderConfiguration.class); + if (!Strings.isNullOrEmpty(jwksUri)) { + return jwksUri; + } - return parsedEntity.getJwksUri(); + if (Strings.isNullOrEmpty(openIdConnectEndpoint)) { + throw new AuthenticatorUnavailableException( + "Either openid_connect_url or jwks_uri must be configured for OIDC Authentication backend" + ); + } + + try (CloseableHttpClient httpClient = createHttpClient(oidcHttpCacheStorage)) { - } + HttpGet httpGet = new HttpGet(openIdConnectEndpoint); - } catch (IOException e) { - throw new AuthenticatorUnavailableException("Error while getting " + openIdConnectEndpoint + ": " + e, e); - } + RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) + .setConnectTimeout(getRequestTimeoutMs(), TimeUnit.MILLISECONDS) + .build(); - } + httpGet.setConfig(requestConfig); - public int getRequestTimeoutMs() { - return requestTimeoutMs; - } + HttpCacheContext httpContext = null; - public void setRequestTimeoutMs(int httpTimeoutMs) { - this.requestTimeoutMs = httpTimeoutMs; - } + if (oidcHttpCacheStorage != null) { + httpContext = new HttpCacheContext(); + } - private void logCacheResponseStatus(HttpCacheContext httpContext) { - this.oidcRequests++; + try (CloseableHttpResponse response = httpClient.execute(httpGet, httpContext)) { + if (httpContext != null) { + logCacheResponseStatus(httpContext); + } - switch (httpContext.getCacheResponseStatus()) { - case CACHE_HIT: - this.oidcCacheHits++; - break; - case CACHE_MODULE_RESPONSE: - this.oidcCacheModuleResponses++; - break; - case CACHE_MISS: - this.oidcCacheMisses++; - break; - case VALIDATED: - this.oidcCacheHitsValidated++; - break; - } + if (response.getCode() < 200 || response.getCode() >= 300) { + throw new AuthenticatorUnavailableException( + "Error while getting " + openIdConnectEndpoint + ": " + response.getReasonPhrase() + ); + } + + HttpEntity httpEntity = response.getEntity(); - long now = System.currentTimeMillis(); + if (httpEntity == null) { + throw new AuthenticatorUnavailableException("Error while getting " + openIdConnectEndpoint + ": Empty response entity"); + } - if (this.oidcRequests >= 2 && now - lastCacheStatusLog > CACHE_STATUS_LOG_INTERVAL_MS) { - log.info("Cache status for KeySetRetriever:\noidcCacheHits: {}\noidcCacheHitsValidated: {}" - + "\noidcCacheModuleResponses: {}" + "\noidcCacheMisses: {}", oidcCacheHits, oidcCacheHitsValidated, oidcCacheModuleResponses, oidcCacheMisses); - lastCacheStatusLog = now; - } + OpenIdProviderConfiguration parsedEntity = DefaultObjectMapper.objectMapper.readValue( + httpEntity.getContent(), + OpenIdProviderConfiguration.class + ); - } + return parsedEntity.getJwksUri(); - private CloseableHttpClient createHttpClient(HttpCacheStorage httpCacheStorage) { - HttpClientBuilder builder; + } - if (httpCacheStorage != null) { - builder = CachingHttpClients.custom().setCacheConfig(cacheConfig).setHttpCacheStorage(httpCacheStorage); - } else { - builder = HttpClients.custom(); - } + } catch (IOException e) { + throw new AuthenticatorUnavailableException("Error while getting " + openIdConnectEndpoint + ": " + e, e); + } - builder.useSystemProperties(); + } - if (sslConfig != null) { - final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() - .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()) - .build(); + public int getRequestTimeoutMs() { + return requestTimeoutMs; + } - builder.setConnectionManager(cm); - } + public void setRequestTimeoutMs(int httpTimeoutMs) { + this.requestTimeoutMs = httpTimeoutMs; + } - return builder.build(); - } + private void logCacheResponseStatus(HttpCacheContext httpContext) { + this.oidcRequests++; - private void configureCache(boolean useCacheForOidConnectEndpoint) { - if (useCacheForOidConnectEndpoint) { - cacheConfig = CacheConfig.custom().setMaxCacheEntries(10).setMaxObjectSize(1024L * 1024L).build(); - oidcHttpCacheStorage = new BasicHttpCacheStorage(cacheConfig); - } - } - - public int getOidcCacheHits() { - return oidcCacheHits; - } - - public int getOidcCacheMisses() { - return oidcCacheMisses; - } - - public int getOidcCacheHitsValidated() { - return oidcCacheHitsValidated; - } - - public int getOidcCacheModuleResponses() { - return oidcCacheModuleResponses; - } + switch (httpContext.getCacheResponseStatus()) { + case CACHE_HIT: + this.oidcCacheHits++; + break; + case CACHE_MODULE_RESPONSE: + this.oidcCacheModuleResponses++; + break; + case CACHE_MISS: + this.oidcCacheMisses++; + break; + case VALIDATED: + this.oidcCacheHitsValidated++; + break; + } + + long now = System.currentTimeMillis(); + + if (this.oidcRequests >= 2 && now - lastCacheStatusLog > CACHE_STATUS_LOG_INTERVAL_MS) { + log.info( + "Cache status for KeySetRetriever:\noidcCacheHits: {}\noidcCacheHitsValidated: {}" + + "\noidcCacheModuleResponses: {}" + + "\noidcCacheMisses: {}", + oidcCacheHits, + oidcCacheHitsValidated, + oidcCacheModuleResponses, + oidcCacheMisses + ); + lastCacheStatusLog = now; + } + + } + + private CloseableHttpClient createHttpClient(HttpCacheStorage httpCacheStorage) { + HttpClientBuilder builder; + + if (httpCacheStorage != null) { + builder = CachingHttpClients.custom().setCacheConfig(cacheConfig).setHttpCacheStorage(httpCacheStorage); + } else { + builder = HttpClients.custom(); + } + + builder.useSystemProperties(); + + if (sslConfig != null) { + final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create() + .setSSLSocketFactory(sslConfig.toSSLConnectionSocketFactory()) + .build(); + + builder.setConnectionManager(cm); + } + + return builder.build(); + } + + private void configureCache(boolean useCacheForOidConnectEndpoint) { + if (useCacheForOidConnectEndpoint) { + cacheConfig = CacheConfig.custom().setMaxCacheEntries(10).setMaxObjectSize(1024L * 1024L).build(); + oidcHttpCacheStorage = new BasicHttpCacheStorage(cacheConfig); + } + } + + public int getOidcCacheHits() { + return oidcCacheHits; + } + + public int getOidcCacheMisses() { + return oidcCacheMisses; + } + + public int getOidcCacheHitsValidated() { + return oidcCacheHitsValidated; + } + + public int getOidcCacheModuleResponses() { + return oidcCacheModuleResponses; + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySet.java b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySet.java index 7e3cec8246..fe410b171c 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySet.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySet.java @@ -25,295 +25,300 @@ import org.apache.logging.log4j.Logger; public class SelfRefreshingKeySet implements KeyProvider { - private static final Logger log = LogManager.getLogger(SelfRefreshingKeySet.class); - - private final KeySetProvider keySetProvider; - private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue()); - private volatile JsonWebKeys jsonWebKeys = new JsonWebKeys(); - private boolean refreshInProgress = false; - private long refreshCount = 0; - private long queuedGetCount = 0; - private long recentRefreshCount = 0; - private long refreshTime = 0; - private Throwable lastRefreshFailure = null; - private int requestTimeoutMs = 5000; - private int queuedThreadTimeoutMs = 2500; - private int refreshRateLimitTimeWindowMs = 10000; - private int refreshRateLimitCount = 10; - - public SelfRefreshingKeySet(KeySetProvider refreshFunction) { - this.keySetProvider = refreshFunction; - } - - public JsonWebKey getKey(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { - if (Strings.isNullOrEmpty(kid)) { - return getKeyWithoutKeyId(); - } else { - return getKeyWithKeyId(kid); - } - } - - public synchronized JsonWebKey getKeyAfterRefresh(String kid) - throws AuthenticatorUnavailableException, BadCredentialsException { - JsonWebKey result = getKeyAfterRefreshInternal(kid); - - if (result != null) { - return result; - } else if (jsonWebKeys.getKeys().size() == 0) { - throw new AuthenticatorUnavailableException("No JWK are available from IdP"); - } else { - throw new BadCredentialsException("JWT did not contain KID which is required if IdP provides multiple JWK"); - } - } - - private synchronized JsonWebKey getKeyAfterRefreshInternal(String kid) throws AuthenticatorUnavailableException { - if (refreshInProgress) { - return waitForRefreshToFinish(kid); - } else { - return performRefresh(kid); - } - } - - private JsonWebKey getKeyWithoutKeyId() throws AuthenticatorUnavailableException, BadCredentialsException { - List keys = jsonWebKeys.getKeys(); - - if (keys == null || keys.size() == 0) { - JsonWebKey result = getKeyWithRefresh(null); - - if (result != null) { - return result; - } else { - throw new AuthenticatorUnavailableException("No JWK are available from IdP"); - } - } else if (keys.size() == 1) { - return keys.get(0); - } else { - JsonWebKey result = getKeyWithRefresh(null); - - if (result != null) { - return result; - } else { - throw new BadCredentialsException( - "JWT did not contain KID which is required if IdP provides multiple JWK"); - } - } - } - - private JsonWebKey getKeyWithKeyId(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { - JsonWebKey result = jsonWebKeys.getKey(kid); - - if (result != null) { - return result; - } - - result = getKeyWithRefresh(kid); - - if (result == null) { - throw new BadCredentialsException("Unknown kid " + kid); - } - - return result; - } - - private synchronized JsonWebKey getKeyWithRefresh(String kid) throws AuthenticatorUnavailableException { - - // Always re-check within synchronized to handle any races - - JsonWebKey result = getKeySimple(kid); - - if (result != null) { - return result; - } - - return getKeyAfterRefreshInternal(kid); - } - - private JsonWebKey getKeySimple(String kid) { - if (Strings.isNullOrEmpty(kid)) { - List keys = jsonWebKeys.getKeys(); - - if (keys != null && keys.size() == 1) { - return keys.get(0); - } else { - return null; - } - - } else { - return jsonWebKeys.getKey(kid); - } - } - - private synchronized JsonWebKey waitForRefreshToFinish(String kid) { - queuedGetCount++; - long currentRefreshCount = refreshCount; - - try { - wait(queuedThreadTimeoutMs); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.debug(e.toString()); - } - - // Just be optimistic and re-check the key - - JsonWebKey result = getKeySimple(kid); - - if (result != null) { - return result; - } - - if (refreshInProgress && currentRefreshCount == refreshCount) { - // The wait() call returned due to the timeout. - throw new AuthenticatorUnavailableException("Authentication backend timed out"); - } else if (lastRefreshFailure != null) { - throw new AuthenticatorUnavailableException("Authentication backend failed", lastRefreshFailure); - } else { - // Refresh was successful, but we did not get a matching key - return null; - } - } - - private synchronized JsonWebKey performRefresh(String kid) { - if (log.isDebugEnabled()) { - log.debug("performRefresh({})", kid); - } - - final boolean recentRefresh; - - if (System.currentTimeMillis() - refreshTime < refreshRateLimitTimeWindowMs) { - recentRefreshCount++; - recentRefresh = true; - - if (recentRefreshCount > refreshRateLimitCount) { - throw new AuthenticatorUnavailableException("Too many unknown kids recently: " + recentRefreshCount); - } - } else { - recentRefresh = false; - } - - refreshInProgress = true; - refreshCount++; - - log.info("Performing refresh {}", refreshCount); - - long currentRefreshCount = refreshCount; - - try { - - Future future = threadPoolExecutor.submit(new Runnable() { - - @Override - public void run() { - try { - JsonWebKeys newKeys = keySetProvider.get(); - - if (newKeys == null) { - throw new RuntimeException("Refresh function " + keySetProvider + " yielded null"); - } - - log.info("KeySetProvider finished"); - - synchronized (SelfRefreshingKeySet.this) { - jsonWebKeys = newKeys; - refreshInProgress = false; - lastRefreshFailure = null; - SelfRefreshingKeySet.this.notifyAll(); - } - } catch (Throwable e) { - synchronized (SelfRefreshingKeySet.this) { - lastRefreshFailure = e; - refreshInProgress = false; - SelfRefreshingKeySet.this.notifyAll(); - } - log.warn("KeySetProvider threw error", e); - } finally { - if (!recentRefresh) { - recentRefreshCount = 0; - refreshTime = System.currentTimeMillis(); - } - } - - } - }); - - try { - wait(requestTimeoutMs); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - log.debug(e.toString()); - } - - JsonWebKey result = getKeySimple(kid); - - if (result != null) { - return result; - } - - if (refreshInProgress && currentRefreshCount == refreshCount) { - if (!future.isDone()) { - future.cancel(true); - } - - lastRefreshFailure = new AuthenticatorUnavailableException("Authentication backend timed out"); - - throw new AuthenticatorUnavailableException("Authentication backend timed out"); - } - - if (lastRefreshFailure != null) { - throw new AuthenticatorUnavailableException("Authentication backend failed", lastRefreshFailure); - } - - return null; - - } catch (RejectedExecutionException e) { - throw new AuthenticatorUnavailableException("Did not try to call authentication backend because of " - + threadPoolExecutor.getActiveCount() + " pending threads", e); - } finally { - if (refreshInProgress && currentRefreshCount == refreshCount) { - refreshInProgress = false; - notifyAll(); - } - } - } - - public int getRequestTimeoutMs() { - return requestTimeoutMs; - } - - public void setRequestTimeoutMs(int requestTimeoutMs) { - this.requestTimeoutMs = requestTimeoutMs; - } - - public int getQueuedThreadTimeoutMs() { - return queuedThreadTimeoutMs; - } - - public void setQueuedThreadTimeoutMs(int queuedThreadTimeoutMs) { - this.queuedThreadTimeoutMs = queuedThreadTimeoutMs; - } - - public long getRefreshCount() { - return refreshCount; - } - - public long getQueuedGetCount() { - return queuedGetCount; - } - - public int getRefreshRateLimitTimeWindowMs() { - return refreshRateLimitTimeWindowMs; - } - - public void setRefreshRateLimitTimeWindowMs(int refreshRateLimitTimeWindowMs) { - this.refreshRateLimitTimeWindowMs = refreshRateLimitTimeWindowMs; - } - - public int getRefreshRateLimitCount() { - return refreshRateLimitCount; - } - - public void setRefreshRateLimitCount(int refreshRateLimitCount) { - this.refreshRateLimitCount = refreshRateLimitCount; - } + private static final Logger log = LogManager.getLogger(SelfRefreshingKeySet.class); + + private final KeySetProvider keySetProvider; + private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( + 1, + 10, + 1000, + TimeUnit.MILLISECONDS, + new LinkedBlockingQueue() + ); + private volatile JsonWebKeys jsonWebKeys = new JsonWebKeys(); + private boolean refreshInProgress = false; + private long refreshCount = 0; + private long queuedGetCount = 0; + private long recentRefreshCount = 0; + private long refreshTime = 0; + private Throwable lastRefreshFailure = null; + private int requestTimeoutMs = 5000; + private int queuedThreadTimeoutMs = 2500; + private int refreshRateLimitTimeWindowMs = 10000; + private int refreshRateLimitCount = 10; + + public SelfRefreshingKeySet(KeySetProvider refreshFunction) { + this.keySetProvider = refreshFunction; + } + + public JsonWebKey getKey(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { + if (Strings.isNullOrEmpty(kid)) { + return getKeyWithoutKeyId(); + } else { + return getKeyWithKeyId(kid); + } + } + + public synchronized JsonWebKey getKeyAfterRefresh(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { + JsonWebKey result = getKeyAfterRefreshInternal(kid); + + if (result != null) { + return result; + } else if (jsonWebKeys.getKeys().size() == 0) { + throw new AuthenticatorUnavailableException("No JWK are available from IdP"); + } else { + throw new BadCredentialsException("JWT did not contain KID which is required if IdP provides multiple JWK"); + } + } + + private synchronized JsonWebKey getKeyAfterRefreshInternal(String kid) throws AuthenticatorUnavailableException { + if (refreshInProgress) { + return waitForRefreshToFinish(kid); + } else { + return performRefresh(kid); + } + } + + private JsonWebKey getKeyWithoutKeyId() throws AuthenticatorUnavailableException, BadCredentialsException { + List keys = jsonWebKeys.getKeys(); + + if (keys == null || keys.size() == 0) { + JsonWebKey result = getKeyWithRefresh(null); + + if (result != null) { + return result; + } else { + throw new AuthenticatorUnavailableException("No JWK are available from IdP"); + } + } else if (keys.size() == 1) { + return keys.get(0); + } else { + JsonWebKey result = getKeyWithRefresh(null); + + if (result != null) { + return result; + } else { + throw new BadCredentialsException("JWT did not contain KID which is required if IdP provides multiple JWK"); + } + } + } + + private JsonWebKey getKeyWithKeyId(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { + JsonWebKey result = jsonWebKeys.getKey(kid); + + if (result != null) { + return result; + } + + result = getKeyWithRefresh(kid); + + if (result == null) { + throw new BadCredentialsException("Unknown kid " + kid); + } + + return result; + } + + private synchronized JsonWebKey getKeyWithRefresh(String kid) throws AuthenticatorUnavailableException { + + // Always re-check within synchronized to handle any races + + JsonWebKey result = getKeySimple(kid); + + if (result != null) { + return result; + } + + return getKeyAfterRefreshInternal(kid); + } + + private JsonWebKey getKeySimple(String kid) { + if (Strings.isNullOrEmpty(kid)) { + List keys = jsonWebKeys.getKeys(); + + if (keys != null && keys.size() == 1) { + return keys.get(0); + } else { + return null; + } + + } else { + return jsonWebKeys.getKey(kid); + } + } + + private synchronized JsonWebKey waitForRefreshToFinish(String kid) { + queuedGetCount++; + long currentRefreshCount = refreshCount; + + try { + wait(queuedThreadTimeoutMs); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.debug(e.toString()); + } + + // Just be optimistic and re-check the key + + JsonWebKey result = getKeySimple(kid); + + if (result != null) { + return result; + } + + if (refreshInProgress && currentRefreshCount == refreshCount) { + // The wait() call returned due to the timeout. + throw new AuthenticatorUnavailableException("Authentication backend timed out"); + } else if (lastRefreshFailure != null) { + throw new AuthenticatorUnavailableException("Authentication backend failed", lastRefreshFailure); + } else { + // Refresh was successful, but we did not get a matching key + return null; + } + } + + private synchronized JsonWebKey performRefresh(String kid) { + if (log.isDebugEnabled()) { + log.debug("performRefresh({})", kid); + } + + final boolean recentRefresh; + + if (System.currentTimeMillis() - refreshTime < refreshRateLimitTimeWindowMs) { + recentRefreshCount++; + recentRefresh = true; + + if (recentRefreshCount > refreshRateLimitCount) { + throw new AuthenticatorUnavailableException("Too many unknown kids recently: " + recentRefreshCount); + } + } else { + recentRefresh = false; + } + + refreshInProgress = true; + refreshCount++; + + log.info("Performing refresh {}", refreshCount); + + long currentRefreshCount = refreshCount; + + try { + + Future future = threadPoolExecutor.submit(new Runnable() { + + @Override + public void run() { + try { + JsonWebKeys newKeys = keySetProvider.get(); + + if (newKeys == null) { + throw new RuntimeException("Refresh function " + keySetProvider + " yielded null"); + } + + log.info("KeySetProvider finished"); + + synchronized (SelfRefreshingKeySet.this) { + jsonWebKeys = newKeys; + refreshInProgress = false; + lastRefreshFailure = null; + SelfRefreshingKeySet.this.notifyAll(); + } + } catch (Throwable e) { + synchronized (SelfRefreshingKeySet.this) { + lastRefreshFailure = e; + refreshInProgress = false; + SelfRefreshingKeySet.this.notifyAll(); + } + log.warn("KeySetProvider threw error", e); + } finally { + if (!recentRefresh) { + recentRefreshCount = 0; + refreshTime = System.currentTimeMillis(); + } + } + + } + }); + + try { + wait(requestTimeoutMs); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.debug(e.toString()); + } + + JsonWebKey result = getKeySimple(kid); + + if (result != null) { + return result; + } + + if (refreshInProgress && currentRefreshCount == refreshCount) { + if (!future.isDone()) { + future.cancel(true); + } + + lastRefreshFailure = new AuthenticatorUnavailableException("Authentication backend timed out"); + + throw new AuthenticatorUnavailableException("Authentication backend timed out"); + } + + if (lastRefreshFailure != null) { + throw new AuthenticatorUnavailableException("Authentication backend failed", lastRefreshFailure); + } + + return null; + + } catch (RejectedExecutionException e) { + throw new AuthenticatorUnavailableException( + "Did not try to call authentication backend because of " + threadPoolExecutor.getActiveCount() + " pending threads", + e + ); + } finally { + if (refreshInProgress && currentRefreshCount == refreshCount) { + refreshInProgress = false; + notifyAll(); + } + } + } + + public int getRequestTimeoutMs() { + return requestTimeoutMs; + } + + public void setRequestTimeoutMs(int requestTimeoutMs) { + this.requestTimeoutMs = requestTimeoutMs; + } + + public int getQueuedThreadTimeoutMs() { + return queuedThreadTimeoutMs; + } + + public void setQueuedThreadTimeoutMs(int queuedThreadTimeoutMs) { + this.queuedThreadTimeoutMs = queuedThreadTimeoutMs; + } + + public long getRefreshCount() { + return refreshCount; + } + + public long getQueuedGetCount() { + return queuedGetCount; + } + + public int getRefreshRateLimitTimeWindowMs() { + return refreshRateLimitTimeWindowMs; + } + + public void setRefreshRateLimitTimeWindowMs(int refreshRateLimitTimeWindowMs) { + this.refreshRateLimitTimeWindowMs = refreshRateLimitTimeWindowMs; + } + + public int getRefreshRateLimitCount() { + return refreshRateLimitCount; + } + + public void setRefreshRateLimitCount(int refreshRateLimitCount) { + this.refreshRateLimitCount = refreshRateLimitCount; + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/jwt/oidc/json/OpenIdProviderConfiguration.java b/src/main/java/com/amazon/dlic/auth/http/jwt/oidc/json/OpenIdProviderConfiguration.java index 58a4310a2d..3bcfb796b0 100644 --- a/src/main/java/com/amazon/dlic/auth/http/jwt/oidc/json/OpenIdProviderConfiguration.java +++ b/src/main/java/com/amazon/dlic/auth/http/jwt/oidc/json/OpenIdProviderConfiguration.java @@ -17,15 +17,15 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class OpenIdProviderConfiguration { - @JsonProperty("jwks_uri") - private String jwksUri; + @JsonProperty("jwks_uri") + private String jwksUri; - public String getJwksUri() { - return jwksUri; - } + public String getJwksUri() { + return jwksUri; + } - public void setJwksUri(String jwksUri) { - this.jwksUri = jwksUri; - } + public void setJwksUri(String jwksUri) { + this.jwksUri = jwksUri; + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java index 15aff90f1a..d8e11960d6 100644 --- a/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/kerberos/HTTPSpnegoAuthenticator.java @@ -58,7 +58,7 @@ public class HTTPSpnegoAuthenticator implements HTTPAuthenticator { private static final String EMPTY_STRING = ""; - private static final Oid[] KRB_OIDS = new Oid[] {KrbConstants.SPNEGO, KrbConstants.KRB5MECH}; + private static final Oid[] KRB_OIDS = new Oid[] { KrbConstants.SPNEGO, KrbConstants.KRB5MECH }; protected final Logger log = LogManager.getLogger(this.getClass()); @@ -98,17 +98,17 @@ public Void run() { } } catch (Throwable e) { log.error("Unable to enable krb_debug due to ", e); - System.err.println("Unable to enable krb_debug due to "+ExceptionsHelper.stackTrace(e)); - System.out.println("Unable to enable krb_debug due to "+ExceptionsHelper.stackTrace(e)); + System.err.println("Unable to enable krb_debug due to " + ExceptionsHelper.stackTrace(e)); + System.out.println("Unable to enable krb_debug due to " + ExceptionsHelper.stackTrace(e)); } System.setProperty(KrbConstants.USE_SUBJECT_CREDS_ONLY_PROP, "false"); String krb5Path = krb5PathSetting; - if(!Strings.isNullOrEmpty(krb5Path)) { + if (!Strings.isNullOrEmpty(krb5Path)) { - if(Paths.get(krb5Path).isAbsolute()) { + if (Paths.get(krb5Path).isAbsolute()) { log.debug("krb5_filepath: {}", krb5Path); System.setProperty(KrbConstants.KRB5_CONF_PROP, krb5Path); } else { @@ -118,29 +118,36 @@ public Void run() { System.setProperty(KrbConstants.KRB5_CONF_PROP, krb5Path); } else { - if(Strings.isNullOrEmpty(System.getProperty(KrbConstants.KRB5_CONF_PROP))) { + if (Strings.isNullOrEmpty(System.getProperty(KrbConstants.KRB5_CONF_PROP))) { System.setProperty(KrbConstants.KRB5_CONF_PROP, "/etc/krb5.conf"); log.debug("krb5_filepath (was not set or configured, set to default): /etc/krb5.conf"); } } stripRealmFromPrincipalName = settings.getAsBoolean("strip_realm_from_principal", true); - acceptorPrincipal = new HashSet<>(settings.getAsList("plugins.security.kerberos.acceptor_principal", Collections.emptyList())); + acceptorPrincipal = new HashSet<>( + settings.getAsList("plugins.security.kerberos.acceptor_principal", Collections.emptyList()) + ); final String _acceptorKeyTabPath = settings.get("plugins.security.kerberos.acceptor_keytab_filepath"); - if(acceptorPrincipal == null || acceptorPrincipal.size() == 0) { + if (acceptorPrincipal == null || acceptorPrincipal.size() == 0) { log.error("acceptor_principal must not be null or empty. Kerberos authentication will not work"); acceptorPrincipal = null; } - if(_acceptorKeyTabPath == null || _acceptorKeyTabPath.length() == 0) { - log.error("plugins.security.kerberos.acceptor_keytab_filepath must not be null or empty. Kerberos authentication will not work"); + if (_acceptorKeyTabPath == null || _acceptorKeyTabPath.length() == 0) { + log.error( + "plugins.security.kerberos.acceptor_keytab_filepath must not be null or empty. Kerberos authentication will not work" + ); acceptorKeyTabPath = null; } else { acceptorKeyTabPath = configDir.resolve(settings.get("plugins.security.kerberos.acceptor_keytab_filepath")); - if(!Files.exists(acceptorKeyTabPath)) { - log.error("Unable to read keytab from {} - Maybe the file does not exist or is not readable. Kerberos authentication will not work", acceptorKeyTabPath); + if (!Files.exists(acceptorKeyTabPath)) { + log.error( + "Unable to read keytab from {} - Maybe the file does not exist or is not readable. Kerberos authentication will not work", + acceptorKeyTabPath + ); acceptorKeyTabPath = null; } } @@ -155,7 +162,9 @@ public Void run() { } catch (Throwable e) { log.error("Cannot construct HTTPSpnegoAuthenticator due to {}", e.getMessage(), e); - log.error("Please make sure you configured 'plugins.security.kerberos.acceptor_keytab_filepath' realtive to the ES config/ dir!"); + log.error( + "Please make sure you configured 'plugins.security.kerberos.acceptor_keytab_filepath' realtive to the ES config/ dir!" + ); throw e; } @@ -252,11 +261,13 @@ public GSSCredential run() throws GSSException { return new AuthCredentials("_incomplete_", (Object) outToken); } - final String username = ((SimpleUserPrincipal) principal).getName(); - if(username == null || username.length() == 0) { - log.error("Got empty or null user from kerberos. Normally this means that you acceptor principal {} does not match the server hostname", acceptorPrincipal); + if (username == null || username.length() == 0) { + log.error( + "Got empty or null user from kerberos. Normally this means that you acceptor principal {} does not match the server hostname", + acceptorPrincipal + ); } return new AuthCredentials(username, (Object) outToken).markComplete(); @@ -272,19 +283,22 @@ public GSSCredential run() throws GSSException { @Override public boolean reRequestAuthentication(final RestChannel channel, AuthCredentials creds) { - final BytesRestResponse wwwAuthenticateResponse; - XContentBuilder response = getNegotiateResponseBody(); + final BytesRestResponse wwwAuthenticateResponse; + XContentBuilder response = getNegotiateResponseBody(); - if (response != null) { - wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED, response); + if (response != null) { + wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED, response); } else { - wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED, EMPTY_STRING); + wwwAuthenticateResponse = new BytesRestResponse(RestStatus.UNAUTHORIZED, EMPTY_STRING); } - if(creds == null || creds.getNativeCredentials() == null) { + if (creds == null || creds.getNativeCredentials() == null) { wwwAuthenticateResponse.addHeader("WWW-Authenticate", "Negotiate"); } else { - wwwAuthenticateResponse.addHeader("WWW-Authenticate", "Negotiate "+Base64.getEncoder().encodeToString((byte[]) creds.getNativeCredentials())); + wwwAuthenticateResponse.addHeader( + "WWW-Authenticate", + "Negotiate " + Base64.getEncoder().encodeToString((byte[]) creds.getNativeCredentials()) + ); } channel.sendResponse(wwwAuthenticateResponse); return true; @@ -298,7 +312,7 @@ public String getType() { /** * This class gets a gss credential via a privileged action. */ - //borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ + // borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ private static class AcceptAction implements PrivilegedExceptionAction { GSSContext gssContext; @@ -316,7 +330,7 @@ public byte[] run() throws GSSException { } } - //borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ + // borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ private static class AuthenticateAction implements PrivilegedAction { private final Logger logger; @@ -336,7 +350,7 @@ public Principal run() { } } - //borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ + // borrowed from Apache Tomcat 8 http://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk/ private static String getUsernameFromGSSContext(final GSSContext gssContext, final boolean strip, final Logger logger) { if (gssContext.isEstablished()) { GSSName gssName = null; @@ -359,26 +373,26 @@ private static String getUsernameFromGSSContext(final GSSContext gssContext, fin return null; } - private XContentBuilder getNegotiateResponseBody() { - try { - XContentBuilder negotiateResponseBody = XContentFactory.jsonBuilder(); - negotiateResponseBody.startObject(); - negotiateResponseBody.field("error"); - negotiateResponseBody.startObject(); - negotiateResponseBody.field("header"); - negotiateResponseBody.startObject(); - negotiateResponseBody.field("WWW-Authenticate", "Negotiate"); - negotiateResponseBody.endObject(); - negotiateResponseBody.endObject(); - negotiateResponseBody.endObject(); - return negotiateResponseBody; - } catch (Exception ex) { - log.error("Can't construct response body", ex); - return null; - } - } - - private static String stripRealmName(String name, boolean strip){ + private XContentBuilder getNegotiateResponseBody() { + try { + XContentBuilder negotiateResponseBody = XContentFactory.jsonBuilder(); + negotiateResponseBody.startObject(); + negotiateResponseBody.field("error"); + negotiateResponseBody.startObject(); + negotiateResponseBody.field("header"); + negotiateResponseBody.startObject(); + negotiateResponseBody.field("WWW-Authenticate", "Negotiate"); + negotiateResponseBody.endObject(); + negotiateResponseBody.endObject(); + negotiateResponseBody.endObject(); + return negotiateResponseBody; + } catch (Exception ex) { + log.error("Can't construct response body", ex); + return null; + } + } + + private static String stripRealmName(String name, boolean strip) { if (strip && name != null) { final int i = name.indexOf('@'); if (i > 0) { diff --git a/src/main/java/com/amazon/dlic/auth/http/kerberos/util/JaasKrbUtil.java b/src/main/java/com/amazon/dlic/auth/http/kerberos/util/JaasKrbUtil.java index 6574728da4..619c780027 100644 --- a/src/main/java/com/amazon/dlic/auth/http/kerberos/util/JaasKrbUtil.java +++ b/src/main/java/com/amazon/dlic/auth/http/kerberos/util/JaasKrbUtil.java @@ -38,177 +38,177 @@ */ public final class JaasKrbUtil { - private static boolean debug = false; - - private JaasKrbUtil() { - } - - public static void setDebug(final boolean debug) { - JaasKrbUtil.debug = debug; - } - - public static Subject loginUsingPassword(final String principal, final String password) throws LoginException { - final Set principals = new HashSet(); - principals.add(new KerberosPrincipal(principal)); - - final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); - - final Configuration conf = usePassword(principal); - final String confName = "PasswordConf"; - final CallbackHandler callback = new KrbCallbackHandler(principal, password); - final LoginContext loginContext = new LoginContext(confName, subject, callback, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Subject loginUsingTicketCache(final String principal, final Path cachePath) throws LoginException { - final Set principals = new HashSet(); - principals.add(new KerberosPrincipal(principal)); - - final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); - - final Configuration conf = useTicketCache(principal, cachePath); - final String confName = "TicketCacheConf"; - final LoginContext loginContext = new LoginContext(confName, subject, null, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Subject loginUsingKeytab(final Set principalAsStrings, final Path keytabPath, final boolean initiator) throws LoginException { - final Set principals = new HashSet(); - - for(String p: principalAsStrings) { - principals.add(new KerberosPrincipal(p)); - } - - - final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); - - final Configuration conf = useKeytab("*", keytabPath, initiator); - final String confName = "KeytabConf"; - final LoginContext loginContext = new LoginContext(confName, subject, null, conf); - loginContext.login(); - return loginContext.getSubject(); - } - - public static Configuration usePassword(final String principal) { - return new PasswordJaasConf(principal); - } - - public static Configuration useTicketCache(final String principal, final Path credentialPath) { - return new TicketCacheJaasConf(principal, credentialPath); - } - - public static Configuration useKeytab(final String principal, final Path keytabPath, final boolean initiator) { - return new KeytabJaasConf(principal, keytabPath, initiator); - } - - private static String getKrb5LoginModuleName() { - return System.getProperty("java.vendor").contains("IBM") ? "com.ibm.security.auth.module.Krb5LoginModule" - : "com.sun.security.auth.module.Krb5LoginModule"; - } - - static class KeytabJaasConf extends Configuration { - private final String principal; - private final Path keytabPath; - private final boolean initiator; - - public KeytabJaasConf(final String principal, final Path keytab, final boolean initiator) { - this.principal = principal; - this.keytabPath = keytab; - this.initiator = initiator; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { - final Map options = new HashMap(); - options.put("keyTab", keytabPath.toAbsolutePath().toString()); - options.put("principal", principal); - options.put("useKeyTab", "true"); - options.put("storeKey", "true"); - options.put("doNotPrompt", "true"); - options.put("renewTGT", "false"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", String.valueOf(initiator)); - options.put("debug", String.valueOf(debug)); - - return new AppConfigurationEntry[] { new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; - } - } - - static class TicketCacheJaasConf extends Configuration { - private final String principal; - private final Path clientCredentialPath; - - public TicketCacheJaasConf(final String principal, final Path clientCredentialPath) { - this.principal = principal; - this.clientCredentialPath = clientCredentialPath; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { - final Map options = new HashMap(); - options.put("principal", principal); - options.put("storeKey", "false"); - options.put("doNotPrompt", "false"); - options.put("useTicketCache", "true"); - options.put("renewTGT", "true"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", "true"); - options.put("ticketCache", clientCredentialPath.toAbsolutePath().toString()); - options.put("debug", String.valueOf(debug)); - - return new AppConfigurationEntry[] { new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; - } - } - - static class PasswordJaasConf extends Configuration { - private final String principal; - - public PasswordJaasConf(final String principal) { - this.principal = principal; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { - final Map options = new HashMap<>(); - options.put("principal", principal); - options.put("storeKey", "true"); - options.put("useTicketCache", "true"); - options.put("useKeyTab", "false"); - options.put("renewTGT", "true"); - options.put("refreshKrb5Config", "true"); - options.put("isInitiator", "true"); - options.put("debug", String.valueOf(debug)); - - return new AppConfigurationEntry[] { new AppConfigurationEntry(getKrb5LoginModuleName(), - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; - } - } - - public static class KrbCallbackHandler implements CallbackHandler { - private final String principal; - private final String password; - - public KrbCallbackHandler(final String principal, final String password) { - this.principal = principal; - this.password = password; - } - - @Override - public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (int i = 0; i < callbacks.length; i++) { - if (callbacks[i] instanceof PasswordCallback) { - final PasswordCallback pc = (PasswordCallback) callbacks[i]; - if (pc.getPrompt().contains(principal)) { - pc.setPassword(password.toCharArray()); - break; - } - } - } - } - } + private static boolean debug = false; + + private JaasKrbUtil() {} + + public static void setDebug(final boolean debug) { + JaasKrbUtil.debug = debug; + } + + public static Subject loginUsingPassword(final String principal, final String password) throws LoginException { + final Set principals = new HashSet(); + principals.add(new KerberosPrincipal(principal)); + + final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); + + final Configuration conf = usePassword(principal); + final String confName = "PasswordConf"; + final CallbackHandler callback = new KrbCallbackHandler(principal, password); + final LoginContext loginContext = new LoginContext(confName, subject, callback, conf); + loginContext.login(); + return loginContext.getSubject(); + } + + public static Subject loginUsingTicketCache(final String principal, final Path cachePath) throws LoginException { + final Set principals = new HashSet(); + principals.add(new KerberosPrincipal(principal)); + + final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); + + final Configuration conf = useTicketCache(principal, cachePath); + final String confName = "TicketCacheConf"; + final LoginContext loginContext = new LoginContext(confName, subject, null, conf); + loginContext.login(); + return loginContext.getSubject(); + } + + public static Subject loginUsingKeytab(final Set principalAsStrings, final Path keytabPath, final boolean initiator) + throws LoginException { + final Set principals = new HashSet(); + + for (String p : principalAsStrings) { + principals.add(new KerberosPrincipal(p)); + } + + final Subject subject = new Subject(false, principals, new HashSet(), new HashSet()); + + final Configuration conf = useKeytab("*", keytabPath, initiator); + final String confName = "KeytabConf"; + final LoginContext loginContext = new LoginContext(confName, subject, null, conf); + loginContext.login(); + return loginContext.getSubject(); + } + + public static Configuration usePassword(final String principal) { + return new PasswordJaasConf(principal); + } + + public static Configuration useTicketCache(final String principal, final Path credentialPath) { + return new TicketCacheJaasConf(principal, credentialPath); + } + + public static Configuration useKeytab(final String principal, final Path keytabPath, final boolean initiator) { + return new KeytabJaasConf(principal, keytabPath, initiator); + } + + private static String getKrb5LoginModuleName() { + return System.getProperty("java.vendor").contains("IBM") + ? "com.ibm.security.auth.module.Krb5LoginModule" + : "com.sun.security.auth.module.Krb5LoginModule"; + } + + static class KeytabJaasConf extends Configuration { + private final String principal; + private final Path keytabPath; + private final boolean initiator; + + public KeytabJaasConf(final String principal, final Path keytab, final boolean initiator) { + this.principal = principal; + this.keytabPath = keytab; + this.initiator = initiator; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { + final Map options = new HashMap(); + options.put("keyTab", keytabPath.toAbsolutePath().toString()); + options.put("principal", principal); + options.put("useKeyTab", "true"); + options.put("storeKey", "true"); + options.put("doNotPrompt", "true"); + options.put("renewTGT", "false"); + options.put("refreshKrb5Config", "true"); + options.put("isInitiator", String.valueOf(initiator)); + options.put("debug", String.valueOf(debug)); + + return new AppConfigurationEntry[] { + new AppConfigurationEntry(getKrb5LoginModuleName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; + } + } + + static class TicketCacheJaasConf extends Configuration { + private final String principal; + private final Path clientCredentialPath; + + public TicketCacheJaasConf(final String principal, final Path clientCredentialPath) { + this.principal = principal; + this.clientCredentialPath = clientCredentialPath; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { + final Map options = new HashMap(); + options.put("principal", principal); + options.put("storeKey", "false"); + options.put("doNotPrompt", "false"); + options.put("useTicketCache", "true"); + options.put("renewTGT", "true"); + options.put("refreshKrb5Config", "true"); + options.put("isInitiator", "true"); + options.put("ticketCache", clientCredentialPath.toAbsolutePath().toString()); + options.put("debug", String.valueOf(debug)); + + return new AppConfigurationEntry[] { + new AppConfigurationEntry(getKrb5LoginModuleName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; + } + } + + static class PasswordJaasConf extends Configuration { + private final String principal; + + public PasswordJaasConf(final String principal) { + this.principal = principal; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(final String name) { + final Map options = new HashMap<>(); + options.put("principal", principal); + options.put("storeKey", "true"); + options.put("useTicketCache", "true"); + options.put("useKeyTab", "false"); + options.put("renewTGT", "true"); + options.put("refreshKrb5Config", "true"); + options.put("isInitiator", "true"); + options.put("debug", String.valueOf(debug)); + + return new AppConfigurationEntry[] { + new AppConfigurationEntry(getKrb5LoginModuleName(), AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options) }; + } + } + + public static class KrbCallbackHandler implements CallbackHandler { + private final String principal; + private final String password; + + public KrbCallbackHandler(final String principal, final String password) { + this.principal = principal; + this.password = password; + } + + @Override + public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof PasswordCallback) { + final PasswordCallback pc = (PasswordCallback) callbacks[i]; + if (pc.getPrompt().contains(principal)) { + pc.setPassword(password.toCharArray()); + break; + } + } + } + } + } } diff --git a/src/main/java/com/amazon/dlic/auth/http/kerberos/util/KrbConstants.java b/src/main/java/com/amazon/dlic/auth/http/kerberos/util/KrbConstants.java index 801ca78e27..a8a57633dc 100644 --- a/src/main/java/com/amazon/dlic/auth/http/kerberos/util/KrbConstants.java +++ b/src/main/java/com/amazon/dlic/auth/http/kerberos/util/KrbConstants.java @@ -16,28 +16,27 @@ public final class KrbConstants { - static { - Oid spnegoTmp = null; - Oid krbTmp = null; - try { - spnegoTmp = new Oid("1.3.6.1.5.5.2"); - krbTmp = new Oid("1.2.840.113554.1.2.2"); - } catch (final GSSException e) { - - } - SPNEGO = spnegoTmp; - KRB5MECH = krbTmp; - } - - public static final Oid SPNEGO; - public static final Oid KRB5MECH; - public static final String KRB5_CONF_PROP = "java.security.krb5.conf"; - public static final String JAAS_LOGIN_CONF_PROP = "java.security.auth.login.config"; - public static final String USE_SUBJECT_CREDS_ONLY_PROP = "javax.security.auth.useSubjectCredsOnly"; - public static final String NEGOTIATE = "Negotiate"; - public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - - private KrbConstants() { - } + static { + Oid spnegoTmp = null; + Oid krbTmp = null; + try { + spnegoTmp = new Oid("1.3.6.1.5.5.2"); + krbTmp = new Oid("1.2.840.113554.1.2.2"); + } catch (final GSSException e) { + + } + SPNEGO = spnegoTmp; + KRB5MECH = krbTmp; + } + + public static final Oid SPNEGO; + public static final Oid KRB5MECH; + public static final String KRB5_CONF_PROP = "java.security.krb5.conf"; + public static final String JAAS_LOGIN_CONF_PROP = "java.security.auth.login.config"; + public static final String USE_SUBJECT_CREDS_ONLY_PROP = "javax.security.auth.useSubjectCredsOnly"; + public static final String NEGOTIATE = "Negotiate"; + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + + private KrbConstants() {} } diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java b/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java index 4ab5673adb..1c49d10b2e 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/AuthTokenProcessorHandler.java @@ -83,8 +83,7 @@ class AuthTokenProcessorHandler { private JsonMapObjectReaderWriter jsonMapReaderWriter = new JsonMapObjectReaderWriter(); private Pattern samlRolesSeparatorPattern; - AuthTokenProcessorHandler(Settings settings, Settings jwtSettings, Saml2SettingsProvider saml2SettingsProvider) - throws Exception { + AuthTokenProcessorHandler(Settings settings, Settings jwtSettings, Saml2SettingsProvider saml2SettingsProvider) throws Exception { this.saml2SettingsProvider = saml2SettingsProvider; this.jwtRolesKey = jwtSettings.get("roles_key", "roles"); @@ -133,8 +132,8 @@ boolean handle(RestRequest restRequest, RestChannel restChannel) throws Exceptio return AccessController.doPrivileged(new PrivilegedExceptionAction() { @Override - public Boolean run() throws XPathExpressionException, SamlConfigException, IOException, - ParserConfigurationException, SAXException, SettingsException { + public Boolean run() throws XPathExpressionException, SamlConfigException, IOException, ParserConfigurationException, + SAXException, SettingsException { return handleLowLevel(restRequest, restChannel); } }); @@ -147,17 +146,23 @@ public Boolean run() throws XPathExpressionException, SamlConfigException, IOExc } } - private AuthTokenProcessorAction.Response handleImpl(RestRequest restRequest, RestChannel restChannel, - String samlResponseBase64, String samlRequestId, String acsEndpoint, Saml2Settings saml2Settings) - throws XPathExpressionException, ParserConfigurationException, SAXException, IOException, - SettingsException { + private AuthTokenProcessorAction.Response handleImpl( + RestRequest restRequest, + RestChannel restChannel, + String samlResponseBase64, + String samlRequestId, + String acsEndpoint, + Saml2Settings saml2Settings + ) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException, SettingsException { if (token_log.isDebugEnabled()) { try { - token_log.debug("SAMLResponse for {}\n{}", samlRequestId, new String(Util.base64decoder(samlResponseBase64), StandardCharsets.UTF_8)); + token_log.debug( + "SAMLResponse for {}\n{}", + samlRequestId, + new String(Util.base64decoder(samlResponseBase64), StandardCharsets.UTF_8) + ); } catch (Exception e) { - token_log.warn( - "SAMLResponse for {} cannot be decoded from base64\n{}", - samlRequestId, samlResponseBase64, e); + token_log.warn("SAMLResponse for {} cannot be decoded from base64\n{}", samlRequestId, samlResponseBase64, e); } } @@ -185,20 +190,23 @@ private AuthTokenProcessorAction.Response handleImpl(RestRequest restRequest, Re } } - private boolean handleLowLevel(RestRequest restRequest, RestChannel restChannel) throws SamlConfigException, - IOException, XPathExpressionException, ParserConfigurationException, SAXException, SettingsException { + private boolean handleLowLevel(RestRequest restRequest, RestChannel restChannel) throws SamlConfigException, IOException, + XPathExpressionException, ParserConfigurationException, SAXException, SettingsException { try { if (restRequest.getXContentType() != XContentType.JSON) { throw new OpenSearchSecurityException( - "/_opendistro/_security/api/authtoken expects content with type application/json", - RestStatus.UNSUPPORTED_MEDIA_TYPE); + "/_opendistro/_security/api/authtoken expects content with type application/json", + RestStatus.UNSUPPORTED_MEDIA_TYPE + ); } if (restRequest.method() != Method.POST) { - throw new OpenSearchSecurityException("/_opendistro/_security/api/authtoken expects POST requests", - RestStatus.METHOD_NOT_ALLOWED); + throw new OpenSearchSecurityException( + "/_opendistro/_security/api/authtoken expects POST requests", + RestStatus.METHOD_NOT_ALLOWED + ); } Saml2Settings saml2Settings = this.saml2SettingsProvider.getCached(); @@ -214,24 +222,28 @@ private boolean handleLowLevel(RestRequest restRequest, RestChannel restChannel) if (((ObjectNode) jsonRoot).get("SAMLResponse") == null) { log.warn("SAMLResponse is missing from request "); - throw new OpenSearchSecurityException("SAMLResponse is missing from request", - RestStatus.BAD_REQUEST); + throw new OpenSearchSecurityException("SAMLResponse is missing from request", RestStatus.BAD_REQUEST); } String samlResponseBase64 = ((ObjectNode) jsonRoot).get("SAMLResponse").asText(); String samlRequestId = ((ObjectNode) jsonRoot).get("RequestId") != null - ? ((ObjectNode) jsonRoot).get("RequestId").textValue() - : null; + ? ((ObjectNode) jsonRoot).get("RequestId").textValue() + : null; String acsEndpoint = saml2Settings.getSpAssertionConsumerServiceUrl().toString(); - if (((ObjectNode) jsonRoot).get("acsEndpoint") != null - && ((ObjectNode) jsonRoot).get("acsEndpoint").textValue() != null) { + if (((ObjectNode) jsonRoot).get("acsEndpoint") != null && ((ObjectNode) jsonRoot).get("acsEndpoint").textValue() != null) { acsEndpoint = getAbsoluteAcsEndpoint(((ObjectNode) jsonRoot).get("acsEndpoint").textValue()); } - AuthTokenProcessorAction.Response responseBody = this.handleImpl(restRequest, restChannel, - samlResponseBase64, samlRequestId, acsEndpoint, saml2Settings); + AuthTokenProcessorAction.Response responseBody = this.handleImpl( + restRequest, + restChannel, + samlResponseBase64, + samlRequestId, + acsEndpoint, + saml2Settings + ); if (responseBody == null) { return false; @@ -239,16 +251,14 @@ private boolean handleLowLevel(RestRequest restRequest, RestChannel restChannel) String responseBodyString = DefaultObjectMapper.objectMapper.writeValueAsString(responseBody); - BytesRestResponse authenticateResponse = new BytesRestResponse(RestStatus.OK, "application/json", - responseBodyString); + BytesRestResponse authenticateResponse = new BytesRestResponse(RestStatus.OK, "application/json", responseBodyString); restChannel.sendResponse(authenticateResponse); return true; } catch (JsonProcessingException e) { log.warn("Error while parsing JSON for /_opendistro/_security/api/authtoken", e); - BytesRestResponse authenticateResponse = new BytesRestResponse(RestStatus.BAD_REQUEST, - "JSON could not be parsed"); + BytesRestResponse authenticateResponse = new BytesRestResponse(RestStatus.BAD_REQUEST, "JSON could not be parsed"); restChannel.sendResponse(authenticateResponse); return true; } @@ -274,7 +284,8 @@ JsonWebKey createJwkFromSettings(Settings settings, Settings jwtSettings) throws if (jwkSettings.isEmpty()) { throw new Exception( - "Settings for key exchange missing. Please specify at least the option exchange_key with a shared secret."); + "Settings for key exchange missing. Please specify at least the option exchange_key with a shared secret." + ); } JsonWebKey jwk = new JsonWebKey(); @@ -319,8 +330,14 @@ private String createJwt(SamlResponse samlResponse) throws Exception { String encodedJwt = this.jwtProducer.processJwt(jwt); if (token_log.isDebugEnabled()) { - token_log.debug("Created JWT: " + encodedJwt + "\n" + jsonMapReaderWriter.toJson(jwt.getJwsHeaders()) + "\n" - + JwtUtils.claimsToJson(jwt.getClaims())); + token_log.debug( + "Created JWT: " + + encodedJwt + + "\n" + + jsonMapReaderWriter.toJson(jwt.getJwsHeaders()) + + "\n" + + JwtUtils.claimsToJson(jwt.getClaims()) + ); } return encodedJwt; @@ -335,8 +352,7 @@ private long getJwtExpiration(SamlResponse samlResponse) throws Exception { if (sessionNotOnOrAfter != null) { return sessionNotOnOrAfter.getMillis() / 1000 + this.expiryOffset; } else { - throw new Exception( - "Error while determining JWT expiration time: SamlResponse did not contain sessionNotOnOrAfter value"); + throw new Exception("Error while determining JWT expiration time: SamlResponse did not contain sessionNotOnOrAfter value"); } } else { // AUTO @@ -419,9 +435,9 @@ private String[] extractRoles(SamlResponse samlResponse) throws XPathExpressionE private List splitRoles(List values) { return values.stream() - .flatMap(v -> samlRolesSeparatorPattern.splitAsStream(v)) - .filter(r -> !Strings.isNullOrEmpty(r)) - .collect(Collectors.toList()); + .flatMap(v -> samlRolesSeparatorPattern.splitAsStream(v)) + .filter(r -> !Strings.isNullOrEmpty(r)) + .collect(Collectors.toList()); } private String getAbsoluteAcsEndpoint(String acsEndpoint) { @@ -440,7 +456,9 @@ private String getAbsoluteAcsEndpoint(String acsEndpoint) { } private enum ExpiryBaseValue { - AUTO, NOW, SESSION + AUTO, + NOW, + SESSION } public JsonWebKey getSigningKey() { diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java index 7015017fc7..d3068b852a 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticator.java @@ -68,7 +68,6 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX; import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; - public class HTTPSamlAuthenticator implements HTTPAuthenticator, Destroyable { protected final static Logger log = LogManager.getLogger(HTTPSamlAuthenticator.class); @@ -78,9 +77,8 @@ public class HTTPSamlAuthenticator implements HTTPAuthenticator, Destroyable { private static final String API_AUTHTOKEN_SUFFIX = "api/authtoken"; private static final String AUTHINFO_SUFFIX = "authinfo"; - private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" +"(.*)"; - private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX); - + private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)"; + private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX); private static boolean openSamlInitialized = false; @@ -132,13 +130,15 @@ public HTTPSamlAuthenticator(final Settings settings, final Path configPath) { try { this.saml2SettingsProvider.getCached(); } catch (Exception e) { - log.debug("Exception while initializing Saml2SettingsProvider. Possibly, the IdP is unreachable right now. This is recoverable by a meta data refresh.", e); + log.debug( + "Exception while initializing Saml2SettingsProvider. Possibly, the IdP is unreachable right now. This is recoverable by a meta data refresh.", + e + ); } this.jwtSettings = this.createJwtAuthenticatorSettings(settings); - this.authTokenProcessorHandler = new AuthTokenProcessorHandler(settings, jwtSettings, - this.saml2SettingsProvider); + this.authTokenProcessorHandler = new AuthTokenProcessorHandler(settings, jwtSettings, this.saml2SettingsProvider); this.httpJwtAuthenticator = new HTTPJwtAuthenticator(this.jwtSettings, configPath); @@ -149,8 +149,7 @@ public HTTPSamlAuthenticator(final Settings settings, final Path configPath) { } @Override - public AuthCredentials extractCredentials(RestRequest restRequest, ThreadContext threadContext) - throws OpenSearchSecurityException { + public AuthCredentials extractCredentials(RestRequest restRequest, ThreadContext threadContext) throws OpenSearchSecurityException { Matcher matcher = PATTERN_PATH_PREFIX.matcher(restRequest.path()); final String suffix = matcher.matches() ? matcher.group(2) : null; if (API_AUTHTOKEN_SUFFIX.equals(suffix)) { @@ -177,8 +176,7 @@ public boolean reRequestAuthentication(RestChannel restChannel, AuthCredentials RestRequest restRequest = restChannel.request(); Matcher matcher = PATTERN_PATH_PREFIX.matcher(restRequest.path()); final String suffix = matcher.matches() ? matcher.group(2) : null; - if (API_AUTHTOKEN_SUFFIX.equals(suffix) - && this.authTokenProcessorHandler.handle(restRequest, restChannel)){ + if (API_AUTHTOKEN_SUFFIX.equals(suffix) && this.authTokenProcessorHandler.handle(restRequest, restChannel)) { return true; } @@ -200,9 +198,12 @@ private String getWwwAuthenticateHeader(Saml2Settings saml2Settings) throws Exce AuthnRequest authnRequest = this.buildAuthnRequest(saml2Settings); return "X-Security-IdP realm=\"OpenSearch Security\" location=\"" - + StringEscapeUtils.escapeJava(getSamlRequestRedirectBindingLocation(IdpEndpointType.SSO, saml2Settings, - authnRequest.getEncodedAuthnRequest(true))) - + "\" requestId=\"" + StringEscapeUtils.escapeJava(authnRequest.getId()) + "\""; + + StringEscapeUtils.escapeJava( + getSamlRequestRedirectBindingLocation(IdpEndpointType.SSO, saml2Settings, authnRequest.getEncodedAuthnRequest(true)) + ) + + "\" requestId=\"" + + StringEscapeUtils.escapeJava(authnRequest.getId()) + + "\""; } private AuthnRequest buildAuthnRequest(Saml2Settings saml2Settings) { @@ -221,12 +222,16 @@ private AuthnRequest buildAuthnRequest(Saml2Settings saml2Settings) { private PrivateKey getSpSignaturePrivateKey(Settings settings, Path configPath) throws Exception { try { - PrivateKey result = PemKeyReader.loadKeyFromStream(settings.get("sp.signature_private_key_password"), - PemKeyReader.resolveStream("sp.signature_private_key", settings)); + PrivateKey result = PemKeyReader.loadKeyFromStream( + settings.get("sp.signature_private_key_password"), + PemKeyReader.resolveStream("sp.signature_private_key", settings) + ); if (result == null) { - result = PemKeyReader.loadKeyFromFile(settings.get("sp.signature_private_key_password"), - PemKeyReader.resolve("sp.signature_private_key_filepath", settings, configPath, false)); + result = PemKeyReader.loadKeyFromFile( + settings.get("sp.signature_private_key_password"), + PemKeyReader.resolve("sp.signature_private_key_filepath", settings, configPath, false) + ); } return result; @@ -297,8 +302,7 @@ public Void run() throws InitializationException { } @SuppressWarnings("removal") - private MetadataResolver createMetadataResolver(final Settings settings, final Path configPath) - throws Exception { + private MetadataResolver createMetadataResolver(final Settings settings, final Path configPath) throws Exception { final AbstractMetadataResolver metadataResolver; final String idpMetadataUrl = settings.get(IDP_METADATA_URL); @@ -311,7 +315,9 @@ private MetadataResolver createMetadataResolver(final Settings settings, final P } else if (idpMetadataBody != null) { metadataResolver = new DOMMetadataResolver(getMetadataDOM(idpMetadataBody)); } else { - throw new Exception(String.format("One of %s, %s or %s must be configured", IDP_METADATA_URL, IDP_METADATA_FILE, IDP_METADATA_CONTENT)); + throw new Exception( + String.format("One of %s, %s or %s must be configured", IDP_METADATA_URL, IDP_METADATA_FILE, IDP_METADATA_CONTENT) + ); } metadataResolver.setId(HTTPSamlAuthenticator.class.getName() + "_" + (++resolverIdCounter)); @@ -378,14 +384,12 @@ String buildLogoutUrl(AuthCredentials authCredentials) { String nameIdClaim = this.subjectKey == null ? "sub" : "saml_ni"; String nameId = authCredentials.getAttributes().get("attr.jwt." + nameIdClaim); - String nameIdFormat = SamlNameIdFormat - .getByShortName(authCredentials.getAttributes().get("attr.jwt.saml_nif")).getUri(); + String nameIdFormat = SamlNameIdFormat.getByShortName(authCredentials.getAttributes().get("attr.jwt.saml_nif")).getUri(); String sessionIndex = authCredentials.getAttributes().get("attr.jwt.saml_si"); LogoutRequest logoutRequest = new LogoutRequest(saml2Settings, null, nameId, sessionIndex, nameIdFormat); - return getSamlRequestRedirectBindingLocation(IdpEndpointType.SLO, saml2Settings, - logoutRequest.getEncodedLogoutRequest(true)); + return getSamlRequestRedirectBindingLocation(IdpEndpointType.SLO, saml2Settings, logoutRequest.getEncodedLogoutRequest(true)); } catch (Exception e) { log.error("Error while creating logout URL. Logout will be not available", e); @@ -398,8 +402,8 @@ private void initLogoutUrl(RestRequest restRequest, ThreadContext threadContext, threadContext.putTransient(ConfigConstants.SSO_LOGOUT_URL, buildLogoutUrl(authCredentials)); } - private String getSamlRequestRedirectBindingLocation(IdpEndpointType idpEndpointType, Saml2Settings saml2Settings, - String samlRequest) throws Exception { + private String getSamlRequestRedirectBindingLocation(IdpEndpointType idpEndpointType, Saml2Settings saml2Settings, String samlRequest) + throws Exception { URL idpUrl = getIdpUrl(idpEndpointType, saml2Settings); @@ -417,8 +421,7 @@ private String getSamlRequestQueryString(String samlRequest) throws Exception { return "SAMLRequest=" + Util.urlEncoder(samlRequest); } - String queryString = "SAMLRequest=" + Util.urlEncoder(samlRequest) + "&SigAlg=" - + Util.urlEncoder(this.spSignatureAlgorithm); + String queryString = "SAMLRequest=" + Util.urlEncoder(samlRequest) + "&SigAlg=" + Util.urlEncoder(this.spSignatureAlgorithm); String signature = getSamlRequestQueryStringSignature(queryString); @@ -429,8 +432,7 @@ private String getSamlRequestQueryString(String samlRequest) throws Exception { private String getSamlRequestQueryStringSignature(String samlRequestQueryString) throws Exception { try { - return Util.base64encoder( - Util.sign(samlRequestQueryString, this.spSignaturePrivateKey, this.spSignatureAlgorithm)); + return Util.base64encoder(Util.sign(samlRequestQueryString, this.spSignaturePrivateKey, this.spSignatureAlgorithm)); } catch (Exception e) { throw new Exception("Error while signing SAML request", e); } @@ -462,8 +464,7 @@ protected KeyProvider initKeyProvider(Settings settings, Path configPath) throws return new KeyProvider() { @Override - public JsonWebKey getKeyAfterRefresh(String kid) - throws AuthenticatorUnavailableException, BadCredentialsException { + public JsonWebKey getKeyAfterRefresh(String kid) throws AuthenticatorUnavailableException, BadCredentialsException { return authTokenProcessorHandler.getSigningKey(); } @@ -477,6 +478,7 @@ public JsonWebKey getKey(String kid) throws AuthenticatorUnavailableException, B } private enum IdpEndpointType { - SSO, SLO + SSO, + SLO } } diff --git a/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java b/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java index 5274569502..881c9c3553 100644 --- a/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java +++ b/src/main/java/com/amazon/dlic/auth/http/saml/Saml2SettingsProvider.java @@ -68,19 +68,23 @@ Saml2Settings get() throws SamlConfigException { try { HashMap configProperties = new HashMap<>(); - EntityDescriptor entityDescriptor = this.metadataResolver - .resolveSingle(new CriteriaSet(new EntityIdCriterion(this.idpEntityId))); + EntityDescriptor entityDescriptor = this.metadataResolver.resolveSingle( + new CriteriaSet(new EntityIdCriterion(this.idpEntityId)) + ); if (entityDescriptor == null) { throw new SamlConfigException("Could not find entity descriptor for " + this.idpEntityId); } - IDPSSODescriptor idpSsoDescriptor = entityDescriptor - .getIDPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol"); + IDPSSODescriptor idpSsoDescriptor = entityDescriptor.getIDPSSODescriptor("urn:oasis:names:tc:SAML:2.0:protocol"); if (idpSsoDescriptor == null) { - throw new SamlConfigException("Could not find IDPSSODescriptor supporting SAML 2.0 in " - + this.idpEntityId + "; role descriptors: " + entityDescriptor.getRoleDescriptors()); + throw new SamlConfigException( + "Could not find IDPSSODescriptor supporting SAML 2.0 in " + + this.idpEntityId + + "; role descriptors: " + + entityDescriptor.getRoleDescriptors() + ); } initIdpEndpoints(idpSsoDescriptor, configProperties); @@ -121,8 +125,7 @@ Saml2Settings getCached() throws SamlConfigException { private boolean isUpdateRequired() { RefreshableMetadataResolver refreshableMetadataResolver = (RefreshableMetadataResolver) this.metadataResolver; - if (this.cachedSaml2Settings == null || this.metadataUpdateTime == null - || refreshableMetadataResolver.getLastUpdate() == null) { + if (this.cachedSaml2Settings == null || this.metadataUpdateTime == null || refreshableMetadataResolver.getLastUpdate() == null) { return true; } @@ -140,35 +143,39 @@ private void initMisc(HashMap configProperties) { } private void initSpEndpoints(HashMap configProperties) { - configProperties.put(SettingsBuilder.SP_ASSERTION_CONSUMER_SERVICE_URL_PROPERTY_KEY, - this.buildAssertionConsumerEndpoint(this.opensearchSettings.get("kibana_url"))); - configProperties.put(SettingsBuilder.SP_ASSERTION_CONSUMER_SERVICE_BINDING_PROPERTY_KEY, - "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"); + configProperties.put( + SettingsBuilder.SP_ASSERTION_CONSUMER_SERVICE_URL_PROPERTY_KEY, + this.buildAssertionConsumerEndpoint(this.opensearchSettings.get("kibana_url")) + ); + configProperties.put( + SettingsBuilder.SP_ASSERTION_CONSUMER_SERVICE_BINDING_PROPERTY_KEY, + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + ); configProperties.put(SettingsBuilder.SP_ENTITYID_PROPERTY_KEY, this.opensearchSettings.get("sp.entity_id")); } - private void initIdpEndpoints(IDPSSODescriptor idpSsoDescriptor, HashMap configProperties) - throws SamlConfigException { - SingleSignOnService singleSignOnService = this.findSingleSignOnService(idpSsoDescriptor, - "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"); + private void initIdpEndpoints(IDPSSODescriptor idpSsoDescriptor, HashMap configProperties) throws SamlConfigException { + SingleSignOnService singleSignOnService = this.findSingleSignOnService( + idpSsoDescriptor, + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + ); - configProperties.put(SettingsBuilder.IDP_SINGLE_SIGN_ON_SERVICE_URL_PROPERTY_KEY, - singleSignOnService.getLocation()); - configProperties.put(SettingsBuilder.IDP_SINGLE_SIGN_ON_SERVICE_BINDING_PROPERTY_KEY, - singleSignOnService.getBinding()); + configProperties.put(SettingsBuilder.IDP_SINGLE_SIGN_ON_SERVICE_URL_PROPERTY_KEY, singleSignOnService.getLocation()); + configProperties.put(SettingsBuilder.IDP_SINGLE_SIGN_ON_SERVICE_BINDING_PROPERTY_KEY, singleSignOnService.getBinding()); configProperties.put(SettingsBuilder.IDP_ENTITYID_PROPERTY_KEY, this.opensearchSettings.get("idp.entity_id")); - SingleLogoutService singleLogoutService = this.findSingleLogoutService(idpSsoDescriptor, - "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"); + SingleLogoutService singleLogoutService = this.findSingleLogoutService( + idpSsoDescriptor, + "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + ); if (singleLogoutService != null) { - configProperties.put(SettingsBuilder.IDP_SINGLE_LOGOUT_SERVICE_URL_PROPERTY_KEY, - singleLogoutService.getLocation()); - configProperties.put(SettingsBuilder.IDP_SINGLE_LOGOUT_SERVICE_BINDING_PROPERTY_KEY, - singleLogoutService.getBinding()); + configProperties.put(SettingsBuilder.IDP_SINGLE_LOGOUT_SERVICE_URL_PROPERTY_KEY, singleLogoutService.getLocation()); + configProperties.put(SettingsBuilder.IDP_SINGLE_LOGOUT_SERVICE_BINDING_PROPERTY_KEY, singleLogoutService.getBinding()); } else { log.warn( - "The IdP does not provide a Single Logout Service. In order to ensure that users have to re-enter their password after logging out, OpenSearch Security will issue all SAML authentication requests with a mandatory password input (ForceAuthn=true)"); + "The IdP does not provide a Single Logout Service. In order to ensure that users have to re-enter their password after logging out, OpenSearch Security will issue all SAML authentication requests with a mandatory password input (ForceAuthn=true)" + ); } } @@ -176,32 +183,32 @@ private void initIdpCerts(IDPSSODescriptor idpSsoDescriptor, HashMap extractLdapAttributes(String originalUsername, final LdapEntry userEntry, - int customAttrMaxValueLen, WildcardMatcher allowlistedCustomLdapAttrMatcher) { + + public static Map extractLdapAttributes( + String originalUsername, + final LdapEntry userEntry, + int customAttrMaxValueLen, + WildcardMatcher allowlistedCustomLdapAttrMatcher + ) { Map attributes = new HashMap<>(); attributes.put("ldap.original.username", originalUsername); attributes.put("ldap.dn", userEntry.getDn()); diff --git a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java index 1ce545e8da..96cd7a40c9 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthenticationBackend.java @@ -67,13 +67,16 @@ public LDAPAuthenticationBackend(final Settings settings, final Path configPath) this.settings = settings; this.configPath = configPath; this.userBaseSettings = getUserBaseSettings(settings); - this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())).toArray(new String[0]); + this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())) + .toArray(new String[0]); this.shouldFollowReferrals = settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT); customAttrMaxValueLen = settings.getAsInt(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 36); checkForDeprecatedSetting(settings, ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, ConfigConstants.LDAP_CUSTOM_ATTR_ALLOWLIST); - final List customAttrAllowList = settings.getAsList(ConfigConstants.LDAP_CUSTOM_ATTR_ALLOWLIST, settings.getAsList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, - Collections.singletonList("*"))); + final List customAttrAllowList = settings.getAsList( + ConfigConstants.LDAP_CUSTOM_ATTR_ALLOWLIST, + settings.getAsList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, Collections.singletonList("*")) + ); allowlistedCustomLdapAttrMatcher = WildcardMatcher.from(customAttrAllowList); } @@ -81,7 +84,7 @@ public LDAPAuthenticationBackend(final Settings settings, final Path configPath) public User authenticate(final AuthCredentials credentials) throws OpenSearchSecurityException { Connection ldapConnection = null; - final String user =credentials.getUsername(); + final String user = credentials.getUsername(); byte[] password = credentials.getPassword(); try { @@ -98,11 +101,12 @@ public User authenticate(final AuthCredentials credentials) throws OpenSearchSec // makes guessing if a user exists or not harder when looking on the // authentication delay time if (entry == null && settings.getAsBoolean(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, false)) { - String fakeLognDn = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_DN, - "CN=faketomakebindfail,DC=" + UUID.randomUUID().toString()); + String fakeLognDn = settings.get( + ConfigConstants.LDAP_FAKE_LOGIN_DN, + "CN=faketomakebindfail,DC=" + UUID.randomUUID().toString() + ); entry = new LdapEntry(fakeLognDn); - password = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_PASSWORD, "fakeLoginPwd123") - .getBytes(StandardCharsets.UTF_8); + password = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_PASSWORD, "fakeLoginPwd123").getBytes(StandardCharsets.UTF_8); } else if (entry == null) { throw new OpenSearchSecurityException("No user " + user + " found"); } @@ -166,15 +170,24 @@ public boolean exists(final User user) { try { ldapConnection = LDAPAuthorizationBackend.getConnection(settings, configPath); - LdapEntry userEntry = exists(userName, ldapConnection, settings, userBaseSettings, this.returnAttributes, this.shouldFollowReferrals); + LdapEntry userEntry = exists( + userName, + ldapConnection, + settings, + userBaseSettings, + this.returnAttributes, + this.shouldFollowReferrals + ); boolean exists = userEntry != null; - - if(exists) { - user.addAttributes(LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, allowlistedCustomLdapAttrMatcher)); + + if (exists) { + user.addAttributes( + LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, allowlistedCustomLdapAttrMatcher) + ); } - + return exists; - + } catch (final Exception e) { log.warn("User {} does not exist due to ", userName, e); return false; @@ -184,33 +197,39 @@ public boolean exists(final User user) { } static List> getUserBaseSettings(Settings settings) { - Map userBaseSettingsMap = new HashMap<>( - settings.getGroups(ConfigConstants.LDAP_AUTHCZ_USERS)); + Map userBaseSettingsMap = new HashMap<>(settings.getGroups(ConfigConstants.LDAP_AUTHCZ_USERS)); if (!userBaseSettingsMap.isEmpty()) { if (settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { throw new RuntimeException( - "Both old-style and new-style configuration defined for LDAP authentication backend: " - + settings); + "Both old-style and new-style configuration defined for LDAP authentication backend: " + settings + ); } return Utils.getOrderedBaseSettings(userBaseSettingsMap); } else { Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, - settings.get(ConfigConstants.LDAP_AUTHC_USERBASE, DEFAULT_USERBASE)); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, - settings.get(ConfigConstants.LDAP_AUTHC_USERSEARCH, DEFAULT_USERSEARCH_PATTERN)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, settings.get(ConfigConstants.LDAP_AUTHC_USERBASE, DEFAULT_USERBASE)); + settingsBuilder.put( + ConfigConstants.LDAP_AUTHCZ_SEARCH, + settings.get(ConfigConstants.LDAP_AUTHC_USERSEARCH, DEFAULT_USERSEARCH_PATTERN) + ); return Collections.singletonList(Pair.of("_legacyConfig", settingsBuilder.build())); } } - static LdapEntry exists(final String user, Connection ldapConnection, Settings settings, - List> userBaseSettings, String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + static LdapEntry exists( + final String user, + Connection ldapConnection, + Settings settings, + List> userBaseSettings, + String[] returnAttributes, + final boolean shouldFollowReferrals + ) throws Exception { if (settings.getAsBoolean(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, false) - || settings.getAsBoolean(ConfigConstants.LDAP_SEARCH_ALL_BASES, false) - || settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { + || settings.getAsBoolean(ConfigConstants.LDAP_SEARCH_ALL_BASES, false) + || settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { return existsSearchingAllBases(user, ldapConnection, userBaseSettings, returnAttributes, shouldFollowReferrals); } else { return existsSearchingUntilFirstHit(user, ldapConnection, userBaseSettings, returnAttributes, shouldFollowReferrals); @@ -218,8 +237,13 @@ static LdapEntry exists(final String user, Connection ldapConnection, Settings s } - private static LdapEntry existsSearchingUntilFirstHit(final String user, Connection ldapConnection, - List> userBaseSettings, final String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + private static LdapEntry existsSearchingUntilFirstHit( + final String user, + Connection ldapConnection, + List> userBaseSettings, + final String[] returnAttributes, + final boolean shouldFollowReferrals + ) throws Exception { final String username = user; final boolean isDebugEnabled = log.isDebugEnabled(); @@ -230,11 +254,14 @@ private static LdapEntry existsSearchingUntilFirstHit(final String user, Connect f.setFilter(baseSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_USERSEARCH_PATTERN)); f.setParameter(ZERO_PLACEHOLDER, username); - List result = LdapHelper.search(ldapConnection, - baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), - f, - SearchScope.SUBTREE, - returnAttributes, shouldFollowReferrals); + List result = LdapHelper.search( + ldapConnection, + baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), + f, + SearchScope.SUBTREE, + returnAttributes, + shouldFollowReferrals + ); if (isDebugEnabled) { log.debug("Results for LDAP search for {} in base {} is {}", user, entry.getKey(), result); @@ -248,8 +275,13 @@ private static LdapEntry existsSearchingUntilFirstHit(final String user, Connect return null; } - private static LdapEntry existsSearchingAllBases(final String user, Connection ldapConnection, - List> userBaseSettings, final String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + private static LdapEntry existsSearchingAllBases( + final String user, + Connection ldapConnection, + List> userBaseSettings, + final String[] returnAttributes, + final boolean shouldFollowReferrals + ) throws Exception { final String username = user; Set result = new HashSet<>(); @@ -261,11 +293,14 @@ private static LdapEntry existsSearchingAllBases(final String user, Connection l f.setFilter(baseSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_USERSEARCH_PATTERN)); f.setParameter(ZERO_PLACEHOLDER, username); - List foundEntries = LdapHelper.search(ldapConnection, - baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), - f, - SearchScope.SUBTREE, - returnAttributes, shouldFollowReferrals); + List foundEntries = LdapHelper.search( + ldapConnection, + baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), + f, + SearchScope.SUBTREE, + returnAttributes, + shouldFollowReferrals + ); if (isDebugEnabled) { log.debug("Results for LDAP search for " + user + " in base " + entry.getKey() + ":\n" + result); diff --git a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java index 68a8a3fba6..ac3fd8b32f 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java @@ -89,7 +89,8 @@ public class LDAPAuthorizationBackend implements AuthorizationBackend { private static final AtomicInteger CONNECTION_COUNTER = new AtomicInteger(); - private static final String COM_SUN_JNDI_LDAP_OBJECT_DISABLE_ENDPOINT_IDENTIFICATION = "com.sun.jndi.ldap.object.disableEndpointIdentification"; + private static final String COM_SUN_JNDI_LDAP_OBJECT_DISABLE_ENDPOINT_IDENTIFICATION = + "com.sun.jndi.ldap.object.disableEndpointIdentification"; private static final List DEFAULT_TLS_PROTOCOLS = Arrays.asList("TLSv1.2", "TLSv1.1"); static final int ONE_PLACEHOLDER = 1; static final int TWO_PLACEHOLDER = 2; @@ -112,12 +113,14 @@ public class LDAPAuthorizationBackend implements AuthorizationBackend { public LDAPAuthorizationBackend(final Settings settings, final Path configPath) { this.settings = settings; this.skipUsersMatcher = WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS)); - this.nestedRoleMatcher = settings.getAsBoolean(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) ? - WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER)) : null; + this.nestedRoleMatcher = settings.getAsBoolean(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + ? WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER)) + : null; this.configPath = configPath; this.roleBaseSettings = getRoleSearchSettings(settings); this.userBaseSettings = LDAPAuthenticationBackend.getUserBaseSettings(settings); - this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())).toArray(new String[0]); + this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())) + .toArray(new String[0]); this.shouldFollowReferrals = settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT); } @@ -198,10 +201,8 @@ private static List> convertOldStyleSettingsToNewSty Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, - settings.get(ConfigConstants.LDAP_AUTHZ_ROLEBASE, DEFAULT_ROLEBASE)); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, - settings.get(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, DEFAULT_ROLESEARCH)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, settings.get(ConfigConstants.LDAP_AUTHZ_ROLEBASE, DEFAULT_ROLEBASE)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, settings.get(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, DEFAULT_ROLESEARCH)); result.put("convertedOldStyleSettings", settingsBuilder.build()); @@ -209,9 +210,13 @@ private static List> convertOldStyleSettingsToNewSty } @SuppressWarnings("removal") - private static void checkConnection0(final ConnectionConfig connectionConfig, String bindDn, byte[] password, final ClassLoader cl, - final boolean needRestore) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - FileNotFoundException, IOException, LdapException { + private static void checkConnection0( + final ConnectionConfig connectionConfig, + String bindDn, + byte[] password, + final ClassLoader cl, + final boolean needRestore + ) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, LdapException { Connection connection = null; @@ -251,13 +256,15 @@ public Void run() throws Exception { } } - private static Connection getConnection0(final Settings settings, final Path configPath, final ClassLoader cl, - final boolean needRestore) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - FileNotFoundException, IOException, LdapException { + private static Connection getConnection0( + final Settings settings, + final Path configPath, + final ClassLoader cl, + final boolean needRestore + ) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, LdapException { final boolean enableSSL = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL, false); - final List ldapHosts = settings.getAsList(ConfigConstants.LDAP_HOSTS, - Collections.singletonList("localhost")); + final List ldapHosts = settings.getAsList(ConfigConstants.LDAP_HOSTS, Collections.singletonList("localhost")); Connection connection = null; Exception lastException = null; @@ -295,16 +302,17 @@ private static Connection getConnection0(final Settings settings, final Path con final String password = settings.get(ConfigConstants.LDAP_PASSWORD, null); if (isDebugEnabled) { - log.debug("bindDn {}, password {}", bindDn, - password != null && password.length() > 0 ? "****" : ""); + log.debug("bindDn {}, password {}", bindDn, password != null && password.length() > 0 ? "****" : ""); } if (bindDn != null && (password == null || password.length() == 0)) { log.error("No password given for bind_dn {}. Will try to authenticate anonymously to ldap", bindDn); } - final boolean enableClientAuth = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, - ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT); + final boolean enableClientAuth = settings.getAsBoolean( + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT + ); if (isDebugEnabled) { if (enableClientAuth && bindDn == null) { @@ -313,7 +321,8 @@ private static Connection getConnection0(final Settings settings, final Path con log.debug("Will perform anonymous bind because no bind dn is given"); } else if (enableClientAuth && bindDn != null) { log.debug( - "Will perform simple bind with bind dn because to bind dn is given and overrides client cert authentication"); + "Will perform simple bind with bind dn because to bind dn is given and overrides client cert authentication" + ); } else if (!enableClientAuth && bindDn != null) { log.debug("Will perform simple bind with bind dn"); } @@ -358,7 +367,7 @@ private static Connection getConnection0(final Settings settings, final Path con } if (connection == null || !connection.isOpen()) { - Utils.unbindAndCloseSilently(connection); //just in case + Utils.unbindAndCloseSilently(connection); // just in case if (needRestore) { restoreClassLoader0(cl); } @@ -367,8 +376,9 @@ private static Connection getConnection0(final Settings settings, final Path con throw new LdapException("Unable to connect to any of those ldap servers " + ldapHosts); } else { throw new LdapException( - "Unable to connect to any of those ldap servers " + ldapHosts + " due to " + lastException, - lastException); + "Unable to connect to any of those ldap servers " + ldapHosts + " due to " + lastException, + lastException + ); } } @@ -398,29 +408,29 @@ public Response reopen() throws LdapException { @Override public Response open(BindRequest request) throws LdapException { - + try { - if(isDebugEnabled && delegate != null && delegate.isOpen()) { + if (isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet()); } } catch (Throwable e) { - //ignore + // ignore } - + return delegate.open(request); } @Override public Response open() throws LdapException { - + try { - if(isDebugEnabled && delegate != null && delegate.isOpen()) { + if (isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet()); } } catch (Throwable e) { - //ignore + // ignore } - + return delegate.open(); } @@ -441,15 +451,15 @@ public ConnectionConfig getConnectionConfig() { @Override public void close(RequestControl[] controls) { - + try { - if(isDebugEnabled && delegate != null && delegate.isOpen()) { + if (isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet()); } } catch (Throwable e) { - //ignore + // ignore } - + try { delegate.close(controls); } finally { @@ -459,15 +469,15 @@ public void close(RequestControl[] controls) { @Override public void close() { - + try { - if(isDebugEnabled && delegate != null && delegate.isOpen()) { + if (isDebugEnabled && delegate != null && delegate.isOpen()) { log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet()); } } catch (Throwable e) { - //ignore + // ignore } - + try { delegate.close(); } finally { @@ -498,8 +508,7 @@ public Void run() throws Exception { } } - private static void configureSSL(final ConnectionConfig config, final Settings settings, - final Path configPath) throws Exception { + private static void configureSSL(final ConnectionConfig config, final Settings settings, final Path configPath) throws Exception { final boolean isDebugEnabled = log.isDebugEnabled(); final boolean enableSSL = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL, false); @@ -507,13 +516,15 @@ private static void configureSSL(final ConnectionConfig config, final Settings s if (enableSSL || enableStartTLS) { - final boolean enableClientAuth = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, - ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT); + final boolean enableClientAuth = settings.getAsBoolean( + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT + ); final boolean trustAll = settings.getAsBoolean(ConfigConstants.LDAPS_TRUST_ALL, false); - final boolean verifyHostnames = !trustAll && settings.getAsBoolean(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, - ConfigConstants.LDAPS_VERIFY_HOSTNAMES_DEFAULT); + final boolean verifyHostnames = !trustAll + && settings.getAsBoolean(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, ConfigConstants.LDAPS_VERIFY_HOSTNAMES_DEFAULT); if (isDebugEnabled) { log.debug("verifyHostname {}:", verifyHostnames); @@ -525,64 +536,74 @@ private static void configureSSL(final ConnectionConfig config, final Settings s } final boolean pem = settings.get(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, null) != null - || settings.get(ConfigConstants.LDAPS_PEMTRUSTEDCAS_CONTENT, null) != null; + || settings.get(ConfigConstants.LDAPS_PEMTRUSTEDCAS_CONTENT, null) != null; final SslConfig sslConfig = new SslConfig(); CredentialConfig cc; if (pem) { X509Certificate[] trustCertificates = PemKeyReader.loadCertificatesFromStream( - PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMTRUSTEDCAS_CONTENT, settings)); + PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMTRUSTEDCAS_CONTENT, settings) + ); if (trustCertificates == null) { - trustCertificates = PemKeyReader.loadCertificatesFromFile(PemKeyReader - .resolve(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, settings, configPath, !trustAll)); + trustCertificates = PemKeyReader.loadCertificatesFromFile( + PemKeyReader.resolve(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, settings, configPath, !trustAll) + ); } // for client authentication X509Certificate authenticationCertificate = PemKeyReader.loadCertificateFromStream( - PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMCERT_CONTENT, settings)); + PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMCERT_CONTENT, settings) + ); if (authenticationCertificate == null) { - authenticationCertificate = PemKeyReader.loadCertificateFromFile(PemKeyReader - .resolve(ConfigConstants.LDAPS_PEMCERT_FILEPATH, settings, configPath, enableClientAuth)); + authenticationCertificate = PemKeyReader.loadCertificateFromFile( + PemKeyReader.resolve(ConfigConstants.LDAPS_PEMCERT_FILEPATH, settings, configPath, enableClientAuth) + ); } PrivateKey authenticationKey = PemKeyReader.loadKeyFromStream( - settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD), - PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMKEY_CONTENT, settings)); + settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD), + PemKeyReader.resolveStream(ConfigConstants.LDAPS_PEMKEY_CONTENT, settings) + ); if (authenticationKey == null) { - authenticationKey = PemKeyReader - .loadKeyFromFile(settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD), PemKeyReader.resolve( - ConfigConstants.LDAPS_PEMKEY_FILEPATH, settings, configPath, enableClientAuth)); + authenticationKey = PemKeyReader.loadKeyFromFile( + settings.get(ConfigConstants.LDAPS_PEMKEY_PASSWORD), + PemKeyReader.resolve(ConfigConstants.LDAPS_PEMKEY_FILEPATH, settings, configPath, enableClientAuth) + ); } - cc = CredentialConfigFactory.createX509CredentialConfig(trustCertificates, authenticationCertificate, - authenticationKey); + cc = CredentialConfigFactory.createX509CredentialConfig(trustCertificates, authenticationCertificate, authenticationKey); if (isDebugEnabled) { - log.debug("Use PEM to secure communication with LDAP server (client auth is {})", - authenticationKey != null); + log.debug("Use PEM to secure communication with LDAP server (client auth is {})", authenticationKey != null); } } else { final KeyStore trustStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, settings, - configPath, !trustAll), - SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE)); + PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, settings, configPath, !trustAll), + SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE) + ); final List trustStoreAliases = settings.getAsList(ConfigConstants.LDAPS_JKS_TRUST_ALIAS, null); // for client authentication final KeyStore keyStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, settings, - configPath, enableClientAuth), - SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, - SSLConfigConstants.DEFAULT_STORE_PASSWORD), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE)); - final String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD - .getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD); + PemKeyReader.resolve( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + settings, + configPath, + enableClientAuth + ), + SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE) + ); + final String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting( + settings, + SSLConfigConstants.DEFAULT_STORE_PASSWORD + ); final String keyStoreAlias = settings.get(ConfigConstants.LDAPS_JKS_CERT_ALIAS, null); final String[] keyStoreAliases = keyStoreAlias == null ? null : new String[] { keyStoreAlias }; @@ -592,14 +613,17 @@ private static void configureSSL(final ConnectionConfig config, final Settings s } if (isDebugEnabled) { - log.debug("Use Trust-/Keystore to secure communication with LDAP server (client auth is {})", - keyStore != null); + log.debug("Use Trust-/Keystore to secure communication with LDAP server (client auth is {})", keyStore != null); log.debug("trustStoreAliases: {}, keyStoreAlias: {}", trustStoreAliases, keyStoreAlias); } - cc = CredentialConfigFactory.createKeyStoreCredentialConfig(trustStore, - trustStoreAliases == null ? null : trustStoreAliases.toArray(new String[0]), keyStore, - keyStorePassword, keyStoreAliases); + cc = CredentialConfigFactory.createKeyStoreCredentialConfig( + trustStore, + trustStoreAliases == null ? null : trustStoreAliases.toArray(new String[0]), + keyStore, + keyStorePassword, + keyStoreAliases + ); } @@ -614,9 +638,13 @@ private static void configureSSL(final ConnectionConfig config, final Settings s final String deiProp = System.getProperty(COM_SUN_JNDI_LDAP_OBJECT_DISABLE_ENDPOINT_IDENTIFICATION); if (deiProp == null || !Boolean.parseBoolean(deiProp)) { - log.warn("In order to disable host name verification for LDAP connections (verify_hostnames: true), " - + "you also need to set set the system property "+COM_SUN_JNDI_LDAP_OBJECT_DISABLE_ENDPOINT_IDENTIFICATION+" to true when starting the JVM running OpenSearch. " - + "This applies for all Java versions released since July 2018."); + log.warn( + "In order to disable host name verification for LDAP connections (verify_hostnames: true), " + + "you also need to set set the system property " + + COM_SUN_JNDI_LDAP_OBJECT_DISABLE_ENDPOINT_IDENTIFICATION + + " to true when starting the JVM running OpenSearch. " + + "This applies for all Java versions released since July 2018." + ); // See: // https://www.oracle.com/technetwork/java/javase/8u181-relnotes-4479407.html // https://www.oracle.com/technetwork/java/javase/10-0-2-relnotes-4477557.html @@ -627,10 +655,8 @@ private static void configureSSL(final ConnectionConfig config, final Settings s } - final List enabledCipherSuites = settings.getAsList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, - Collections.emptyList()); - final List enabledProtocols = settings.getAsList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, - DEFAULT_TLS_PROTOCOLS); + final List enabledCipherSuites = settings.getAsList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, Collections.emptyList()); + final List enabledProtocols = settings.getAsList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, DEFAULT_TLS_PROTOCOLS); if (!enabledCipherSuites.isEmpty()) { sslConfig.setEnabledCipherSuites(enabledCipherSuites.toArray(new String[0])); @@ -654,14 +680,12 @@ private static void configureSSL(final ConnectionConfig config, final Settings s config.setResponseTimeout(Duration.ofMillis(responseTimeout < 0L ? 0L : responseTimeout)); if (isDebugEnabled) { - log.debug("Connect timeout: " + config.getConnectTimeout() + "/ResponseTimeout: " - + config.getResponseTimeout()); + log.debug("Connect timeout: " + config.getConnectTimeout() + "/ResponseTimeout: " + config.getResponseTimeout()); } } @Override - public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) - throws OpenSearchSecurityException { + public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) throws OpenSearchSecurityException { if (user == null) { return; @@ -673,7 +697,7 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) String dn = null; final boolean isDebugEnabled = log.isDebugEnabled(); - if (isDebugEnabled){ + if (isDebugEnabled) { log.debug("DBGTRACE (2): username: {} -> {}", user.getName(), Arrays.toString(user.getName().getBytes(StandardCharsets.UTF_8))); } @@ -686,11 +710,14 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) originalUserName = user.getName(); } - if (isDebugEnabled){ - log.debug("DBGTRACE (3): authenticatedUser: {} -> {}", authenticatedUser, Arrays.toString(authenticatedUser.getBytes(StandardCharsets.UTF_8))); + if (isDebugEnabled) { + log.debug( + "DBGTRACE (3): authenticatedUser: {} -> {}", + authenticatedUser, + Arrays.toString(authenticatedUser.getBytes(StandardCharsets.UTF_8)) + ); } - final boolean rolesearchEnabled = settings.getAsBoolean(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true); if (isDebugEnabled) { @@ -727,8 +754,13 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) log.trace("{} is a valid DN", authenticatedUser); } - if (isDebugEnabled){ - log.debug("DBGTRACE (4): authenticatedUser="+authenticatedUser+" -> "+Arrays.toString(authenticatedUser.getBytes(StandardCharsets.UTF_8))); + if (isDebugEnabled) { + log.debug( + "DBGTRACE (4): authenticatedUser=" + + authenticatedUser + + " -> " + + Arrays.toString(authenticatedUser.getBytes(StandardCharsets.UTF_8)) + ); } entry = LdapHelper.lookup(connection, authenticatedUser, this.returnAttributes, this.shouldFollowReferrals); @@ -739,10 +771,21 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) } else { - if (isDebugEnabled) - log.debug("DBGTRACE (5): authenticatedUser="+user.getName()+" -> "+Arrays.toString(user.getName().getBytes(StandardCharsets.UTF_8))); - - entry = LDAPAuthenticationBackend.exists(user.getName(), connection, settings, userBaseSettings, this.returnAttributes, this.shouldFollowReferrals); + if (isDebugEnabled) log.debug( + "DBGTRACE (5): authenticatedUser=" + + user.getName() + + " -> " + + Arrays.toString(user.getName().getBytes(StandardCharsets.UTF_8)) + ); + + entry = LDAPAuthenticationBackend.exists( + user.getName(), + connection, + settings, + userBaseSettings, + this.returnAttributes, + this.shouldFollowReferrals + ); if (isTraceEnabled) { log.trace("{} is not a valid DN and was resolved to {}", authenticatedUser, entry); @@ -759,8 +802,8 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) log.trace("User found with DN {}", dn); } - if (isDebugEnabled){ - log.debug("DBGTRACE (6): dn"+dn+" -> "+Arrays.toString(dn.getBytes(StandardCharsets.UTF_8))); + if (isDebugEnabled) { + log.debug("DBGTRACE (6): dn" + dn + " -> " + Arrays.toString(dn.getBytes(StandardCharsets.UTF_8))); } } @@ -784,8 +827,8 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) final Collection userRoles = entry.getAttribute(roleName).getStringValues(); for (final String possibleRoleDN : userRoles) { - if (isDebugEnabled){ - log.debug("DBGTRACE (7): possibleRoleDN"+possibleRoleDN); + if (isDebugEnabled) { + log.debug("DBGTRACE (7): possibleRoleDN" + possibleRoleDN); } if (isValidDn(possibleRoleDN)) { @@ -838,8 +881,8 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) if (rolesearchEnabled) { String escapedDn = dn; - if (isDebugEnabled){ - log.debug("DBGTRACE (8): escapedDn"+escapedDn); + if (isDebugEnabled) { + log.debug("DBGTRACE (8): escapedDn" + escapedDn); } for (Map.Entry roleSearchSettingsEntry : roleBaseSettings) { @@ -849,16 +892,24 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) f.setFilter(roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_ROLESEARCH)); f.setParameter(LDAPAuthenticationBackend.ZERO_PLACEHOLDER, escapedDn); f.setParameter(ONE_PLACEHOLDER, originalUserName); - f.setParameter(TWO_PLACEHOLDER, - userRoleAttributeValue == null ? TWO_PLACEHOLDER : userRoleAttributeValue); + f.setParameter(TWO_PLACEHOLDER, userRoleAttributeValue == null ? TWO_PLACEHOLDER : userRoleAttributeValue); - List rolesResult = LdapHelper.search(connection, - roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), - f, - SearchScope.SUBTREE, this.returnAttributes, this.shouldFollowReferrals); + List rolesResult = LdapHelper.search( + connection, + roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), + f, + SearchScope.SUBTREE, + this.returnAttributes, + this.shouldFollowReferrals + ); if (isTraceEnabled) { - log.trace("Results for LDAP group search for {} in base {}:\n{}", escapedDn, roleSearchSettingsEntry.getKey(), rolesResult); + log.trace( + "Results for LDAP group search for {} in base {}:\n{}", + escapedDn, + roleSearchSettingsEntry.getKey(), + rolesResult + ); } if (rolesResult != null && !rolesResult.isEmpty()) { @@ -886,17 +937,21 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) final Set nestedReturn = new HashSet<>(ldapRoles); for (final LdapName roleLdapName : ldapRoles) { - Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys - .get(roleLdapName); + Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys.get(roleLdapName); if (nameRoleSearchBaseKeys == null) { - log.error("Could not find roleSearchBaseKeys for " + roleLdapName + "; existing: " - + resultRoleSearchBaseKeys); + log.error("Could not find roleSearchBaseKeys for " + roleLdapName + "; existing: " + resultRoleSearchBaseKeys); continue; } - final Set nestedRoles = resolveNestedRoles(roleLdapName, connection, userRoleNames, 0, - rolesearchEnabled, nameRoleSearchBaseKeys); + final Set nestedRoles = resolveNestedRoles( + roleLdapName, + connection, + userRoleNames, + 0, + rolesearchEnabled, + nameRoleSearchBaseKeys + ); if (isTraceEnabled) { log.trace("{} nested roles for {}", nestedRoles.size(), roleLdapName); @@ -953,10 +1008,14 @@ public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) } - protected Set resolveNestedRoles(final LdapName roleDn, final Connection ldapConnection, - String userRoleName, int depth, final boolean rolesearchEnabled, - Set> roleSearchBaseSettingsSet) - throws OpenSearchSecurityException, LdapException { + protected Set resolveNestedRoles( + final LdapName roleDn, + final Connection ldapConnection, + String userRoleName, + int depth, + final boolean rolesearchEnabled, + Set> roleSearchBaseSettingsSet + ) throws OpenSearchSecurityException, LdapException { if (nestedRoleMatcher.test(roleDn.toString())) { @@ -980,8 +1039,8 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti for (final String possibleRoleDN : userRoles) { - if (isDebugEnabled){ - log.debug("DBGTRACE (10): possibleRoleDN"+possibleRoleDN); + if (isDebugEnabled) { + log.debug("DBGTRACE (10): possibleRoleDN" + possibleRoleDN); } if (isValidDn(possibleRoleDN)) { @@ -1008,13 +1067,11 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti if (rolesearchEnabled) { String escapedDn = roleDn.toString(); - if (isDebugEnabled){ + if (isDebugEnabled) { log.debug("DBGTRACE (10): escapedDn {}", escapedDn); } - - for (Map.Entry roleSearchBaseSettingsEntry : Utils - .getOrderedBaseSettings(roleSearchBaseSettingsSet)) { + for (Map.Entry roleSearchBaseSettingsEntry : Utils.getOrderedBaseSettings(roleSearchBaseSettingsSet)) { Settings roleSearchSettings = roleSearchBaseSettingsEntry.getValue(); SearchFilter f = new SearchFilter(); @@ -1022,14 +1079,22 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti f.setParameter(LDAPAuthenticationBackend.ZERO_PLACEHOLDER, escapedDn); f.setParameter(ONE_PLACEHOLDER, escapedDn); - List foundEntries = LdapHelper.search(ldapConnection, - roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), - f, - SearchScope.SUBTREE, - this.returnAttributes, this.shouldFollowReferrals); + List foundEntries = LdapHelper.search( + ldapConnection, + roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), + f, + SearchScope.SUBTREE, + this.returnAttributes, + this.shouldFollowReferrals + ); if (isTraceEnabled) { - log.trace("Results for LDAP group search for {} in base {}:\n{}", escapedDn, roleSearchBaseSettingsEntry.getKey(), foundEntries); + log.trace( + "Results for LDAP group search for {} in base {}:\n{}", + escapedDn, + roleSearchBaseSettingsEntry.getKey(), + foundEntries + ); } if (foundEntries != null) { @@ -1048,8 +1113,7 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti int maxDepth = ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT; try { - maxDepth = settings.getAsInt(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH, - ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT); + maxDepth = settings.getAsInt(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH, ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT); } catch (Exception e) { log.error(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH + " is not parseable: " + e, e); } @@ -1059,13 +1123,18 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys.get(nm); if (nameRoleSearchBaseKeys == null) { - log.error( - "Could not find roleSearchBaseKeys for " + nm + "; existing: " + resultRoleSearchBaseKeys); + log.error("Could not find roleSearchBaseKeys for " + nm + "; existing: " + resultRoleSearchBaseKeys); continue; } - final Set in = resolveNestedRoles(nm, ldapConnection, userRoleName, depth, rolesearchEnabled, - nameRoleSearchBaseKeys); + final Set in = resolveNestedRoles( + nm, + ldapConnection, + userRoleName, + depth, + rolesearchEnabled, + nameRoleSearchBaseKeys + ); result.addAll(in); } } @@ -1099,16 +1168,21 @@ private String getRoleFromEntry(final Connection ldapConnection, final LdapName return null; } - if("dn".equalsIgnoreCase(role)) { + if ("dn".equalsIgnoreCase(role)) { return ldapName.toString(); } try { - final LdapEntry roleEntry = LdapHelper.lookup(ldapConnection, ldapName.toString(), this.returnAttributes, this.shouldFollowReferrals); - - if(roleEntry != null) { + final LdapEntry roleEntry = LdapHelper.lookup( + ldapConnection, + ldapName.toString(), + this.returnAttributes, + this.shouldFollowReferrals + ); + + if (roleEntry != null) { final LdapAttribute roleAttribute = roleEntry.getAttribute(role); - if(roleAttribute != null) { + if (roleAttribute != null) { return Utils.getSingleStringValue(roleAttribute); } } diff --git a/src/main/java/com/amazon/dlic/auth/ldap/util/ConfigConstants.java b/src/main/java/com/amazon/dlic/auth/ldap/util/ConfigConstants.java index bdd9f39a8e..4854f80332 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap/util/ConfigConstants.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/util/ConfigConstants.java @@ -14,7 +14,7 @@ public final class ConfigConstants { public static final String LDAP_AUTHC_USERBASE = "userbase"; - public static final String LDAP_AUTHC_USERNAME_ATTRIBUTE = "username_attribute";//multi-value + public static final String LDAP_AUTHC_USERNAME_ATTRIBUTE = "username_attribute";// multi-value public static final String LDAP_AUTHC_USERSEARCH = "usersearch"; public static final String LDAP_AUTHCZ_USERS = "users"; @@ -22,13 +22,12 @@ public final class ConfigConstants { public static final String LDAP_AUTHCZ_BASE = "base"; public static final String LDAP_AUTHCZ_SEARCH = "search"; - public static final String LDAP_AUTHZ_RESOLVE_NESTED_ROLES = "resolve_nested_roles"; public static final String LDAP_AUTHZ_ROLEBASE = "rolebase"; - public static final String LDAP_AUTHZ_ROLENAME = "rolename";//multi-value + public static final String LDAP_AUTHZ_ROLENAME = "rolename";// multi-value public static final String LDAP_AUTHZ_ROLESEARCH = "rolesearch"; - public static final String LDAP_AUTHZ_USERROLEATTRIBUTE = "userroleattribute";//multi-value - public static final String LDAP_AUTHZ_USERROLENAME = "userrolename";//multi-value + public static final String LDAP_AUTHZ_USERROLEATTRIBUTE = "userroleattribute";// multi-value + public static final String LDAP_AUTHZ_USERROLENAME = "userrolename";// multi-value public static final String LDAP_AUTHZ_SKIP_USERS = "skip_users"; public static final String LDAP_AUTHZ_ROLESEARCH_ENABLED = "rolesearch_enabled"; public static final String LDAP_AUTHZ_NESTEDROLEFILTER = "nested_role_filter"; diff --git a/src/main/java/com/amazon/dlic/auth/ldap/util/LdapHelper.java b/src/main/java/com/amazon/dlic/auth/ldap/util/LdapHelper.java index db737ca5c5..f06c7d59d7 100644 --- a/src/main/java/com/amazon/dlic/auth/ldap/util/LdapHelper.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/util/LdapHelper.java @@ -38,9 +38,16 @@ public class LdapHelper { private static SearchFilter ALL = new SearchFilter("(objectClass=*)"); + @SuppressWarnings("removal") - public static List search(final Connection conn, final String unescapedDn, SearchFilter filter, - final SearchScope searchScope, final String[] returnAttributes, boolean shouldFollowReferrals) throws LdapException { + public static List search( + final Connection conn, + final String unescapedDn, + SearchFilter filter, + final SearchScope searchScope, + final String[] returnAttributes, + boolean shouldFollowReferrals + ) throws LdapException { final SecurityManager sm = System.getSecurityManager(); @@ -61,7 +68,7 @@ public List run() throws Exception { final SearchOperation search = new SearchOperation(conn); if (shouldFollowReferrals) { - // referrals will be followed to build the response + // referrals will be followed to build the response request.setReferralHandler(new SearchReferralHandler()); } @@ -80,12 +87,17 @@ public List run() throws Exception { } else { throw new RuntimeException(e); } - }catch (InvalidNameException e) { + } catch (InvalidNameException e) { throw new RuntimeException(e); } } - public static LdapEntry lookup(final Connection conn, final String unescapedDn, final String[] returnAttributes, boolean shouldFollowReferrals) throws LdapException { + public static LdapEntry lookup( + final Connection conn, + final String unescapedDn, + final String[] returnAttributes, + boolean shouldFollowReferrals + ) throws LdapException { final List entries = search(conn, unescapedDn, ALL, SearchScope.OBJECT, returnAttributes, shouldFollowReferrals); @@ -99,15 +111,15 @@ public static LdapEntry lookup(final Connection conn, final String unescapedDn, private static String escapeDn(String dn) throws InvalidNameException { final LdapName dnName = new LdapName(dn); final List escaped = new ArrayList<>(dnName.size()); - for(Rdn rdn: dnName.getRdns()) { + for (Rdn rdn : dnName.getRdns()) { escaped.add(new Rdn(rdn.getType(), escapeForwardSlash(rdn.getValue()))); } return new LdapName(escaped).toString(); } private static Object escapeForwardSlash(Object input) { - if(input != null && input instanceof String) { - return ((String)input).replace("/", "\\2f"); + if (input != null && input instanceof String) { + return ((String) input).replace("/", "\\2f"); } else { return input; } diff --git a/src/main/java/com/amazon/dlic/auth/ldap/util/Utils.java b/src/main/java/com/amazon/dlic/auth/ldap/util/Utils.java index f10452f410..743705eee5 100644 --- a/src/main/java/com/amazon/dlic/auth/ldap/util/Utils.java +++ b/src/main/java/com/amazon/dlic/auth/ldap/util/Utils.java @@ -83,8 +83,10 @@ private static void sortBaseSettings(List> list) { @Override public int compare(Map.Entry o1, Map.Entry o2) { - int attributeOrder = Integer.compare(o1.getValue().getAsInt("order", Integer.MAX_VALUE), - o2.getValue().getAsInt("order", Integer.MAX_VALUE)); + int attributeOrder = Integer.compare( + o1.getValue().getAsInt("order", Integer.MAX_VALUE), + o2.getValue().getAsInt("order", Integer.MAX_VALUE) + ); if (attributeOrder != 0) { return attributeOrder; @@ -96,12 +98,12 @@ public int compare(Map.Entry o1, Map.Entry o } public static String getSingleStringValue(LdapAttribute attribute) { - if(attribute == null) { + if (attribute == null) { return null; } - if(attribute.size() > 1) { - if(log.isDebugEnabled()) { + if (attribute.size() > 1) { + if (log.isDebugEnabled()) { log.debug("Multiple values found for {} ({})", attribute.getName(), attribute); } } diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java index f64f3fc0b4..74184de0eb 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthenticationBackend2.java @@ -65,8 +65,7 @@ public class LDAPAuthenticationBackend2 implements AuthenticationBackend, Destro public LDAPAuthenticationBackend2(final Settings settings, final Path configPath) throws SSLConfigException { this.settings = settings; - LDAPConnectionFactoryFactory ldapConnectionFactoryFactory = new LDAPConnectionFactoryFactory(settings, - configPath); + LDAPConnectionFactoryFactory ldapConnectionFactoryFactory = new LDAPConnectionFactoryFactory(settings, configPath); this.connectionPool = ldapConnectionFactoryFactory.createConnectionPool(); this.connectionFactory = ldapConnectionFactoryFactory.createConnectionFactory(this.connectionPool); @@ -78,11 +77,13 @@ public LDAPAuthenticationBackend2(final Settings settings, final Path configPath } this.userSearcher = new LDAPUserSearcher(settings); - this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())).toArray(new String[0]); + this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())) + .toArray(new String[0]); this.shouldFollowReferrals = settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT); customAttrMaxValueLen = settings.getAsInt(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 36); - whitelistedCustomLdapAttrMatcher = WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, - Collections.singletonList("*"))); + whitelistedCustomLdapAttrMatcher = WildcardMatcher.from( + settings.getAsList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, Collections.singletonList("*")) + ); } @Override @@ -112,7 +113,6 @@ public User run() throws Exception { } } - private User authenticate0(final AuthCredentials credentials) throws OpenSearchSecurityException { Connection ldapConnection = null; @@ -130,11 +130,12 @@ private User authenticate0(final AuthCredentials credentials) throws OpenSearchS // makes guessing if a user exists or not harder when looking on the // authentication delay time if (entry == null && settings.getAsBoolean(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, false)) { - String fakeLognDn = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_DN, - "CN=faketomakebindfail,DC=" + UUID.randomUUID().toString()); + String fakeLognDn = settings.get( + ConfigConstants.LDAP_FAKE_LOGIN_DN, + "CN=faketomakebindfail,DC=" + UUID.randomUUID().toString() + ); entry = new LdapEntry(fakeLognDn); - password = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_PASSWORD, "fakeLoginPwd123") - .getBytes(StandardCharsets.UTF_8); + password = settings.get(ConfigConstants.LDAP_FAKE_LOGIN_PASSWORD, "fakeLoginPwd123").getBytes(StandardCharsets.UTF_8); } else if (entry == null) { throw new OpenSearchSecurityException("No user " + user + " found"); } @@ -195,7 +196,6 @@ public boolean exists(final User user) { sm.checkPermission(new SpecialPermission()); } - return AccessController.doPrivileged(new PrivilegedAction() { @Override public Boolean run() { @@ -217,13 +217,15 @@ private boolean exists0(final User user) { ldapConnection = this.connectionFactory.getConnection(); ldapConnection.open(); LdapEntry userEntry = this.userSearcher.exists(ldapConnection, userName, this.returnAttributes, this.shouldFollowReferrals); - + boolean exists = userEntry != null; - - if(exists) { - user.addAttributes(LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, whitelistedCustomLdapAttrMatcher)); + + if (exists) { + user.addAttributes( + LdapUser.extractLdapAttributes(userName, userEntry, customAttrMaxValueLen, whitelistedCustomLdapAttrMatcher) + ); } - + return exists; } catch (final Exception e) { log.warn("User {} does not exist due to exception", userName, e); @@ -234,8 +236,7 @@ private boolean exists0(final User user) { } @SuppressWarnings("removal") - private void authenticateByLdapServer(final Connection connection, final String dn, byte[] password) - throws LdapException { + private void authenticateByLdapServer(final Connection connection, final String dn, byte[] password) throws LdapException { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java index c140dbb6f9..d8d27de7da 100755 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPAuthorizationBackend2.java @@ -81,17 +81,18 @@ public class LDAPAuthorizationBackend2 implements AuthorizationBackend, Destroya public LDAPAuthorizationBackend2(final Settings settings, final Path configPath) throws SSLConfigException { this.settings = settings; this.skipUsersMatcher = WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS)); - this.nestedRoleMatcher = settings.getAsBoolean(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) ? - WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER)) : null; + this.nestedRoleMatcher = settings.getAsBoolean(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + ? WildcardMatcher.from(settings.getAsList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER)) + : null; this.roleBaseSettings = getRoleSearchSettings(settings); - LDAPConnectionFactoryFactory ldapConnectionFactoryFactory = new LDAPConnectionFactoryFactory(settings, - configPath); + LDAPConnectionFactoryFactory ldapConnectionFactoryFactory = new LDAPConnectionFactoryFactory(settings, configPath); this.connectionPool = ldapConnectionFactoryFactory.createConnectionPool(); this.connectionFactory = ldapConnectionFactoryFactory.createConnectionFactory(this.connectionPool); this.userSearcher = new LDAPUserSearcher(settings); - this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())).toArray(new String[0]); + this.returnAttributes = settings.getAsList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, Arrays.asList(ReturnAttributes.ALL.value())) + .toArray(new String[0]); this.shouldFollowReferrals = settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT); } @@ -112,10 +113,8 @@ private static List> convertOldStyleSettingsToNewSty Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, - settings.get(ConfigConstants.LDAP_AUTHZ_ROLEBASE, DEFAULT_ROLEBASE)); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, - settings.get(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, DEFAULT_ROLESEARCH)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, settings.get(ConfigConstants.LDAP_AUTHZ_ROLEBASE, DEFAULT_ROLEBASE)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, settings.get(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, DEFAULT_ROLESEARCH)); result.put("convertedOldStyleSettings", settingsBuilder.build()); @@ -124,8 +123,7 @@ private static List> convertOldStyleSettingsToNewSty @SuppressWarnings("removal") @Override - public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) - throws OpenSearchSecurityException { + public void fillRoles(final User user, final AuthCredentials optionalAuthCreds) throws OpenSearchSecurityException { final SecurityManager sm = System.getSecurityManager(); @@ -152,8 +150,7 @@ public Void run() throws Exception { } } - private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds) - throws OpenSearchSecurityException { + private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds) throws OpenSearchSecurityException { if (user == null) { return; @@ -170,7 +167,7 @@ private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds authenticatedUser = entry.getDn(); originalUserName = ((LdapUser) user).getOriginalUsername(); } else { - authenticatedUser =user.getName(); + authenticatedUser = user.getName(); originalUserName = user.getName(); } @@ -309,17 +306,24 @@ private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds f.setFilter(roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_ROLESEARCH)); f.setParameter(ZERO_PLACEHOLDER, escapedDn); f.setParameter(ONE_PLACEHOLDER, originalUserName); - f.setParameter(TWO_PLACEHOLDER, - userRoleAttributeValue == null ? TWO_PLACEHOLDER : userRoleAttributeValue); + f.setParameter(TWO_PLACEHOLDER, userRoleAttributeValue == null ? TWO_PLACEHOLDER : userRoleAttributeValue); - List rolesResult = LdapHelper.search(connection, - roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), - f, - SearchScope.SUBTREE, - this.returnAttributes, this.shouldFollowReferrals); + List rolesResult = LdapHelper.search( + connection, + roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), + f, + SearchScope.SUBTREE, + this.returnAttributes, + this.shouldFollowReferrals + ); if (isTraceEnabled) { - log.trace("Results for LDAP group search for {} in base {}:\n{}", escapedDn, roleSearchSettingsEntry.getKey(), rolesResult); + log.trace( + "Results for LDAP group search for {} in base {}:\n{}", + escapedDn, + roleSearchSettingsEntry.getKey(), + rolesResult + ); } if (rolesResult != null && !rolesResult.isEmpty()) { @@ -347,17 +351,21 @@ private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds final Set nestedReturn = new HashSet<>(ldapRoles); for (final LdapName roleLdapName : ldapRoles) { - Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys - .get(roleLdapName); + Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys.get(roleLdapName); if (nameRoleSearchBaseKeys == null) { - log.error("Could not find roleSearchBaseKeys for {}; existing: {}", - roleLdapName, resultRoleSearchBaseKeys); + log.error("Could not find roleSearchBaseKeys for {}; existing: {}", roleLdapName, resultRoleSearchBaseKeys); continue; } - final Set nestedRoles = resolveNestedRoles(roleLdapName, connection, userRoleNames, 0, - rolesearchEnabled, nameRoleSearchBaseKeys); + final Set nestedRoles = resolveNestedRoles( + roleLdapName, + connection, + userRoleNames, + 0, + rolesearchEnabled, + nameRoleSearchBaseKeys + ); if (isTraceEnabled) { log.trace("{} nested roles for {}", nestedRoles.size(), roleLdapName); @@ -412,10 +420,14 @@ private void fillRoles0(final User user, final AuthCredentials optionalAuthCreds } - protected Set resolveNestedRoles(final LdapName roleDn, final Connection ldapConnection, - String userRoleName, int depth, final boolean rolesearchEnabled, - Set> roleSearchBaseSettingsSet) - throws OpenSearchSecurityException, LdapException { + protected Set resolveNestedRoles( + final LdapName roleDn, + final Connection ldapConnection, + String userRoleName, + int depth, + final boolean rolesearchEnabled, + Set> roleSearchBaseSettingsSet + ) throws OpenSearchSecurityException, LdapException { final boolean isTraceEnabled = log.isTraceEnabled(); if (nestedRoleMatcher.test(roleDn.toString())) { @@ -461,8 +473,7 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti if (rolesearchEnabled) { String escapedDn = roleDn.toString(); - for (Map.Entry roleSearchBaseSettingsEntry : Utils - .getOrderedBaseSettings(roleSearchBaseSettingsSet)) { + for (Map.Entry roleSearchBaseSettingsEntry : Utils.getOrderedBaseSettings(roleSearchBaseSettingsSet)) { Settings roleSearchSettings = roleSearchBaseSettingsEntry.getValue(); SearchFilter f = new SearchFilter(); @@ -470,14 +481,22 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti f.setParameter(ZERO_PLACEHOLDER, escapedDn); f.setParameter(ONE_PLACEHOLDER, escapedDn); - List foundEntries = LdapHelper.search(ldapConnection, - roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), - f, - SearchScope.SUBTREE, - this.returnAttributes, this.shouldFollowReferrals); + List foundEntries = LdapHelper.search( + ldapConnection, + roleSearchSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_ROLEBASE), + f, + SearchScope.SUBTREE, + this.returnAttributes, + this.shouldFollowReferrals + ); if (isTraceEnabled) { - log.trace("Results for LDAP group search for {} in base {}:\n{}", escapedDn, roleSearchBaseSettingsEntry.getKey(), foundEntries); + log.trace( + "Results for LDAP group search for {} in base {}:\n{}", + escapedDn, + roleSearchBaseSettingsEntry.getKey(), + foundEntries + ); } if (foundEntries != null) { @@ -496,8 +515,7 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti int maxDepth = ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT; try { - maxDepth = settings.getAsInt(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH, - ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT); + maxDepth = settings.getAsInt(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH, ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH_DEFAULT); } catch (Exception e) { log.error(ConfigConstants.LDAP_AUTHZ_MAX_NESTED_DEPTH + " is not parseable: ", e); } @@ -507,13 +525,18 @@ protected Set resolveNestedRoles(final LdapName roleDn, final Connecti Set> nameRoleSearchBaseKeys = resultRoleSearchBaseKeys.get(nm); if (nameRoleSearchBaseKeys == null) { - log.error( - "Could not find roleSearchBaseKeys for {}; existing: {}", nm, resultRoleSearchBaseKeys); + log.error("Could not find roleSearchBaseKeys for {}; existing: {}", nm, resultRoleSearchBaseKeys); continue; } - final Set in = resolveNestedRoles(nm, ldapConnection, userRoleName, depth, rolesearchEnabled, - nameRoleSearchBaseKeys); + final Set in = resolveNestedRoles( + nm, + ldapConnection, + userRoleName, + depth, + rolesearchEnabled, + nameRoleSearchBaseKeys + ); result.addAll(in); } } @@ -547,21 +570,26 @@ private String getRoleFromEntry(final Connection ldapConnection, final LdapName return null; } - if("dn".equalsIgnoreCase(role)) { + if ("dn".equalsIgnoreCase(role)) { return ldapName.toString(); } try { - final LdapEntry roleEntry = LdapHelper.lookup(ldapConnection, ldapName.toString(), this.returnAttributes, this.shouldFollowReferrals); - - if(roleEntry != null) { + final LdapEntry roleEntry = LdapHelper.lookup( + ldapConnection, + ldapName.toString(), + this.returnAttributes, + this.shouldFollowReferrals + ); + + if (roleEntry != null) { final LdapAttribute roleAttribute = roleEntry.getAttribute(role); - if(roleAttribute != null) { + if (roleAttribute != null) { return Utils.getSingleStringValue(roleAttribute); } } } catch (LdapException e) { - log.error("Unable to handle role {} because of ",ldapName, e); + log.error("Unable to handle role {} because of ", ldapName, e); } return null; diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java index f711e41982..877c4160da 100644 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPConnectionFactoryFactory.java @@ -132,10 +132,22 @@ public ConnectionPool createConnectionPool() { checkForDeprecatedSetting(settings, ConfigConstants.LDAP_LEGACY_POOL_PRUNING_PERIOD, ConfigConstants.LDAP_POOL_PRUNING_PERIOD); checkForDeprecatedSetting(settings, ConfigConstants.LDAP_LEGACY_POOL_IDLE_TIME, ConfigConstants.LDAP_POOL_IDLE_TIME); - - result.setPruneStrategy(new IdlePruneStrategy( - Duration.ofMinutes(this.settings.getAsLong(ConfigConstants.LDAP_POOL_PRUNING_PERIOD, this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_PRUNING_PERIOD, 5l))), - Duration.ofMinutes(this.settings.getAsLong(ConfigConstants.LDAP_POOL_IDLE_TIME, this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_IDLE_TIME, 10l)))) + + result.setPruneStrategy( + new IdlePruneStrategy( + Duration.ofMinutes( + this.settings.getAsLong( + ConfigConstants.LDAP_POOL_PRUNING_PERIOD, + this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_PRUNING_PERIOD, 5l) + ) + ), + Duration.ofMinutes( + this.settings.getAsLong( + ConfigConstants.LDAP_POOL_IDLE_TIME, + this.settings.getAsLong(ConfigConstants.LDAP_LEGACY_POOL_IDLE_TIME, 10l) + ) + ) + ) ); result.initialize(); @@ -186,8 +198,10 @@ private ConnectionInitializer getConnectionInitializer() { log.error("No password given for bind_dn {}. Will try to authenticate anonymously to ldap", bindDn); } - boolean enableClientAuth = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, - ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT); + boolean enableClientAuth = settings.getAsBoolean( + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, + ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT + ); if (bindDn != null && password != null) { log.debug("Will perform simple bind with bind dn"); @@ -195,8 +209,7 @@ private ConnectionInitializer getConnectionInitializer() { result.setBindCredential(new Credential(password)); if (enableClientAuth) { - log.warn( - "Will perform simple bind with bind dn because to bind dn is given and overrides client cert authentication"); + log.warn("Will perform simple bind with bind dn because to bind dn is given and overrides client cert authentication"); } } else if (enableClientAuth) { log.debug("Will perform External SASL bind because client cert authentication is enabled"); @@ -210,12 +223,12 @@ private ConnectionInitializer getConnectionInitializer() { private ConnectionStrategy getConnectionStrategy() { switch (this.settings.get(ConfigConstants.LDAP_CONNECTION_STRATEGY, "active_passive").toLowerCase()) { - case "round_robin": - return new RoundRobinConnectionStrategy(); - case "random": - return new RandomConnectionStrategy(); - default: - return new ActivePassiveConnectionStrategy(); + case "round_robin": + return new RoundRobinConnectionStrategy(); + case "random": + return new RandomConnectionStrategy(); + default: + return new ActivePassiveConnectionStrategy(); } } @@ -228,14 +241,19 @@ private Validator getConnectionValidator() { Validator result = null; if ("compare".equalsIgnoreCase(validationStrategy)) { - result = new CompareValidator(new CompareRequest(this.settings.get("validation.compare.dn", ""), - new LdapAttribute(this.settings.get("validation.compare.attribute", "objectClass"), - this.settings.get("validation.compare.value", "top")))); + result = new CompareValidator( + new CompareRequest( + this.settings.get("validation.compare.dn", ""), + new LdapAttribute( + this.settings.get("validation.compare.attribute", "objectClass"), + this.settings.get("validation.compare.value", "top") + ) + ) + ); } else { SearchRequest searchRequest = new SearchRequest(); searchRequest.setBaseDn(this.settings.get("validation.search.base_dn", "")); - searchRequest.setSearchFilter( - new SearchFilter(this.settings.get("validation.search.filter", "(objectClass=*)"))); + searchRequest.setSearchFilter(new SearchFilter(this.settings.get("validation.search.filter", "(objectClass=*)"))); searchRequest.setReturnAttributes(ReturnAttributes.NONE.value()); searchRequest.setSearchScope(SearchScope.OBJECT); searchRequest.setSizeLimit(1); @@ -250,8 +268,7 @@ private String getLdapUrlString() { // It's a bit weird that we create from structured data a plain string which is // later parsed again by ldaptive. But that's the way the API wants it to be. - List ldapHosts = this.settings.getAsList(ConfigConstants.LDAP_HOSTS, - Collections.singletonList("localhost")); + List ldapHosts = this.settings.getAsList(ConfigConstants.LDAP_HOSTS, Collections.singletonList("localhost")); boolean enableSSL = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL, false); StringBuilder result = new StringBuilder(); @@ -282,9 +299,12 @@ private void configureSSL(ConnectionConfig config) { SslConfig ldaptiveSslConfig = new SslConfig(); CredentialConfig cc = CredentialConfigFactory.createKeyStoreCredentialConfig( - this.sslConfig.getEffectiveTruststore(), this.sslConfig.getEffectiveTruststoreAliasesArray(), - this.sslConfig.getEffectiveKeystore(), this.sslConfig.getEffectiveKeyPasswordString(), - this.sslConfig.getEffectiveKeyAliasesArray()); + this.sslConfig.getEffectiveTruststore(), + this.sslConfig.getEffectiveTruststoreAliasesArray(), + this.sslConfig.getEffectiveKeystore(), + this.sslConfig.getEffectiveKeyPasswordString(), + this.sslConfig.getEffectiveKeyAliasesArray() + ); ldaptiveSslConfig.setCredentialConfig(cc); @@ -292,9 +312,11 @@ private void configureSSL(ConnectionConfig config) { ldaptiveSslConfig.setHostnameVerifier(new AllowAnyHostnameVerifier()); if (!Boolean.parseBoolean(System.getProperty("com.sun.jndi.ldap.object.disableEndpointIdentification"))) { - log.warn("In order to disable host name verification for LDAP connections (verify_hostnames: true), " + log.warn( + "In order to disable host name verification for LDAP connections (verify_hostnames: true), " + "you also need to set set the system property com.sun.jndi.ldap.object.disableEndpointIdentification to true when starting the JVM running OpenSearch. " - + "This applies for all Java versions released since July 2018."); + + "This applies for all Java versions released since July 2018." + ); // See: // https://www.oracle.com/technetwork/java/javase/8u181-relnotes-4479407.html // https://www.oracle.com/technetwork/java/javase/10-0-2-relnotes-4477557.html diff --git a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPUserSearcher.java b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPUserSearcher.java index 81da81647f..966555daff 100644 --- a/src/main/java/com/amazon/dlic/auth/ldap2/LDAPUserSearcher.java +++ b/src/main/java/com/amazon/dlic/auth/ldap2/LDAPUserSearcher.java @@ -48,33 +48,34 @@ public LDAPUserSearcher(Settings settings) { } static List> getUserBaseSettings(Settings settings) { - Map userBaseSettingsMap = new HashMap<>( - settings.getGroups(ConfigConstants.LDAP_AUTHCZ_USERS)); + Map userBaseSettingsMap = new HashMap<>(settings.getGroups(ConfigConstants.LDAP_AUTHCZ_USERS)); if (!userBaseSettingsMap.isEmpty()) { if (settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { throw new RuntimeException( - "Both old-style and new-style configuration defined for LDAP authentication backend: " - + settings); + "Both old-style and new-style configuration defined for LDAP authentication backend: " + settings + ); } return Utils.getOrderedBaseSettings(userBaseSettingsMap); } else { Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, - settings.get(ConfigConstants.LDAP_AUTHC_USERBASE, DEFAULT_USERBASE)); - settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_SEARCH, - settings.get(ConfigConstants.LDAP_AUTHC_USERSEARCH, DEFAULT_USERSEARCH_PATTERN)); + settingsBuilder.put(ConfigConstants.LDAP_AUTHCZ_BASE, settings.get(ConfigConstants.LDAP_AUTHC_USERBASE, DEFAULT_USERBASE)); + settingsBuilder.put( + ConfigConstants.LDAP_AUTHCZ_SEARCH, + settings.get(ConfigConstants.LDAP_AUTHC_USERSEARCH, DEFAULT_USERSEARCH_PATTERN) + ); return Collections.singletonList(Pair.of("_legacyConfig", settingsBuilder.build())); } } - LdapEntry exists(Connection ldapConnection, String user, final String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + LdapEntry exists(Connection ldapConnection, String user, final String[] returnAttributes, final boolean shouldFollowReferrals) + throws Exception { if (settings.getAsBoolean(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, false) - || settings.getAsBoolean(ConfigConstants.LDAP_SEARCH_ALL_BASES, false) - || settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { + || settings.getAsBoolean(ConfigConstants.LDAP_SEARCH_ALL_BASES, false) + || settings.hasValue(ConfigConstants.LDAP_AUTHC_USERBASE)) { return existsSearchingAllBases(ldapConnection, user, returnAttributes, shouldFollowReferrals); } else { return existsSearchingUntilFirstHit(ldapConnection, user, returnAttributes, shouldFollowReferrals); @@ -82,7 +83,12 @@ LdapEntry exists(Connection ldapConnection, String user, final String[] returnAt } - private LdapEntry existsSearchingUntilFirstHit(Connection ldapConnection, String user, final String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + private LdapEntry existsSearchingUntilFirstHit( + Connection ldapConnection, + String user, + final String[] returnAttributes, + final boolean shouldFollowReferrals + ) throws Exception { final String username = user; final boolean isDebugEnabled = log.isDebugEnabled(); for (Map.Entry entry : userBaseSettings) { @@ -92,11 +98,14 @@ private LdapEntry existsSearchingUntilFirstHit(Connection ldapConnection, String f.setFilter(baseSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_USERSEARCH_PATTERN)); f.setParameter(ZERO_PLACEHOLDER, username); - List result = LdapHelper.search(ldapConnection, - baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), - f, - SearchScope.SUBTREE, - returnAttributes, shouldFollowReferrals); + List result = LdapHelper.search( + ldapConnection, + baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), + f, + SearchScope.SUBTREE, + returnAttributes, + shouldFollowReferrals + ); if (isDebugEnabled) { log.debug("Results for LDAP search for {} in base {}:\n{}", user, entry.getKey(), result); @@ -110,7 +119,12 @@ private LdapEntry existsSearchingUntilFirstHit(Connection ldapConnection, String return null; } - private LdapEntry existsSearchingAllBases(Connection ldapConnection, String user, final String[] returnAttributes, final boolean shouldFollowReferrals) throws Exception { + private LdapEntry existsSearchingAllBases( + Connection ldapConnection, + String user, + final String[] returnAttributes, + final boolean shouldFollowReferrals + ) throws Exception { final String username = user; Set result = new HashSet<>(); final boolean isDebugEnabled = log.isDebugEnabled(); @@ -121,11 +135,14 @@ private LdapEntry existsSearchingAllBases(Connection ldapConnection, String user f.setFilter(baseSettings.get(ConfigConstants.LDAP_AUTHCZ_SEARCH, DEFAULT_USERSEARCH_PATTERN)); f.setParameter(ZERO_PLACEHOLDER, username); - List foundEntries = LdapHelper.search(ldapConnection, - baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), - f, - SearchScope.SUBTREE, - returnAttributes, shouldFollowReferrals); + List foundEntries = LdapHelper.search( + ldapConnection, + baseSettings.get(ConfigConstants.LDAP_AUTHCZ_BASE, DEFAULT_USERBASE), + f, + SearchScope.SUBTREE, + returnAttributes, + shouldFollowReferrals + ); if (isDebugEnabled) { log.debug("Results for LDAP search for {} in base {}:\n{}", user, entry.getKey(), result); diff --git a/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfigurator.java b/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfigurator.java index ea99625e6b..ed42117a04 100644 --- a/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfigurator.java +++ b/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfigurator.java @@ -95,8 +95,7 @@ public class SettingsBasedSSLConfigurator { private String effectiveKeyAlias; private List effectiveTruststoreAliases; - public SettingsBasedSSLConfigurator(Settings settings, Path configPath, String settingsKeyPrefix, - String clientName) { + public SettingsBasedSSLConfigurator(Settings settings, Path configPath, String settingsKeyPrefix, String clientName) { this.settings = settings; this.configPath = configPath; this.settingsKeyPrefix = normalizeSettingsKeyPrefix(settingsKeyPrefix); @@ -136,10 +135,20 @@ public SSLConfig buildSSLConfig() throws SSLConfigException { return null; } - return new SSLConfig(sslContext, getSupportedProtocols(), getSupportedCipherSuites(), getHostnameVerifier(), - isHostnameVerificationEnabled(), isTrustAllEnabled(), isStartTlsEnabled(), this.effectiveTruststore, - this.effectiveTruststoreAliases, this.effectiveKeystore, this.effectiveKeyPassword, - this.effectiveKeyAlias); + return new SSLConfig( + sslContext, + getSupportedProtocols(), + getSupportedCipherSuites(), + getHostnameVerifier(), + isHostnameVerificationEnabled(), + isTrustAllEnabled(), + isStartTlsEnabled(), + this.effectiveTruststore, + this.effectiveTruststoreAliases, + this.effectiveKeystore, + this.effectiveKeyPassword, + this.effectiveKeyAlias + ); } private boolean isHostnameVerificationEnabled() { @@ -181,7 +190,7 @@ private void configureWithSettings() throws SSLConfigException, NoSuchAlgorithmE this.enableSslClientAuth = getSettingAsBoolean(ENABLE_SSL_CLIENT_AUTH, false); if (settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, null) != null - || settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, null) != null) { + || settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, null) != null) { initFromPem(); } else { initFromKeyStore(); @@ -194,22 +203,21 @@ private void configureWithSettings() throws SSLConfigException, NoSuchAlgorithmE if (enableSslClientAuth) { if (effectiveKeystore != null) { try { - sslContextBuilder.loadKeyMaterial(effectiveKeystore, effectiveKeyPassword, - new PrivateKeyStrategy() { - - @Override - public String chooseAlias(Map aliases, SSLParameters sslParameters) { - if (aliases == null || aliases.isEmpty()) { - return effectiveKeyAlias; - } - - if (effectiveKeyAlias == null || effectiveKeyAlias.isEmpty()) { - return aliases.keySet().iterator().next(); - } - - return effectiveKeyAlias; - } - }); + sslContextBuilder.loadKeyMaterial(effectiveKeystore, effectiveKeyPassword, new PrivateKeyStrategy() { + + @Override + public String chooseAlias(Map aliases, SSLParameters sslParameters) { + if (aliases == null || aliases.isEmpty()) { + return effectiveKeyAlias; + } + + if (effectiveKeyAlias == null || effectiveKeyAlias.isEmpty()) { + return aliases.keySet().iterator().next(); + } + + return effectiveKeyAlias; + } + }); } catch (UnrecoverableKeyException e) { throw new RuntimeException(e); } @@ -223,22 +231,25 @@ private void initFromPem() throws SSLConfigException { try { trustCertificates = PemKeyReader.loadCertificatesFromStream( - PemKeyReader.resolveStream(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, settings)); + PemKeyReader.resolveStream(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, settings) + ); } catch (Exception e) { throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT + " for " + this.clientName, - e); + "Error loading PEM from " + settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT + " for " + this.clientName, + e + ); } if (trustCertificates == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, settings, configPath, - !isTrustAllEnabled()); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, settings, configPath, !isTrustAllEnabled()); try { trustCertificates = PemKeyReader.loadCertificatesFromFile(path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMTRUSTEDCAS_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -247,21 +258,22 @@ private void initFromPem() throws SSLConfigException { try { authenticationCertificate = PemKeyReader.loadCertificatesFromStream( - PemKeyReader.resolveStream(settingsKeyPrefix + PEMCERT_CONTENT, settings)); + PemKeyReader.resolveStream(settingsKeyPrefix + PEMCERT_CONTENT, settings) + ); } catch (Exception e) { - throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMCERT_CONTENT + " for " + this.clientName, e); + throw new SSLConfigException("Error loading PEM from " + settingsKeyPrefix + PEMCERT_CONTENT + " for " + this.clientName, e); } if (authenticationCertificate == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMCERT_FILEPATH, settings, configPath, - enableSslClientAuth); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMCERT_FILEPATH, settings, configPath, enableSslClientAuth); try { authenticationCertificate = PemKeyReader.loadCertificatesFromFile(path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMCERT_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMCERT_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -269,22 +281,24 @@ private void initFromPem() throws SSLConfigException { PrivateKey authenticationKey; try { - authenticationKey = PemKeyReader.loadKeyFromStream(getSetting(PEMKEY_PASSWORD), - PemKeyReader.resolveStream(settingsKeyPrefix + PEMKEY_CONTENT, settings)); + authenticationKey = PemKeyReader.loadKeyFromStream( + getSetting(PEMKEY_PASSWORD), + PemKeyReader.resolveStream(settingsKeyPrefix + PEMKEY_CONTENT, settings) + ); } catch (Exception e) { - throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMKEY_CONTENT + " for " + this.clientName, e); + throw new SSLConfigException("Error loading PEM from " + settingsKeyPrefix + PEMKEY_CONTENT + " for " + this.clientName, e); } if (authenticationKey == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMKEY_FILEPATH, settings, configPath, - enableSslClientAuth); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMKEY_FILEPATH, settings, configPath, enableSslClientAuth); try { authenticationKey = PemKeyReader.loadKeyFromFile(getSetting(PEMKEY_PASSWORD), path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMKEY_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMKEY_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -292,8 +306,12 @@ private void initFromPem() throws SSLConfigException { effectiveKeyPassword = PemKeyReader.randomChars(12); effectiveKeyAlias = "al"; effectiveTruststore = PemKeyReader.toTruststore(effectiveKeyAlias, trustCertificates); - effectiveKeystore = PemKeyReader.toKeystore(effectiveKeyAlias, effectiveKeyPassword, - authenticationCertificate, authenticationKey); + effectiveKeystore = PemKeyReader.toKeystore( + effectiveKeyAlias, + effectiveKeyPassword, + authenticationCertificate, + authenticationKey + ); } catch (Exception e) { throw new SSLConfigException("Error initializing SSLConfig for " + this.clientName, e); } @@ -306,13 +324,20 @@ private void initFromKeyStore() throws SSLConfigException { try { trustStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, settings, - configPath, !isTrustAllEnabled()), - SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE)); + PemKeyReader.resolve( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + settings, + configPath, + !isTrustAllEnabled() + ), + SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE) + ); } catch (Exception e) { - throw new SSLConfigException("Error loading trust store from " - + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH), e); + throw new SSLConfigException( + "Error loading trust store from " + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH), + e + ); } effectiveTruststoreAliases = getSettingAsList(CA_ALIAS, null); @@ -321,20 +346,24 @@ private void initFromKeyStore() throws SSLConfigException { try { keyStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, settings, - configPath, enableSslClientAuth), - SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, - SSLConfigConstants.DEFAULT_STORE_PASSWORD), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE)); + PemKeyReader.resolve( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + settings, + configPath, + enableSslClientAuth + ), + SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE) + ); } catch (Exception e) { - throw new SSLConfigException("Error loading key store from " - + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH), e); + throw new SSLConfigException( + "Error loading key store from " + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH), + e + ); } - String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, - SSLConfigConstants.DEFAULT_STORE_PASSWORD); - effectiveKeyPassword = keyStorePassword == null || keyStorePassword.isEmpty() ? null - : keyStorePassword.toCharArray(); + String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD); + effectiveKeyPassword = keyStorePassword == null || keyStorePassword.isEmpty() ? null : keyStorePassword.toCharArray(); effectiveKeyAlias = getSetting(CERT_ALIAS); if (enableSslClientAuth && effectiveKeyAlias == null) { @@ -393,10 +422,20 @@ public static class SSLConfig { private final char[] effectiveKeyPassword; private final String effectiveKeyAlias; - public SSLConfig(SSLContext sslContext, String[] supportedProtocols, String[] supportedCipherSuites, - HostnameVerifier hostnameVerifier, boolean hostnameVerificationEnabled, boolean trustAll, - boolean startTlsEnabled, KeyStore effectiveTruststore, List effectiveTruststoreAliases, - KeyStore effectiveKeystore, char[] effectiveKeyPassword, String effectiveKeyAlias) { + public SSLConfig( + SSLContext sslContext, + String[] supportedProtocols, + String[] supportedCipherSuites, + HostnameVerifier hostnameVerifier, + boolean hostnameVerificationEnabled, + boolean trustAll, + boolean startTlsEnabled, + KeyStore effectiveTruststore, + List effectiveTruststoreAliases, + KeyStore effectiveKeystore, + char[] effectiveKeyPassword, + String effectiveKeyAlias + ) { this.sslContext = sslContext; this.supportedProtocols = supportedProtocols; this.supportedCipherSuites = supportedCipherSuites; @@ -432,8 +471,7 @@ public HostnameVerifier getHostnameVerifier() { } public SSLConnectionSocketFactory toSSLConnectionSocketFactory() { - return new SSLConnectionSocketFactory(sslContext, supportedProtocols, supportedCipherSuites, - hostnameVerifier); + return new SSLConnectionSocketFactory(sslContext, supportedProtocols, supportedCipherSuites, hostnameVerifier); } public boolean isStartTlsEnabled() { @@ -490,12 +528,29 @@ public String[] getEffectiveKeyAliasesArray() { @Override public String toString() { - return "SSLConfig [sslContext=" + sslContext + ", supportedProtocols=" + Arrays.toString(supportedProtocols) - + ", supportedCipherSuites=" + Arrays.toString(supportedCipherSuites) + ", hostnameVerifier=" - + hostnameVerifier + ", startTlsEnabled=" + startTlsEnabled + ", hostnameVerificationEnabled=" - + hostnameVerificationEnabled + ", trustAll=" + trustAll + ", effectiveTruststore=" - + effectiveTruststore + ", effectiveTruststoreAliases=" + effectiveTruststoreAliases - + ", effectiveKeystore=" + effectiveKeystore + ", effectiveKeyAlias=" + effectiveKeyAlias + "]"; + return "SSLConfig [sslContext=" + + sslContext + + ", supportedProtocols=" + + Arrays.toString(supportedProtocols) + + ", supportedCipherSuites=" + + Arrays.toString(supportedCipherSuites) + + ", hostnameVerifier=" + + hostnameVerifier + + ", startTlsEnabled=" + + startTlsEnabled + + ", hostnameVerificationEnabled=" + + hostnameVerificationEnabled + + ", trustAll=" + + trustAll + + ", effectiveTruststore=" + + effectiveTruststore + + ", effectiveTruststoreAliases=" + + effectiveTruststoreAliases + + ", effectiveKeystore=" + + effectiveKeystore + + ", effectiveKeyAlias=" + + effectiveKeyAlias + + "]"; } public boolean isTrustAllEnabled() { @@ -511,8 +566,7 @@ public SSLConfigException() { super(); } - public SSLConfigException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { + public SSLConfigException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } @@ -532,23 +586,26 @@ public SSLConfigException(Throwable cause) { private static class OverlyTrustfulSSLContextBuilder extends SSLContextBuilder { @Override - protected void initSSLContext(SSLContext sslContext, Collection keyManagers, - Collection trustManagers, SecureRandom secureRandom) throws KeyManagementException { - sslContext.init(!keyManagers.isEmpty() ? keyManagers.toArray(new KeyManager[keyManagers.size()]) : null, - new TrustManager[] { new OverlyTrustfulTrustManager() }, secureRandom); + protected void initSSLContext( + SSLContext sslContext, + Collection keyManagers, + Collection trustManagers, + SecureRandom secureRandom + ) throws KeyManagementException { + sslContext.init( + !keyManagers.isEmpty() ? keyManagers.toArray(new KeyManager[keyManagers.size()]) : null, + new TrustManager[] { new OverlyTrustfulTrustManager() }, + secureRandom + ); } } private static class OverlyTrustfulTrustManager implements X509TrustManager { @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } + public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {} @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } + public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {} @Override public X509Certificate[] getAcceptedIssuers() { diff --git a/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfiguratorV4.java b/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfiguratorV4.java index 013d8b70d7..c2de5d95a2 100644 --- a/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfiguratorV4.java +++ b/src/main/java/com/amazon/dlic/util/SettingsBasedSSLConfiguratorV4.java @@ -96,8 +96,7 @@ public class SettingsBasedSSLConfiguratorV4 { private String effectiveKeyAlias; private List effectiveTruststoreAliases; - public SettingsBasedSSLConfiguratorV4(Settings settings, Path configPath, String settingsKeyPrefix, - String clientName) { + public SettingsBasedSSLConfiguratorV4(Settings settings, Path configPath, String settingsKeyPrefix, String clientName) { this.settings = settings; this.configPath = configPath; this.settingsKeyPrefix = normalizeSettingsKeyPrefix(settingsKeyPrefix); @@ -137,10 +136,20 @@ public SSLConfig buildSSLConfig() throws SSLConfigException { return null; } - return new SSLConfig(sslContext, getSupportedProtocols(), getSupportedCipherSuites(), getHostnameVerifier(), - isHostnameVerificationEnabled(), isTrustAllEnabled(), isStartTlsEnabled(), this.effectiveTruststore, - this.effectiveTruststoreAliases, this.effectiveKeystore, this.effectiveKeyPassword, - this.effectiveKeyAlias); + return new SSLConfig( + sslContext, + getSupportedProtocols(), + getSupportedCipherSuites(), + getHostnameVerifier(), + isHostnameVerificationEnabled(), + isTrustAllEnabled(), + isStartTlsEnabled(), + this.effectiveTruststore, + this.effectiveTruststoreAliases, + this.effectiveKeystore, + this.effectiveKeyPassword, + this.effectiveKeyAlias + ); } private boolean isHostnameVerificationEnabled() { @@ -182,7 +191,7 @@ private void configureWithSettings() throws SSLConfigException, NoSuchAlgorithmE this.enableSslClientAuth = getSettingAsBoolean(ENABLE_SSL_CLIENT_AUTH, false); if (settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, null) != null - || settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, null) != null) { + || settings.get(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, null) != null) { initFromPem(); } else { initFromKeyStore(); @@ -195,22 +204,21 @@ private void configureWithSettings() throws SSLConfigException, NoSuchAlgorithmE if (enableSslClientAuth) { if (effectiveKeystore != null) { try { - sslContextBuilder.loadKeyMaterial(effectiveKeystore, effectiveKeyPassword, - new PrivateKeyStrategy() { - - @Override - public String chooseAlias(Map aliases, Socket socket) { - if (aliases == null || aliases.isEmpty()) { - return effectiveKeyAlias; - } - - if (effectiveKeyAlias == null || effectiveKeyAlias.isEmpty()) { - return aliases.keySet().iterator().next(); - } - - return effectiveKeyAlias; - } - }); + sslContextBuilder.loadKeyMaterial(effectiveKeystore, effectiveKeyPassword, new PrivateKeyStrategy() { + + @Override + public String chooseAlias(Map aliases, Socket socket) { + if (aliases == null || aliases.isEmpty()) { + return effectiveKeyAlias; + } + + if (effectiveKeyAlias == null || effectiveKeyAlias.isEmpty()) { + return aliases.keySet().iterator().next(); + } + + return effectiveKeyAlias; + } + }); } catch (UnrecoverableKeyException e) { throw new RuntimeException(e); } @@ -224,22 +232,25 @@ private void initFromPem() throws SSLConfigException { try { trustCertificates = PemKeyReader.loadCertificatesFromStream( - PemKeyReader.resolveStream(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, settings)); + PemKeyReader.resolveStream(settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT, settings) + ); } catch (Exception e) { throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT + " for " + this.clientName, - e); + "Error loading PEM from " + settingsKeyPrefix + PEMTRUSTEDCAS_CONTENT + " for " + this.clientName, + e + ); } if (trustCertificates == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, settings, configPath, - !isTrustAllEnabled()); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH, settings, configPath, !isTrustAllEnabled()); try { trustCertificates = PemKeyReader.loadCertificatesFromFile(path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMTRUSTEDCAS_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMTRUSTEDCAS_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -248,21 +259,22 @@ private void initFromPem() throws SSLConfigException { try { authenticationCertificate = PemKeyReader.loadCertificatesFromStream( - PemKeyReader.resolveStream(settingsKeyPrefix + PEMCERT_CONTENT, settings)); + PemKeyReader.resolveStream(settingsKeyPrefix + PEMCERT_CONTENT, settings) + ); } catch (Exception e) { - throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMCERT_CONTENT + " for " + this.clientName, e); + throw new SSLConfigException("Error loading PEM from " + settingsKeyPrefix + PEMCERT_CONTENT + " for " + this.clientName, e); } if (authenticationCertificate == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMCERT_FILEPATH, settings, configPath, - enableSslClientAuth); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMCERT_FILEPATH, settings, configPath, enableSslClientAuth); try { authenticationCertificate = PemKeyReader.loadCertificatesFromFile(path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMCERT_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMCERT_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -270,22 +282,24 @@ private void initFromPem() throws SSLConfigException { PrivateKey authenticationKey; try { - authenticationKey = PemKeyReader.loadKeyFromStream(getSetting(PEMKEY_PASSWORD), - PemKeyReader.resolveStream(settingsKeyPrefix + PEMKEY_CONTENT, settings)); + authenticationKey = PemKeyReader.loadKeyFromStream( + getSetting(PEMKEY_PASSWORD), + PemKeyReader.resolveStream(settingsKeyPrefix + PEMKEY_CONTENT, settings) + ); } catch (Exception e) { - throw new SSLConfigException( - "Error loading PEM from " + settingsKeyPrefix + PEMKEY_CONTENT + " for " + this.clientName, e); + throw new SSLConfigException("Error loading PEM from " + settingsKeyPrefix + PEMKEY_CONTENT + " for " + this.clientName, e); } if (authenticationKey == null) { - String path = PemKeyReader.resolve(settingsKeyPrefix + PEMKEY_FILEPATH, settings, configPath, - enableSslClientAuth); + String path = PemKeyReader.resolve(settingsKeyPrefix + PEMKEY_FILEPATH, settings, configPath, enableSslClientAuth); try { authenticationKey = PemKeyReader.loadKeyFromFile(getSetting(PEMKEY_PASSWORD), path); } catch (Exception e) { - throw new SSLConfigException("Error loading PEM from " + path + " (" + settingsKeyPrefix - + PEMKEY_FILEPATH + ") for " + this.clientName, e); + throw new SSLConfigException( + "Error loading PEM from " + path + " (" + settingsKeyPrefix + PEMKEY_FILEPATH + ") for " + this.clientName, + e + ); } } @@ -293,8 +307,12 @@ private void initFromPem() throws SSLConfigException { effectiveKeyPassword = PemKeyReader.randomChars(12); effectiveKeyAlias = "al"; effectiveTruststore = PemKeyReader.toTruststore(effectiveKeyAlias, trustCertificates); - effectiveKeystore = PemKeyReader.toKeystore(effectiveKeyAlias, effectiveKeyPassword, - authenticationCertificate, authenticationKey); + effectiveKeystore = PemKeyReader.toKeystore( + effectiveKeyAlias, + effectiveKeyPassword, + authenticationCertificate, + authenticationKey + ); } catch (Exception e) { throw new SSLConfigException("Error initializing SSLConfig for " + this.clientName, e); } @@ -307,13 +325,20 @@ private void initFromKeyStore() throws SSLConfigException { try { trustStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, settings, - configPath, !isTrustAllEnabled()), - SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE)); + PemKeyReader.resolve( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + settings, + configPath, + !isTrustAllEnabled() + ), + SECURITY_SSL_TRANSPORT_TRUSTSTORE_PASSWORD.getSetting(settings), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_TYPE) + ); } catch (Exception e) { - throw new SSLConfigException("Error loading trust store from " - + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH), e); + throw new SSLConfigException( + "Error loading trust store from " + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH), + e + ); } effectiveTruststoreAliases = getSettingAsList(CA_ALIAS, null); @@ -322,20 +347,24 @@ private void initFromKeyStore() throws SSLConfigException { try { keyStore = PemKeyReader.loadKeyStore( - PemKeyReader.resolve(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, settings, - configPath, enableSslClientAuth), - SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, - SSLConfigConstants.DEFAULT_STORE_PASSWORD), - settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE)); + PemKeyReader.resolve( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, + settings, + configPath, + enableSslClientAuth + ), + SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD), + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE) + ); } catch (Exception e) { - throw new SSLConfigException("Error loading key store from " - + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH), e); + throw new SSLConfigException( + "Error loading key store from " + settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH), + e + ); } - String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD - .getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD); - effectiveKeyPassword = keyStorePassword == null || keyStorePassword.isEmpty() ? null - : keyStorePassword.toCharArray(); + String keyStorePassword = SECURITY_SSL_TRANSPORT_KEYSTORE_PASSWORD.getSetting(settings, SSLConfigConstants.DEFAULT_STORE_PASSWORD); + effectiveKeyPassword = keyStorePassword == null || keyStorePassword.isEmpty() ? null : keyStorePassword.toCharArray(); effectiveKeyAlias = getSetting(CERT_ALIAS); if (enableSslClientAuth && effectiveKeyAlias == null) { @@ -394,10 +423,20 @@ public static class SSLConfig { private final char[] effectiveKeyPassword; private final String effectiveKeyAlias; - public SSLConfig(SSLContext sslContext, String[] supportedProtocols, String[] supportedCipherSuites, - HostnameVerifier hostnameVerifier, boolean hostnameVerificationEnabled, boolean trustAll, - boolean startTlsEnabled, KeyStore effectiveTruststore, List effectiveTruststoreAliases, - KeyStore effectiveKeystore, char[] effectiveKeyPassword, String effectiveKeyAlias) { + public SSLConfig( + SSLContext sslContext, + String[] supportedProtocols, + String[] supportedCipherSuites, + HostnameVerifier hostnameVerifier, + boolean hostnameVerificationEnabled, + boolean trustAll, + boolean startTlsEnabled, + KeyStore effectiveTruststore, + List effectiveTruststoreAliases, + KeyStore effectiveKeystore, + char[] effectiveKeyPassword, + String effectiveKeyAlias + ) { this.sslContext = sslContext; this.supportedProtocols = supportedProtocols; this.supportedCipherSuites = supportedCipherSuites; @@ -437,8 +476,7 @@ public SSLIOSessionStrategy toSSLIOSessionStrategy() { } public SSLConnectionSocketFactory toSSLConnectionSocketFactory() { - return new SSLConnectionSocketFactory(sslContext, supportedProtocols, supportedCipherSuites, - hostnameVerifier); + return new SSLConnectionSocketFactory(sslContext, supportedProtocols, supportedCipherSuites, hostnameVerifier); } public boolean isStartTlsEnabled() { @@ -495,12 +533,29 @@ public String[] getEffectiveKeyAliasesArray() { @Override public String toString() { - return "SSLConfig [sslContext=" + sslContext + ", supportedProtocols=" + Arrays.toString(supportedProtocols) - + ", supportedCipherSuites=" + Arrays.toString(supportedCipherSuites) + ", hostnameVerifier=" - + hostnameVerifier + ", startTlsEnabled=" + startTlsEnabled + ", hostnameVerificationEnabled=" - + hostnameVerificationEnabled + ", trustAll=" + trustAll + ", effectiveTruststore=" - + effectiveTruststore + ", effectiveTruststoreAliases=" + effectiveTruststoreAliases - + ", effectiveKeystore=" + effectiveKeystore + ", effectiveKeyAlias=" + effectiveKeyAlias + "]"; + return "SSLConfig [sslContext=" + + sslContext + + ", supportedProtocols=" + + Arrays.toString(supportedProtocols) + + ", supportedCipherSuites=" + + Arrays.toString(supportedCipherSuites) + + ", hostnameVerifier=" + + hostnameVerifier + + ", startTlsEnabled=" + + startTlsEnabled + + ", hostnameVerificationEnabled=" + + hostnameVerificationEnabled + + ", trustAll=" + + trustAll + + ", effectiveTruststore=" + + effectiveTruststore + + ", effectiveTruststoreAliases=" + + effectiveTruststoreAliases + + ", effectiveKeystore=" + + effectiveKeystore + + ", effectiveKeyAlias=" + + effectiveKeyAlias + + "]"; } public boolean isTrustAllEnabled() { @@ -516,8 +571,7 @@ public SSLConfigException() { super(); } - public SSLConfigException(String message, Throwable cause, boolean enableSuppression, - boolean writableStackTrace) { + public SSLConfigException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } @@ -537,23 +591,26 @@ public SSLConfigException(Throwable cause) { private static class OverlyTrustfulSSLContextBuilder extends SSLContextBuilder { @Override - protected void initSSLContext(SSLContext sslContext, Collection keyManagers, - Collection trustManagers, SecureRandom secureRandom) throws KeyManagementException { - sslContext.init(!keyManagers.isEmpty() ? keyManagers.toArray(new KeyManager[keyManagers.size()]) : null, - new TrustManager[] { new OverlyTrustfulTrustManager() }, secureRandom); + protected void initSSLContext( + SSLContext sslContext, + Collection keyManagers, + Collection trustManagers, + SecureRandom secureRandom + ) throws KeyManagementException { + sslContext.init( + !keyManagers.isEmpty() ? keyManagers.toArray(new KeyManager[keyManagers.size()]) : null, + new TrustManager[] { new OverlyTrustfulTrustManager() }, + secureRandom + ); } } private static class OverlyTrustfulTrustManager implements X509TrustManager { @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } + public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {} @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) - throws CertificateException { - } + public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {} @Override public X509Certificate[] getAcceptedIssuers() { diff --git a/src/main/java/org/opensearch/security/DefaultObjectMapper.java b/src/main/java/org/opensearch/security/DefaultObjectMapper.java index 7c3168c68a..774af04bfa 100644 --- a/src/main/java/org/opensearch/security/DefaultObjectMapper.java +++ b/src/main/java/org/opensearch/security/DefaultObjectMapper.java @@ -54,7 +54,7 @@ public class DefaultObjectMapper { public static final ObjectMapper objectMapper = new ObjectMapper(); public final static ObjectMapper YAML_MAPPER = new ObjectMapper(new YAMLFactory()); private static final ObjectMapper defaulOmittingObjectMapper = new ObjectMapper(); - + static { objectMapper.setSerializationInclusion(Include.NON_NULL); //objectMapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS); @@ -116,7 +116,7 @@ public T run() throws Exception { throw (IOException) e.getCause(); } } - + @SuppressWarnings("removal") public static T readValue(String string, Class clazz) throws IOException { @@ -137,7 +137,7 @@ public T run() throws Exception { throw (IOException) e.getCause(); } } - + @SuppressWarnings("removal") public static JsonNode readTree(String string) throws IOException { diff --git a/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java b/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java index 29c5b6c9a1..0e6944e9c4 100644 --- a/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java +++ b/src/main/java/org/opensearch/security/action/configupdate/ConfigUpdateNodeResponse.java @@ -37,10 +37,10 @@ import org.opensearch.core.xcontent.XContentBuilder; public class ConfigUpdateNodeResponse extends BaseNodeResponse implements ToXContentObject { - + private String[] updatedConfigTypes; private String message; - + public ConfigUpdateNodeResponse(StreamInput in) throws IOException { super(in); this.updatedConfigTypes = in.readStringArray(); @@ -52,11 +52,11 @@ public ConfigUpdateNodeResponse(final DiscoveryNode node, String[] updatedConfig this.updatedConfigTypes = updatedConfigTypes; this.message = message; } - + public static ConfigUpdateNodeResponse readNodeResponse(StreamInput in) throws IOException { return new ConfigUpdateNodeResponse(in); } - + public String[] getUpdatedConfigTypes() { return updatedConfigTypes==null?null:Arrays.copyOf(updatedConfigTypes, updatedConfigTypes.length); } @@ -64,7 +64,7 @@ public String[] getUpdatedConfigTypes() { public String getMessage() { return message; } - + @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java b/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java index 42879a8b6c..c5c60cf8a6 100644 --- a/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java +++ b/src/main/java/org/opensearch/security/action/configupdate/TransportConfigUpdateAction.java @@ -57,12 +57,12 @@ public class TransportConfigUpdateAction private final Provider backendRegistry; private final ConfigurationRepository configurationRepository; private DynamicConfigFactory dynamicConfigFactory; - + @Inject public TransportConfigUpdateAction(final Settings settings, final ThreadPool threadPool, final ClusterService clusterService, final TransportService transportService, final ConfigurationRepository configurationRepository, final ActionFilters actionFilters, - Provider backendRegistry, DynamicConfigFactory dynamicConfigFactory) { + Provider backendRegistry, DynamicConfigFactory dynamicConfigFactory) { super(ConfigUpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, ConfigUpdateRequest::new, TransportConfigUpdateAction.NodeConfigUpdateRequest::new, ThreadPool.Names.MANAGEMENT, ConfigUpdateNodeResponse.class); @@ -96,14 +96,14 @@ public void writeTo(final StreamOutput out) throws IOException { protected ConfigUpdateNodeResponse newNodeResponse(StreamInput in) throws IOException { return new ConfigUpdateNodeResponse(in); } - + @Override protected ConfigUpdateResponse newResponse(ConfigUpdateRequest request, List responses, List failures) { return new ConfigUpdateResponse(this.clusterService.getClusterName(), responses, failures); } - + @Override protected ConfigUpdateNodeResponse nodeOperation(final NodeConfigUpdateRequest request) { configurationRepository.reloadConfiguration(CType.fromStringValues((request.request.getConfigTypes()))); diff --git a/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java b/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java index 897843ca92..901800f0a2 100644 --- a/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java +++ b/src/main/java/org/opensearch/security/action/whoami/TransportWhoAmIAction.java @@ -65,10 +65,10 @@ protected void doExecute(Task task, WhoAmIRequest request, ActionListener { +ActionRequestBuilder { public WhoAmIRequestBuilder(final ClusterAdminClient client) throws IOException { this(client, WhoAmIAction.INSTANCE); } diff --git a/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java b/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java index 876079dced..2b25344f76 100644 --- a/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java +++ b/src/main/java/org/opensearch/security/action/whoami/WhoAmIResponse.java @@ -37,12 +37,12 @@ import org.opensearch.core.xcontent.XContentBuilder; public class WhoAmIResponse extends ActionResponse implements ToXContent { - + private String dn; private boolean isAdmin; private boolean isAuthenticated; private boolean isNodeCertificateRequest; - + public WhoAmIResponse(String dn, boolean isAdmin, boolean isAuthenticated, boolean isNodeCertificateRequest) { this.dn = dn; this.isAdmin = isAdmin; @@ -93,8 +93,8 @@ public boolean isNodeCertificateRequest() { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - - builder.startObject("whoami"); + + builder.startObject("whoami"); builder.field("dn", dn); builder.field("is_admin", isAdmin); builder.field("is_authenticated", isAuthenticated); diff --git a/src/main/java/org/opensearch/security/auditlog/AuditLog.java b/src/main/java/org/opensearch/security/auditlog/AuditLog.java index a35bfaa209..128944e387 100644 --- a/src/main/java/org/opensearch/security/auditlog/AuditLog.java +++ b/src/main/java/org/opensearch/security/auditlog/AuditLog.java @@ -74,7 +74,7 @@ public interface AuditLog extends Closeable { // set config void setConfig(AuditConfig auditConfig); - + public enum Origin { REST, TRANSPORT, LOCAL } diff --git a/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java b/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java index 5fb11102a8..1152abe89e 100644 --- a/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java +++ b/src/main/java/org/opensearch/security/auditlog/config/AuditConfig.java @@ -275,7 +275,7 @@ static Set fromSettingStringSet(final Settings settings, FilterEntries f final boolean foundDefault = stringSetOfKey.stream().anyMatch(defaultDetectorValue::equals); if (!foundDefault) { - return stringSetOfKey; + return stringSetOfKey; } // Fallback to the legacy keyname diff --git a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java index 6495c8e2c9..b835078aa3 100644 --- a/src/main/java/org/opensearch/security/auth/AuthFailureListener.java +++ b/src/main/java/org/opensearch/security/auth/AuthFailureListener.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth; diff --git a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java index 5762cd371a..0296f56a4a 100644 --- a/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthenticationBackend.java @@ -43,13 +43,13 @@ * Instead catch all exceptions and log a appropriate error message. A logger can be instantiated like: *

* {@code private final Logger log = LogManager.getLogger(this.getClass());} - * + * *

*/ public interface AuthenticationBackend { /** - * The type (name) of the authenticator. Only for logging. + * The type (name) of the authenticator. Only for logging. * @return the type */ String getType(); @@ -58,20 +58,20 @@ public interface AuthenticationBackend { * Validate credentials and return an authenticated user (or throw an OpenSearchSecurityException) *

* Results of this method are normally cached so that we not need to query the backend for every authentication attempt. - *

+ *

* @param The credentials to be validated, never null * @return the authenticated User, never null * @throws OpenSearchSecurityException in case an authentication failure * (when credentials are incorrect, the user does not exist or the backend is not reachable) */ User authenticate(AuthCredentials credentials) throws OpenSearchSecurityException; - + /** - * + * * Lookup for a specific user in the authentication backend - * + * * @param user The user for which the authentication backend should be queried. If the authentication backend supports - * user attributes in combination with impersonation the attributes needs to be added to user by calling {@code user.addAttributes()} + * user attributes in combination with impersonation the attributes needs to be added to user by calling {@code user.addAttributes()} * @return true if the user exists in the authentication backend, false otherwise. Before return call {@code user.addAttributes()} as explained above. */ boolean exists(User user); diff --git a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java index 83bf131a62..3aea412e69 100644 --- a/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java +++ b/src/main/java/org/opensearch/security/auth/AuthorizationBackend.java @@ -49,7 +49,7 @@ public interface AuthorizationBackend { /** - * The type (name) of the authorizer. Only for logging. + * The type (name) of the authorizer. Only for logging. * @return the type */ String getType(); @@ -61,7 +61,7 @@ public interface AuthorizationBackend { *

* @param user The authenticated user to populate with backend roles, never null * @param credentials Credentials to authenticate to the authorization backend, maybe null. - * This parameter is for future usage, currently always empty credentials are passed! + * This parameter is for future usage, currently always empty credentials are passed! * @throws OpenSearchSecurityException in case when the authorization backend cannot be reached * or the {@code credentials} are insufficient to authenticate to the authorization backend. */ diff --git a/src/main/java/org/opensearch/security/auth/BackendRegistry.java b/src/main/java/org/opensearch/security/auth/BackendRegistry.java index 635811a7ae..51e93978bd 100644 --- a/src/main/java/org/opensearch/security/auth/BackendRegistry.java +++ b/src/main/java/org/opensearch/security/auth/BackendRegistry.java @@ -181,7 +181,7 @@ public boolean authenticate(final RestRequest request, final RestChannel channel if (isDebugEnabled) { log.debug("Rejecting REST request because of blocked address: {}", request.getHttpChannel().getRemoteAddress()); } - + channel.sendResponse(new BytesRestResponse(RestStatus.UNAUTHORIZED, "Authentication finally failed")); return false; @@ -200,14 +200,14 @@ public boolean authenticate(final RestRequest request, final RestChannel channel // ThreadContext injected user return true; } - + if (!isInitialized()) { log.error("Not yet initialized (you may need to run securityadmin)"); channel.sendResponse(new BytesRestResponse(RestStatus.SERVICE_UNAVAILABLE, "OpenSearch Security not initialized.")); return false; } - + final TransportAddress remoteAddress = xffResolver.resolve(request); final boolean isTraceEnabled = log.isTraceEnabled(); if (isTraceEnabled) { @@ -291,7 +291,7 @@ public boolean authenticate(final RestRequest request, final RestChannel channel } } - //http completed + //http completed authenticatedUser = authcz(userCache, restRoleCache, ac, authDomain.getBackend(), restAuthorizers); if(authenticatedUser == null) { @@ -479,7 +479,7 @@ private User authcz(final Cache cache, Cache * A HTTP authenticator extracts {@link AuthCredentials} from a {@link RestRequest} *

- * + * * Implementation classes must provide a public constructor *

* {@code public MyHTTPAuthenticator(org.opensearch.common.settings.Settings settings, java.nio.file.Path configPath)} @@ -51,14 +51,14 @@ public interface HTTPAuthenticator { /** - * The type (name) of the authenticator. Only for logging. + * The type (name) of the authenticator. Only for logging. * @return the type */ String getType(); - + /** * Extract {@link AuthCredentials} from {@link RestRequest} - * + * * @param request The rest request * @param context The current thread context * @return The authentication credentials (complete or incomplete) or null when no credentials are found in the request @@ -68,17 +68,17 @@ public interface HTTPAuthenticator { * @throws OpenSearchSecurityException */ AuthCredentials extractCredentials(RestRequest request, ThreadContext context) throws OpenSearchSecurityException; - + /** * If the {@code extractCredentials()} call was not successful or the authentication flow needs another roundtrip this method * will be called. If the custom HTTP authenticator does not support this method is a no-op and false should be returned. - * + * * If the custom HTTP authenticator does support re-request authentication or supports authentication flows with multiple roundtrips * then the response should be sent (through the channel) and true must be returned. - * + * * @param channel The rest channel to sent back the response via {@code channel.sendResponse()} * @param credentials The credentials from the prior authentication attempt - * @return false if re-request is not supported/necessary, true otherwise. + * @return false if re-request is not supported/necessary, true otherwise. * If true is returned {@code channel.sendResponse()} must be called so that the request completes. */ boolean reRequestAuthentication(final RestChannel channel, AuthCredentials credentials); diff --git a/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java b/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java index a5eba40353..e74c3ad70a 100644 --- a/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java +++ b/src/main/java/org/opensearch/security/auth/blocking/ClientBlockRegistry.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.blocking; diff --git a/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java b/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java index 363645cd90..450dda54db 100644 --- a/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java +++ b/src/main/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistry.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.blocking; diff --git a/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java index 3f603437a0..a4d596b61d 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AbstractRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; diff --git a/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java index 42f1d1f165..35a6571f8f 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; diff --git a/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java b/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java index 7fe5ac05d6..3fd0c12246 100644 --- a/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java +++ b/src/main/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiter.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; diff --git a/src/main/java/org/opensearch/security/configuration/AdminDNs.java b/src/main/java/org/opensearch/security/configuration/AdminDNs.java index ced262d543..72a4485e9f 100644 --- a/src/main/java/org/opensearch/security/configuration/AdminDNs.java +++ b/src/main/java/org/opensearch/security/configuration/AdminDNs.java @@ -62,7 +62,7 @@ public AdminDNs(final Settings settings) { this.injectAdminUserEnabled = settings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, false); final List adminDnsA = settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Collections.emptyList()); - + for (String dn:adminDnsA) { try { log.debug("{} is registered as an admin dn", dn); @@ -73,13 +73,13 @@ public AdminDNs(final Settings settings) { if (log.isDebugEnabled()) { log.debug("Admin DN not an LDAP name, but admin user injection enabled. Will add {} to admin usernames", dn); } - adminUsernames.add(dn); + adminUsernames.add(dn); } else { - log.error("Unable to parse admin dn {}",dn, e); + log.error("Unable to parse admin dn {}",dn, e); } } } - + log.debug("Loaded {} admin DN's {}",adminDn.size(), adminDn); final Settings impersonationDns = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_IMPERSONATION_DN+"."); @@ -95,7 +95,7 @@ public AdminDNs(final Settings settings) { ); log.debug("Loaded {} impersonation DN's {}", allowedDnsImpersonations.size(), allowedDnsImpersonations); - + final Settings impersonationUsersRest = settings.getByPrefix(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+"."); allowedRestImpersonations = impersonationUsersRest.keySet().stream() @@ -103,9 +103,9 @@ public AdminDNs(final Settings settings) { ImmutableMap.toImmutableMap( Function.identity(), user -> WildcardMatcher.from(settings.getAsList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+"."+user)) - ) - ); - + ) + ); + log.debug("Loaded {} impersonation users for REST {}",allowedRestImpersonations.size(), allowedRestImpersonations); } @@ -129,11 +129,11 @@ public boolean isAdmin(User user) { } return false; } - + public boolean isAdminDN(String dn) { - + if(dn == null) return false; - + try { return isAdminDN(new LdapName(dn)); } catch (InvalidNameException e) { @@ -143,16 +143,16 @@ public boolean isAdminDN(String dn) { private boolean isAdminDN(LdapName dn) { if(dn == null) return false; - + boolean isAdmin = adminDn.contains(dn); - + if (log.isTraceEnabled()) { log.trace("Is principal {} an admin cert? {}", dn.toString(), isAdmin); } - + return isAdmin; } - + public boolean isRestImpersonationAllowed(final String originalUser, final String impersonated) { return (originalUser != null) ? allowedRestImpersonations.getOrDefault(originalUser, WildcardMatcher.NONE).test(impersonated) : false; } diff --git a/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java b/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java index 61877f2bf2..1c42321986 100644 --- a/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java +++ b/src/main/java/org/opensearch/security/configuration/ClusterInfoHolder.java @@ -40,7 +40,7 @@ public class ClusterInfoHolder implements ClusterStateListener { private volatile DiscoveryNodes nodes = null; private volatile Boolean isLocalNodeElectedClusterManager = null; private volatile boolean initialized; - + @Override public void clusterChanged(ClusterChangedEvent event) { if(nodes == null || event.nodesChanged()) { @@ -50,7 +50,7 @@ public void clusterChanged(ClusterChangedEvent event) { } initialized = true; } - + isLocalNodeElectedClusterManager = event.localNodeClusterManager()?Boolean.TRUE:Boolean.FALSE; } @@ -69,7 +69,7 @@ public Boolean hasNode(DiscoveryNode node) { } return null; } - + return nodes.nodeExists(node)?Boolean.TRUE:Boolean.FALSE; } } diff --git a/src/main/java/org/opensearch/security/configuration/CompatConfig.java b/src/main/java/org/opensearch/security/configuration/CompatConfig.java index 6912cb4fbb..48f91b10be 100644 --- a/src/main/java/org/opensearch/security/configuration/CompatConfig.java +++ b/src/main/java/org/opensearch/security/configuration/CompatConfig.java @@ -50,13 +50,13 @@ public CompatConfig(final Environment environment, final OpensearchDynamicSettin this.staticSettings = environment.settings(); this.transportPassiveAuthSetting = transportPassiveAuthSetting; } - + @Subscribe public void onDynamicConfigModelChanged(DynamicConfigModel dcm) { this.dcm = dcm; log.debug("dynamicSecurityConfig updated?: {}", (dcm != null)); } - + //true is default public boolean restAuthEnabled() { final boolean restInitiallyDisabled = staticSettings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_DISABLE_REST_AUTH_INITIALLY, false); @@ -79,7 +79,7 @@ public boolean restAuthEnabled() { } } - + //true is default public boolean transportInterClusterAuthEnabled() { final boolean interClusterAuthInitiallyDisabled = staticSettings.getAsBoolean(ConfigConstants.SECURITY_UNSUPPORTED_DISABLE_INTERTRANSPORT_AUTH_INITIALLY, false); diff --git a/src/main/java/org/opensearch/security/configuration/ConfigCallback.java b/src/main/java/org/opensearch/security/configuration/ConfigCallback.java index d7d1ed0cee..cb8fc1eedf 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigCallback.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigCallback.java @@ -30,7 +30,7 @@ import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration; public interface ConfigCallback { - + void success(SecurityDynamicConfiguration dConf); void noData(String id); void singleFailure(Failure failure); diff --git a/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java b/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java index ea7799e014..c628a3156e 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigUpdateAlreadyInProgressException.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.configuration; diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java index 4aa9fadcae..f5751efcae 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsRequestValve.java @@ -36,7 +36,7 @@ import org.opensearch.threadpool.ThreadPool; public interface DlsFlsRequestValve { - + boolean invoke(String action, ActionRequest request, ActionListener listener, EvaluatedDlsFlsConfig evaluatedDlsFlsConfig, Resolved resolved); void handleSearchContext(SearchContext context, ThreadPool threadPool, NamedXContentRegistry namedXContentRegistry); @@ -61,5 +61,5 @@ public void onQueryPhase(QuerySearchResult queryResult) { } } - + } diff --git a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java index 532f820210..947557d342 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java +++ b/src/main/java/org/opensearch/security/configuration/DlsFlsValveImpl.java @@ -266,7 +266,7 @@ public boolean invoke(String action, ActionRequest request, final ActionListener RestStatus.FORBIDDEN)); return false; } - + if (evaluatedDlsFlsConfig.hasDls()) { if (request instanceof SearchRequest) { @@ -317,7 +317,7 @@ public void handleSearchContext(SearchContext context, ThreadPool threadPool, Na assert context.parsedQuery() != null; final Set unparsedDlsQueries = queries.get(dlsEval); - + if (unparsedDlsQueries != null && !unparsedDlsQueries.isEmpty()) { BooleanQuery.Builder queryBuilder = dlsQueryParser.parse(unparsedDlsQueries, context.getQueryShardContext(), (q) -> new ConstantScoreQuery(q)); @@ -390,7 +390,7 @@ private void setDlsHeaders(EvaluatedDlsFlsConfig dlsFls, ActionRequest request) } else { if (threadContext.getHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER) != null) { Object deserializedDlsQueries = Base64Helper.deserializeObject(threadContext.getHeader(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER)); - if (!dlsQueries.equals(deserializedDlsQueries)) { + if (!dlsQueries.equals(deserializedDlsQueries)) { throw new OpenSearchSecurityException(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER + " does not match (SG 900D)"); } } else { diff --git a/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java b/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java index fd3b3aee98..a5f07541c8 100644 --- a/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java +++ b/src/main/java/org/opensearch/security/configuration/DlsQueryParser.java @@ -99,7 +99,7 @@ public BooleanQuery.Builder parse(Set unparsedDlsQueries, QueryShardCont return dlsQueryBuilder; } - + private static void handleNested(final QueryShardContext queryShardContext, final BooleanQuery.Builder dlsQueryBuilder, final Query parentQuery) { final BitSetProducer parentDocumentsFilter = queryShardContext.bitsetFilter(NON_NESTED_QUERY); @@ -131,7 +131,7 @@ boolean containsTermLookupQuery(Set unparsedQueries) { if (log.isDebugEnabled()) { log.debug("containsTermLookupQuery() returns true due to " + query + "\nqueries: " + unparsedQueries); } - + return true; } } @@ -139,7 +139,7 @@ boolean containsTermLookupQuery(Set unparsedQueries) { if (log.isDebugEnabled()) { log.debug("containsTermLookupQuery() returns false\nqueries: " + unparsedQueries); } - + return false; } @@ -156,5 +156,5 @@ boolean containsTermLookupQuery(String query) { } } - + } diff --git a/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java b/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java index 4b603fa804..79069ef53e 100644 --- a/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java +++ b/src/main/java/org/opensearch/security/configuration/EmptyFilterLeafReader.java @@ -102,7 +102,7 @@ public EmptyDirectoryReader(final DirectoryReader in) throws IOException { protected DirectoryReader doWrapDirectoryReader(final DirectoryReader in) throws IOException { return new EmptyDirectoryReader(in); } - + @Override public CacheHelper getReaderCacheHelper() { return in.getReaderCacheHelper(); diff --git a/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java b/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java index 5e96af6449..ba6a29b08a 100644 --- a/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java +++ b/src/main/java/org/opensearch/security/configuration/InvalidConfigException.java @@ -29,7 +29,7 @@ public class InvalidConfigException extends Exception { /** - * + * */ private static final long serialVersionUID = 1L; diff --git a/src/main/java/org/opensearch/security/configuration/StaticResourceException.java b/src/main/java/org/opensearch/security/configuration/StaticResourceException.java index b4d787aa0f..8574a170bb 100644 --- a/src/main/java/org/opensearch/security/configuration/StaticResourceException.java +++ b/src/main/java/org/opensearch/security/configuration/StaticResourceException.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.configuration; diff --git a/src/main/java/org/opensearch/security/filter/SecurityFilter.java b/src/main/java/org/opensearch/security/filter/SecurityFilter.java index 7bdd5946d5..4dd629c010 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityFilter.java @@ -192,7 +192,7 @@ private void ap if (user != null) { org.apache.logging.log4j.ThreadContext.put("user", user.getName()); } - + if (isActionTraceEnabled()) { String count = ""; @@ -232,12 +232,12 @@ private void ap chain.proceed(task, action, request, listener); return; } - - + + if(immutableIndicesMatcher != WildcardMatcher.NONE) { - + boolean isImmutable = false; - + if(request instanceof BulkShardRequest) { for(BulkItemRequest bsr: ((BulkShardRequest) request).items()) { isImmutable = checkImmutableIndices(bsr.request(), listener); @@ -248,7 +248,7 @@ private void ap } else { isImmutable = checkImmutableIndices(request, listener); } - + if(isImmutable) { return; } @@ -301,7 +301,7 @@ private void ap } final PrivilegesEvaluatorResponse pres = eval.evaluate(user, action, request, task, injectedRoles); - + if (log.isDebugEnabled()) { log.debug(pres.toString()); } @@ -384,7 +384,7 @@ private static boolean isUserAdmin(User user, final AdminDNs adminDns) { } private void attachSourceFieldContext(ActionRequest request) { - + if(request instanceof SearchRequest && SourceFieldsContext.isNeeded((SearchRequest) request)) { if(threadContext.getHeader("_opendistro_security_source_field_context") == null) { final String serializedSourceFieldContext = Base64Helper.serializeObject(new SourceFieldsContext((SearchRequest) request)); @@ -397,7 +397,7 @@ private void attachSourceFieldContext(ActionRequest request) { } } } - + @SuppressWarnings("rawtypes") private boolean checkImmutableIndices(Object request, ActionListener listener) { final boolean isModifyIndexRequest = request instanceof DeleteRequest @@ -413,11 +413,11 @@ private boolean checkImmutableIndices(Object request, ActionListener listener) { listener.onFailure(new OpenSearchSecurityException("Index is immutable", RestStatus.FORBIDDEN)); return true; } - + if ((request instanceof IndexRequest) && isRequestIndexImmutable(request)) { ((IndexRequest) request).opType(OpType.CREATE); } - + return false; } diff --git a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java index 2fec235f3e..a5a23957ed 100644 --- a/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java +++ b/src/main/java/org/opensearch/security/filter/SecurityRestFilter.java @@ -117,7 +117,7 @@ public SecurityRestFilter(final BackendRegistry registry, final AuditLog auditLo */ public RestHandler wrap(RestHandler original, AdminDNs adminDNs) { return new RestHandler() { - + @Override public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception { org.apache.logging.log4j.ThreadContext.clearAll(); @@ -142,7 +142,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha NodeClient client) throws Exception { threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_ORIGIN, Origin.REST.toString()); - + if(HTTPHelper.containsBadHeader(request)) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); log.error(exception.toString()); @@ -150,7 +150,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, exception)); return true; } - + if(SSLRequestHelper.containsBadHeader(threadContext, ConfigConstants.OPENDISTRO_SECURITY_CONFIG_PREFIX)) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); log.error(exception.toString()); @@ -165,7 +165,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha if(sslInfo.getPrincipal() != null) { threadContext.putTransient("_opendistro_security_ssl_principal", sslInfo.getPrincipal()); } - + if(sslInfo.getX509Certs() != null) { threadContext.putTransient("_opendistro_security_ssl_peer_certificates", sslInfo.getX509Certs()); } @@ -178,7 +178,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, e)); return true; } - + if(!compatConfig.restAuthEnabled()) { return false; } @@ -197,7 +197,7 @@ private boolean checkAndAuthenticateRequest(RestRequest request, RestChannel cha org.apache.logging.log4j.ThreadContext.put("user", ((User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER)).getName()); } } - + return false; } diff --git a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java index 35278d261f..30e6134381 100644 --- a/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPBasicAuthenticator.java @@ -47,20 +47,20 @@ public class HTTPBasicAuthenticator implements HTTPAuthenticator { protected final Logger log = LogManager.getLogger(this.getClass()); public HTTPBasicAuthenticator(final Settings settings, final Path configPath) { - + } @Override public AuthCredentials extractCredentials(final RestRequest request, ThreadContext threadContext) { final boolean forceLogin = request.paramAsBoolean("force_login", false); - + if(forceLogin) { return null; } - + final String authorizationHeader = request.header("Authorization"); - + return HTTPHelper.extractCredentials(authorizationHeader, log); } diff --git a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java index 51ff6304b1..373919669d 100644 --- a/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPClientCertAuthenticator.java @@ -48,7 +48,7 @@ import org.opensearch.security.user.AuthCredentials; public class HTTPClientCertAuthenticator implements HTTPAuthenticator { - + protected final Logger log = LogManager.getLogger(this.getClass()); protected final Settings settings; @@ -62,29 +62,29 @@ public AuthCredentials extractCredentials(final RestRequest request, final Threa final String principal = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL); if (!Strings.isNullOrEmpty(principal)) { - + final String usernameAttribute = settings.get("username_attribute"); final String rolesAttribute = settings.get("roles_attribute"); - + try { final LdapName rfc2253dn = new LdapName(principal); String username = principal.trim(); String[] backendRoles = null; - + if(usernameAttribute != null && usernameAttribute.length() > 0) { final List usernames = getDnAttribute(rfc2253dn, usernameAttribute); if(usernames.isEmpty() == false) { username = usernames.get(0); } } - + if(rolesAttribute != null && rolesAttribute.length() > 0) { final List roles = getDnAttribute(rfc2253dn, rolesAttribute); if(roles.isEmpty() == false) { backendRoles = roles.toArray(new String[0]); } } - + return new AuthCredentials(username, backendRoles).markComplete(); } catch (InvalidNameException e) { log.error("Client cert had no properly formed DN (was: {})", principal); @@ -106,8 +106,8 @@ public boolean reRequestAuthentication(final RestChannel channel, AuthCredential public String getType() { return "clientcert"; } - - private List getDnAttribute(LdapName rfc2253dn, String attribute) { + + private List getDnAttribute(LdapName rfc2253dn, String attribute) { final List attrValues = new ArrayList<>(rfc2253dn.size()); final List reverseRdn = new ArrayList<>(rfc2253dn.getRdns()); Collections.reverse(reverseRdn); @@ -117,7 +117,7 @@ private List getDnAttribute(LdapName rfc2253dn, String attribute) { attrValues.add(rdn.getValue().toString()); } } - + return Collections.unmodifiableList(attrValues); } } diff --git a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java index 28fb80e0db..348811b694 100644 --- a/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/HTTPProxyAuthenticator.java @@ -57,14 +57,14 @@ public HTTPProxyAuthenticator(Settings settings, final Path configPath) { @Override public AuthCredentials extractCredentials(final RestRequest request, ThreadContext context) { - + if(context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE) != Boolean.TRUE) { throw new OpenSearchSecurityException("xff not done"); } - + final String userHeader = settings.get("user_header"); final String rolesHeader = settings.get("roles_header"); - + if (log.isDebugEnabled()) { log.debug("Headers {}", request.getHeaders()); log.debug("UserHeader {}, value {}", userHeader, userHeader == null ? null : request.header(userHeader)); diff --git a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java index 404fd2dcc2..5d9e933c8f 100644 --- a/src/main/java/org/opensearch/security/http/RemoteIpDetector.java +++ b/src/main/java/org/opensearch/security/http/RemoteIpDetector.java @@ -120,23 +120,23 @@ String detect(RestRequest request, ThreadContext threadContext){ if (isTraceEnabled) { log.trace("originalRemoteAddr {}", originalRemoteAddr); } - + //X-Forwarded-For: client1, proxy1, proxy2 // ^^^^^^ originalRemoteAddr - + //originalRemoteAddr need to be in the list of internalProxies if (internalProxies !=null && internalProxies.matcher(originalRemoteAddr).matches()) { String remoteIp = null; final StringBuilder concatRemoteIpHeaderValue = new StringBuilder(); - + //client1, proxy1, proxy2 final List remoteIpHeaders = request.getHeaders().get(remoteIpHeader); //X-Forwarded-For if(remoteIpHeaders == null || remoteIpHeaders.isEmpty()) { return originalRemoteAddr; } - + for (String rh:remoteIpHeaders) { if (concatRemoteIpHeaderValue.length() > 0) { concatRemoteIpHeaderValue.append(", "); @@ -144,7 +144,7 @@ String detect(RestRequest request, ThreadContext threadContext){ concatRemoteIpHeaderValue.append(rh); } - + if (isTraceEnabled) { log.trace("concatRemoteIpHeaderValue {}", concatRemoteIpHeaderValue.toString()); } @@ -162,14 +162,14 @@ String detect(RestRequest request, ThreadContext threadContext){ break; } } - + // continue to loop on remoteIpHeaderValue to build the new value of the remoteIpHeader final LinkedList newRemoteIpHeaderValue = new LinkedList<>(); for (; idx >= 0; idx--) { String currentRemoteIp = remoteIpHeaderValue[idx]; newRemoteIpHeaderValue.addFirst(currentRemoteIp); } - + if (remoteIp != null) { if (isTraceEnabled) { final String originalRemoteHost = ((InetSocketAddress)request.getHttpChannel().getRemoteAddress()).getAddress().getHostName(); @@ -178,17 +178,17 @@ String detect(RestRequest request, ThreadContext threadContext){ threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE, Boolean.TRUE); return remoteIp; - + } else { log.warn("Remote ip could not be detected, this should normally not happen"); } - + } else { if (isTraceEnabled) { log.trace("Skip RemoteIpDetector for request {} with originalRemoteAddr '{}' cause no internal proxy matches", request.uri(), request.getHttpChannel().getRemoteAddress()); } } - + return originalRemoteAddr; } diff --git a/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java b/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java index 3d977dcc7e..6f2f57053f 100644 --- a/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/http/SecurityHttpServerTransport.java @@ -39,7 +39,7 @@ import org.opensearch.transport.SharedGroupFactory; public class SecurityHttpServerTransport extends SecuritySSLNettyHttpServerTransport { - + public SecurityHttpServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, final ThreadPool threadPool, final SecurityKeyStore odsks, final SslExceptionHandler sslExceptionHandler, final NamedXContentRegistry namedXContentRegistry, final ValidatingDispatcher dispatcher, final ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { diff --git a/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java b/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java index b05153db4c..3c1dedc55e 100644 --- a/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/http/SecurityNonSslHttpServerTransport.java @@ -54,7 +54,7 @@ public ChannelHandler configureServerChannelHandler() { } protected class NonSslHttpChannelHandler extends Netty4HttpServerTransport.HttpChannelHandler { - + protected NonSslHttpChannelHandler(Netty4HttpServerTransport transport, final HttpHandlingSettings handlingSettings) { super(transport, handlingSettings); } diff --git a/src/main/java/org/opensearch/security/http/XFFResolver.java b/src/main/java/org/opensearch/security/http/XFFResolver.java index 23de8e3676..c44e98537d 100644 --- a/src/main/java/org/opensearch/security/http/XFFResolver.java +++ b/src/main/java/org/opensearch/security/http/XFFResolver.java @@ -47,7 +47,7 @@ public class XFFResolver { private volatile boolean enabled; private volatile RemoteIpDetector detector; private final ThreadContext threadContext; - + public XFFResolver(final ThreadPool threadPool) { super(); this.threadContext = threadPool.getThreadContext(); @@ -58,16 +58,16 @@ public TransportAddress resolve(final RestRequest request) throws OpenSearchSecu if (isTraceEnabled) { log.trace("resolve {}", request.getHttpChannel().getRemoteAddress()); } - + if(enabled && request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress && request.getHttpChannel() instanceof Netty4HttpChannel) { final InetSocketAddress isa = new InetSocketAddress(detector.detect(request, threadContext), ((InetSocketAddress)request.getHttpChannel().getRemoteAddress()).getPort()); - - if(isa.isUnresolved()) { + + if(isa.isUnresolved()) { throw new OpenSearchSecurityException("Cannot resolve address "+isa.getHostString()); } - - + + if (isTraceEnabled) { if(threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_XFF_DONE) == Boolean.TRUE) { log.trace("xff resolved {} to {}", request.getHttpChannel().getRemoteAddress(), isa); @@ -77,7 +77,7 @@ public TransportAddress resolve(final RestRequest request) throws OpenSearchSecu } return new TransportAddress(isa); } else if(request.getHttpChannel().getRemoteAddress() instanceof InetSocketAddress){ - + if (isTraceEnabled) { log.trace("no xff done (enabled or no netty request) {},{},{},{}",enabled, request.getClass()); diff --git a/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java b/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java index d792158fea..e98f26d85a 100644 --- a/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java +++ b/src/main/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticator.java @@ -60,7 +60,7 @@ public AuthCredentials extractCredentials(final RestRequest request, ThreadConte if(credentials == null) { return null; } - + String attrHeaderPrefix = settings.get("attr_header_prefix"); if(Strings.isNullOrEmpty(attrHeaderPrefix)) { log.debug("attr_header_prefix is null. Skipping additional attribute extraction"); @@ -68,7 +68,7 @@ public AuthCredentials extractCredentials(final RestRequest request, ThreadConte } else if(log.isDebugEnabled()) { log.debug("attrHeaderPrefix {}", attrHeaderPrefix); } - + credentials.addAttribute(ATTR_PROXY_USERNAME, credentials.getUsername()); attrHeaderPrefix = attrHeaderPrefix.toLowerCase(); for (Entry> entry : request.getHeaders().entrySet()) { diff --git a/src/main/java/org/opensearch/security/httpclient/HttpClient.java b/src/main/java/org/opensearch/security/httpclient/HttpClient.java index d032ca3544..ad507ea47c 100644 --- a/src/main/java/org/opensearch/security/httpclient/HttpClient.java +++ b/src/main/java/org/opensearch/security/httpclient/HttpClient.java @@ -195,7 +195,7 @@ public boolean index(final String content, final String index, final String type try { final IndexRequest ir = new IndexRequest(index); - + final IndexResponse response = rclient.index(ir .setRefreshPolicy(refresh?RefreshPolicy.IMMEDIATE:RefreshPolicy.NONE) .source(content, XContentType.JSON), RequestOptions.DEFAULT); diff --git a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java index 8bfbb7c0db..129233a007 100644 --- a/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java +++ b/src/main/java/org/opensearch/security/privileges/DocumentAllowList.java @@ -193,7 +193,7 @@ public static class Entry { if (index.indexOf('/') != -1 || index.indexOf('|') != -1) { throw new IllegalArgumentException("Invalid index name: " + index); } - + this.index = index; this.id = id; } diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java index 36d53b2a9e..278dc86b7c 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluator.java @@ -134,7 +134,7 @@ public class PrivilegesEvaluator { private final boolean dfmEmptyOverwritesAll; private DynamicConfigModel dcm; private final NamedXContentRegistry namedXContentRegistry; - + public PrivilegesEvaluator(final ClusterService clusterService, final ThreadPool threadPool, final ConfigurationRepository configurationRepository, final IndexNameExpressionResolver resolver, AuditLog auditLog, final Settings settings, final PrivilegesInterceptor privilegesInterceptor, final ClusterInfoHolder clusterInfoHolder, @@ -309,7 +309,7 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin } presponse.evaluatedDlsFlsConfig = getSecurityRoles(mappedRoles).getDlsFls(user, dfmEmptyOverwritesAll, resolver, clusterService, namedXContentRegistry); - + if (isClusterPerm(action0)) { if(!securityRoles.impliesClusterPermissionPermission(action0)) { @@ -384,7 +384,7 @@ public PrivilegesEvaluatorResponse evaluate(final User user, String action0, fin presponse.allowed = true; return presponse; } - + // term aggregations if (termsAggregationEvaluator.evaluate(requestedResolved, request, clusterService, user, securityRoles, resolver, presponse) .isComplete()) { return presponse; @@ -728,7 +728,7 @@ private boolean checkDocAllowListHeader(User user, String action, ActionRequest if (log.isDebugEnabled()) { log.debug("Request " + request + " is allowed by " + documentAllowList); } - + return true; } else { return false; @@ -739,7 +739,7 @@ private boolean checkDocAllowListHeader(User user, String action, ActionRequest return false; } } - + private List toString(List aliases) { if(aliases == null || aliases.size() == 0) { return Collections.emptyList(); diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java index 8b3e51f045..31ce7095d2 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesEvaluatorResponse.java @@ -42,11 +42,11 @@ public class PrivilegesEvaluatorResponse { PrivilegesEvaluatorResponseState state = PrivilegesEvaluatorResponseState.PENDING; Resolved resolved; CreateIndexRequestBuilder createIndexRequestBuilder; - + public Resolved getResolved() { return resolved; } - + public boolean isAllowed() { return allowed; } @@ -61,11 +61,11 @@ public Set getMissingPrivileges() { public EvaluatedDlsFlsConfig getEvaluatedDlsFlsConfig() { return evaluatedDlsFlsConfig; } - + public CreateIndexRequestBuilder getCreateIndexRequestBuilder() { return createIndexRequestBuilder; } - + public PrivilegesEvaluatorResponse markComplete() { this.state = PrivilegesEvaluatorResponseState.COMPLETE; return this; @@ -89,10 +89,10 @@ public String toString() { return "PrivEvalResponse [allowed=" + allowed + ", missingPrivileges=" + missingPrivileges + ", evaluatedDlsFlsConfig=" + evaluatedDlsFlsConfig + "]"; } - + public static enum PrivilegesEvaluatorResponseState { PENDING, COMPLETE; } - + } diff --git a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java index c76910474f..dd569b05fb 100644 --- a/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java +++ b/src/main/java/org/opensearch/security/privileges/PrivilegesInterceptor.java @@ -65,7 +65,7 @@ protected static ReplaceResult newAccessGrantedReplaceResult(CreateIndexRequestB protected final Client client; protected final ThreadPool threadPool; - public PrivilegesInterceptor(final IndexNameExpressionResolver resolver, final ClusterService clusterService, + public PrivilegesInterceptor(final IndexNameExpressionResolver resolver, final ClusterService clusterService, final Client client, ThreadPool threadPool) { this.resolver = resolver; this.clusterService = clusterService; @@ -77,7 +77,7 @@ public ReplaceResult replaceDashboardsIndex(final ActionRequest request, final S final Resolved requestedResolved, final Map tenants) { throw new RuntimeException("not implemented"); } - + protected final ThreadContext getThreadContext() { return threadPool.getThreadContext(); } diff --git a/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java b/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java index 60456a4eb3..a74ea17ccd 100644 --- a/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluator.java @@ -47,9 +47,9 @@ import org.opensearch.tasks.Task; public class SecurityIndexAccessEvaluator { - + Logger log = LogManager.getLogger(this.getClass()); - + private final String securityIndex; private final AuditLog auditLog; private final WildcardMatcher securityDeniedActionMatcher; @@ -86,7 +86,7 @@ public SecurityIndexAccessEvaluator(final Settings settings, AuditLog auditLog, securityDeniedActionMatcher = WildcardMatcher.from(restoreSecurityIndexEnabled ? securityIndexDeniedActionPatternsList : securityIndexDeniedActionPatternsListNoSnapshot); } - + public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final Task task, final String action, final Resolved requestedResolved, final PrivilegesEvaluatorResponse presponse) { final boolean isDebugEnabled = log.isDebugEnabled(); diff --git a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java index c457b42624..c536ae2d2e 100644 --- a/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/SnapshotRestoreEvaluator.java @@ -47,7 +47,7 @@ public class SnapshotRestoreEvaluator { private final String securityIndex; private final AuditLog auditLog; private final boolean restoreSecurityIndexEnabled; - + public SnapshotRestoreEvaluator(final Settings settings, AuditLog auditLog) { this.enableSnapshotRestorePrivilege = settings.getAsBoolean(ConfigConstants.SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE, ConfigConstants.SECURITY_DEFAULT_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE); @@ -63,27 +63,27 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T if (!(request instanceof RestoreSnapshotRequest)) { return presponse; } - + // snapshot restore for regular users not enabled if (!enableSnapshotRestorePrivilege) { log.warn("{} is not allowed for a regular user", action); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } // if this feature is enabled, users can also snapshot and restore // the Security index and the global state if (restoreSecurityIndexEnabled) { presponse.allowed = true; - return presponse; + return presponse; } - + if (clusterInfoHolder.isLocalNodeElectedClusterManager() == Boolean.FALSE) { presponse.allowed = true; - return presponse.markComplete(); + return presponse.markComplete(); } - + final RestoreSnapshotRequest restoreRequest = (RestoreSnapshotRequest) request; // Do not allow restore of global state @@ -91,7 +91,7 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T auditLog.logSecurityIndexAttempt(request, action, task); log.warn("{} with 'include_global_state' enabled is not allowed", action); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } final List rs = SnapshotRestoreHelper.resolveOriginalIndices(restoreRequest); @@ -100,7 +100,7 @@ public PrivilegesEvaluatorResponse evaluate(final ActionRequest request, final T auditLog.logSecurityIndexAttempt(request, action, task); log.warn("{} for '{}' as source index is not allowed", action, securityIndex); presponse.allowed = false; - return presponse.markComplete(); + return presponse.markComplete(); } return presponse; } diff --git a/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java b/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java index 1d1d048350..53709458fd 100644 --- a/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java +++ b/src/main/java/org/opensearch/security/privileges/TermsAggregationEvaluator.java @@ -56,12 +56,12 @@ public class TermsAggregationEvaluator { "indices:data/read/field_caps*" //"indices:admin/mappings/fields/get*" }; - + private static final QueryBuilder NONE_QUERY = new MatchNoneQueryBuilder(); - + public TermsAggregationEvaluator() { } - + public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final ActionRequest request, ClusterService clusterService, User user, SecurityRoles securityRoles, IndexNameExpressionResolver resolver, PrivilegesEvaluatorResponse presponse) { try { if(request instanceof SearchRequest) { @@ -81,14 +81,14 @@ public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final Actio && ab.getPipelineAggregations().isEmpty() && ab.getSubAggregations().isEmpty()) { - + final Set allPermittedIndices = securityRoles.getAllPermittedIndicesForDashboards(resolved, user, READ_ACTIONS, resolver, clusterService); if(allPermittedIndices == null || allPermittedIndices.isEmpty()) { sr.source().query(NONE_QUERY); } else { sr.source().query(new TermsQueryBuilder("_index", allPermittedIndices)); - } - + } + presponse.allowed = true; return presponse.markComplete(); } @@ -99,7 +99,7 @@ public PrivilegesEvaluatorResponse evaluate(final Resolved resolved, final Actio log.warn("Unable to evaluate terms aggregation",e); return presponse; } - + return presponse; } } diff --git a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java index d2d0685860..5892a91a30 100644 --- a/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java +++ b/src/main/java/org/opensearch/security/resolver/IndexResolverReplacer.java @@ -369,7 +369,7 @@ public final static class Resolved { private final Set remoteIndices; private final boolean isLocalAll; private final IndicesOptions indicesOptions; - + public Resolved(final ImmutableSet aliases, final ImmutableSet allIndices, final ImmutableSet originalRequested, @@ -394,15 +394,15 @@ public Set getAliases() { public Set getAllIndices() { return allIndices; } - + public Set getAllIndicesResolved(ClusterService clusterService, IndexNameExpressionResolver resolver) { - if (isLocalAll) { + if (isLocalAll) { return new HashSet<>(Arrays.asList(resolver.concreteIndexNames(clusterService.state(), indicesOptions, "*"))); - } else { + } else { return allIndices; } } - + public boolean isAllIndicesEmpty() { return allIndices.isEmpty(); } @@ -711,7 +711,7 @@ private boolean getOrReplaceAllIndices(final Object request, final IndicesProvid } private IndicesOptions indicesOptionsFrom(Object localRequest) { - + if(!respectRequestIndicesOptions) { return IndicesOptions.fromOptions(false, true, true, false, true); } diff --git a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java index 0fd88e7565..a7620f6bdc 100644 --- a/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/DashboardsInfoAction.java @@ -92,9 +92,9 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { - + final User user = (User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); builder.startObject(); @@ -131,6 +131,6 @@ public void accept(RestChannel channel) throws Exception { public String getName() { return "Kibana Info Action"; } - - + + } diff --git a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java index b88d2700c9..17d5ee122f 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityHealthAction.java @@ -67,7 +67,7 @@ public List routes() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { return new RestChannelConsumer() { - + final String mode = request.param("mode","strict"); @Override @@ -76,8 +76,8 @@ public void accept(RestChannel channel) throws Exception { RestStatus restStatus = RestStatus.OK; BytesRestResponse response = null; try { - - + + String status = "UP"; String message = null; @@ -98,12 +98,12 @@ public void accept(RestChannel channel) throws Exception { } finally { builder.close(); } - - + + channel.sendResponse(response); } - - + + }; } diff --git a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java index f8e03da5d2..7867e8790d 100644 --- a/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/SecurityInfoAction.java @@ -88,12 +88,12 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { - + final boolean verbose = request.paramAsBoolean("verbose", false); - + final X509Certificate[] certs = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PEER_CERTIFICATES); final User user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); final TransportAddress remoteAddress = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); @@ -112,7 +112,7 @@ public void accept(RestChannel channel) throws Exception { builder.field("principal", (String)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL)); builder.field("peer_certificates", certs != null && certs.length > 0 ? certs.length + "" : "0"); builder.field("sso_logout_url", (String)threadContext.getTransient(ConfigConstants.SSO_LOGOUT_URL)); - + if(user != null && verbose) { try { builder.field("size_of_user", RamUsageEstimator.humanReadableUnits(Base64Helper.serializeObject(user).length())); @@ -122,8 +122,8 @@ public void accept(RestChannel channel) throws Exception { //ignore } } - - + + builder.endObject(); response = new BytesRestResponse(RestStatus.OK, builder); @@ -144,7 +144,7 @@ public void accept(RestChannel channel) throws Exception { } }; } - + @Override public String getName() { return "OpenSearch Security Info Action"; diff --git a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java index 266d2edf49..f7b2a606c6 100644 --- a/src/main/java/org/opensearch/security/rest/TenantInfoAction.java +++ b/src/main/java/org/opensearch/security/rest/TenantInfoAction.java @@ -78,7 +78,7 @@ public class TenantInfoAction extends BaseRestHandler { private final AdminDNs adminDns; private final ConfigurationRepository configurationRepository; - public TenantInfoAction(final Settings settings, final RestController controller, + public TenantInfoAction(final Settings settings, final RestController controller, final PrivilegesEvaluator evaluator, final ThreadPool threadPool, final ClusterService clusterService, final AdminDNs adminDns, final ConfigurationRepository configurationRepository) { super(); @@ -102,18 +102,18 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli public void accept(RestChannel channel) throws Exception { XContentBuilder builder = channel.newBuilder(); //NOSONAR BytesRestResponse response = null; - + try { final User user = (User)threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); - + //only allowed for admins or the kibanaserveruser if(!isAuthorized()) { response = new BytesRestResponse(RestStatus.FORBIDDEN,""); } else { builder.startObject(); - + final SortedMap lookup = clusterService.state().metadata().getIndicesLookup(); for(final String indexOrAlias: lookup.keySet()) { final String tenant = tenantNameForIndex(indexOrAlias); @@ -123,7 +123,7 @@ public void accept(RestChannel channel) throws Exception { } builder.endObject(); - + response = new BytesRestResponse(RestStatus.OK, builder); } } catch (final Exception e1) { @@ -179,21 +179,21 @@ private final SecurityDynamicConfiguration load(final CType config, boolean l private String tenantNameForIndex(String index) { String[] indexParts; - if(index == null + if(index == null || (indexParts = index.split("_")).length != 3 ) { return null; } - - + + if(!indexParts[0].equals(evaluator.dashboardsIndex())) { return null; } - + try { final int expectedHash = Integer.parseInt(indexParts[1]); final String sanitizedName = indexParts[2]; - + for(String tenant: evaluator.getAllConfiguredTenantNames()) { if(tenant.hashCode() == expectedHash && sanitizedName.equals(tenant.toLowerCase().replaceAll("[^a-z0-9]+",""))) { return tenant; @@ -211,6 +211,6 @@ private String tenantNameForIndex(String index) { public String getName() { return "Tenant Info Action"; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java index 987b8fac64..7a978034f1 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV6.java @@ -83,9 +83,9 @@ public ConfigModelV6( SecurityDynamicConfiguration rolesmapping, DynamicConfigModel dcm, Settings opensearchSettings) { - + this.roles = roles; - + try { rolesMappingResolution = ConfigConstants.RolesMappingResolution.valueOf( opensearchSettings.get(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, ConfigConstants.RolesMappingResolution.MAPPING_ONLY.toString()) @@ -94,13 +94,13 @@ public ConfigModelV6( log.error("Cannot apply roles mapping resolution", e); rolesMappingResolution = ConfigConstants.RolesMappingResolution.MAPPING_ONLY; } - + agr = reloadActionGroups(actiongroups); securityRoles = reload(roles); tenantHolder = new TenantHolder(roles); roleMappingHolder = new RoleMappingHolder(rolesmapping, dcm.getHostsResolverMode()); } - + public Set getAllConfiguredTenantNames() { final Set configuredTenants = new HashSet<>(); for (Entry securityRole : roles.getCEntries().entrySet()) { @@ -114,18 +114,18 @@ public Set getAllConfiguredTenantNames() { return Collections.unmodifiableSet(configuredTenants); } - + public SecurityRoles getSecurityRoles() { return securityRoles; } - + private static interface ActionGroupResolver { Set resolvedActions(final List actions); } - + private ActionGroupResolver reloadActionGroups(SecurityDynamicConfiguration actionGroups) { return new ActionGroupResolver() { - + private Set getGroupMembers(final String groupname) { if (actionGroups == null) { @@ -134,27 +134,27 @@ private Set getGroupMembers(final String groupname) { return Collections.unmodifiableSet(resolve(actionGroups, groupname)); } - + private Set resolve(final SecurityDynamicConfiguration actionGroups, final String entry) { - + // SG5 format, plain array //List en = actionGroups.getAsList(DotPath.of(entry)); //if (en.isEmpty()) { // try SG6 format including readonly and permissions key // en = actionGroups.getAsList(DotPath.of(entry + "." + ConfigConstants.CONFIGKEY_ACTION_GROUPS_PERMISSIONS)); //} - + if(!actionGroups.getCEntries().containsKey(entry)) { return Collections.emptySet(); } - + final Set ret = new HashSet(); - + final Object actionGroupAsObject = actionGroups.getCEntries().get(entry); - + if(actionGroupAsObject != null && actionGroupAsObject instanceof List) { - + for (final String perm: ((List) actionGroupAsObject)) { if (actionGroups.getCEntries().keySet().contains(perm)) { ret.addAll(resolve(actionGroups,perm)); @@ -162,8 +162,8 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, ret.add(perm); } } - - + + } else if(actionGroupAsObject != null && actionGroupAsObject instanceof ActionGroupsV6) { for (final String perm: ((ActionGroupsV6) actionGroupAsObject).getPermissions()) { if (actionGroups.getCEntries().keySet().contains(perm)) { @@ -175,10 +175,10 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, } else { throw new RuntimeException("Unable to handle "+actionGroupAsObject); } - + return Collections.unmodifiableSet(ret); } - + @Override public Set resolvedActions(final List actions) { final Set resolvedActions = new HashSet(); @@ -208,7 +208,7 @@ private SecurityRoles reload(SecurityDynamicConfiguration settings) { @Override public SecurityRole call() throws Exception { SecurityRole _securityRole = new SecurityRole(securityRole.getKey()); - + if(securityRole.getValue() == null) { return null; } @@ -261,8 +261,8 @@ public SecurityRole call() throws Exception { _securityRole.addIndexPattern(_indexPattern); } - - + + return _securityRole; } }); @@ -352,7 +352,7 @@ public Set getRoles() { public Set getRoleNames() { return getRoles().stream().map(r -> r.getName()).collect(Collectors.toSet()); } - + public SecurityRoles filter(Set keep) { final SecurityRoles retVal = new SecurityRoles(roles.size()); for (SecurityRole sr : roles) { @@ -371,7 +371,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, final Map> dlsQueries = new HashMap>(); final Map> flsFields = new HashMap>(); final Map> maskedFieldsMap = new HashMap>(); - + for (SecurityRole sr : roles) { for (IndexPattern ip : sr.getIpatterns()) { final Set fls = ip.getFls(); @@ -423,7 +423,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } } } - + if (maskedFields != null && maskedFields.size() > 0) { if (maskedFieldsMap.containsKey(indexPattern)) { @@ -444,7 +444,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } } } - + return new EvaluatedDlsFlsConfig(dlsQueries, flsFields, maskedFieldsMap); } @@ -1010,10 +1010,10 @@ private static boolean impliesTypePerm(Set ipatterns, Resolved res ); } - - + + //####### - + private class TenantHolder { private SetMultimap> tenantsMM = null; @@ -1024,7 +1024,7 @@ public TenantHolder(SecurityDynamicConfiguration roles) { final ExecutorService execs = Executors.newFixedThreadPool(10); for(Entry securityRole: roles.getCEntries().entrySet()) { - + if(securityRole.getValue() == null) { continue; } @@ -1036,7 +1036,7 @@ public Tuple>> call() throws Exception { final Map tenants = securityRole.getValue().getTenants(); if (tenants != null) { - + for (String tenant : tenants.keySet()) { if ("RW".equalsIgnoreCase(tenants.get(tenant))) { @@ -1125,7 +1125,7 @@ private class RoleMappingHolder { private RoleMappingHolder(final SecurityDynamicConfiguration rolesMapping, final String hostResolverMode) { this.hostResolverMode = hostResolverMode; - + if (rolesMapping != null) { users = ArrayListMultimap.create(); @@ -1228,10 +1228,10 @@ private Set map(final User user, final TransportAddress caller) { } } - - - - + + + + public Map mapTenants(User user, Set roles) { return tenantHolder.mapTenants(user, roles); diff --git a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java index 1e2adee1db..560cfb8a6d 100644 --- a/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/ConfigModelV7.java @@ -92,7 +92,7 @@ public ConfigModelV7( this.roles = roles; this.tenants = tenants; - + try { rolesMappingResolution = ConfigConstants.RolesMappingResolution.valueOf( opensearchSettings.get(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, ConfigConstants.RolesMappingResolution.MAPPING_ONLY.toString()) @@ -111,18 +111,18 @@ public ConfigModelV7( public Set getAllConfiguredTenantNames() { return Collections.unmodifiableSet(tenants.getCEntries().keySet()); } - + public SecurityRoles getSecurityRoles() { return securityRoles; } - + private static interface ActionGroupResolver { Set resolvedActions(final List actions); } private ActionGroupResolver reloadActionGroups(SecurityDynamicConfiguration actionGroups) { return new ActionGroupResolver() { - + private Set getGroupMembers(final String groupname) { if (actionGroups == null) { @@ -131,27 +131,27 @@ private Set getGroupMembers(final String groupname) { return Collections.unmodifiableSet(resolve(actionGroups, groupname)); } - + private Set resolve(final SecurityDynamicConfiguration actionGroups, final String entry) { - + // SG5 format, plain array //List en = actionGroups.getAsList(DotPath.of(entry)); //if (en.isEmpty()) { // try SG6 format including readonly and permissions key // en = actionGroups.getAsList(DotPath.of(entry + "." + ConfigConstants.CONFIGKEY_ACTION_GROUPS_PERMISSIONS)); //} - + if(!actionGroups.getCEntries().containsKey(entry)) { return Collections.emptySet(); } - + final Set ret = new HashSet(); - + final Object actionGroupAsObject = actionGroups.getCEntries().get(entry); - + if(actionGroupAsObject != null && actionGroupAsObject instanceof List) { - + for (final String perm: ((List) actionGroupAsObject)) { if (actionGroups.getCEntries().keySet().contains(perm)) { ret.addAll(resolve(actionGroups,perm)); @@ -159,8 +159,8 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, ret.add(perm); } } - - + + } else if(actionGroupAsObject != null && actionGroupAsObject instanceof ActionGroupsV7) { for (final String perm: ((ActionGroupsV7) actionGroupAsObject).getAllowed_actions()) { if (actionGroups.getCEntries().keySet().contains(perm)) { @@ -172,10 +172,10 @@ private Set resolve(final SecurityDynamicConfiguration actionGroups, } else { throw new RuntimeException("Unable to handle "+actionGroupAsObject); } - + return Collections.unmodifiableSet(ret); } - + @Override public Set resolvedActions(final List actions) { final Set resolvedActions = new HashSet(); @@ -205,7 +205,7 @@ private SecurityRoles reload(SecurityDynamicConfiguration settings) { @Override public SecurityRole call() throws Exception { SecurityRole.Builder _securityRole = new SecurityRole.Builder(securityRole.getKey()); - + if(securityRole.getValue() == null) { return null; } @@ -238,21 +238,21 @@ public SecurityRole call() throws Exception { _indexPattern.addFlsFields(fls); _indexPattern.addMaskedFields(maskedFields); _indexPattern.addPerm(agr.resolvedActions(permittedAliasesIndex.getAllowed_actions())); - + /*for(Entry> type: permittedAliasesIndex.getValue().getTypes(-).entrySet()) { TypePerm typePerm = new TypePerm(type.getKey()); final List perms = type.getValue(); typePerm.addPerms(agr.resolvedActions(perms)); _indexPattern.addTypePerms(typePerm); }*/ - + _securityRole.addIndexPattern(_indexPattern); - + } } - - + + return _securityRole.build(); } }); @@ -339,7 +339,7 @@ public String toString() { public Set getRoles() { return Collections.unmodifiableSet(roles); } - + public Set getRoleNames() { return getRoles().stream().map(r -> r.getName()).collect(Collectors.toSet()); } @@ -367,8 +367,8 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, return EvaluatedDlsFlsConfig.EMPTY; } - - Map> dlsQueriesByIndex = new HashMap>(); + + Map> dlsQueriesByIndex = new HashMap>(); Map> flsFields = new HashMap>(); Map> maskedFieldsMap = new HashMap>(); @@ -379,7 +379,7 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, Set noDlsConcreteIndices = new HashSet<>(); Set noFlsConcreteIndices = new HashSet<>(); Set noMaskedFieldConcreteIndices = new HashSet<>(); - + for (SecurityRole role : roles) { for (IndexPattern ip : role.getIpatterns()) { final Set concreteIndices = ip.concreteIndexNames(user, resolver, cs); @@ -409,12 +409,12 @@ public EvaluatedDlsFlsConfig getDlsFls(User user, boolean dfmEmptyOverwritesAll, } else if (dfmEmptyOverwritesAll) { noFlsConcreteIndices.addAll(concreteIndices); } - + Set maskedFields = ip.getMaskedFields(); if (maskedFields != null && maskedFields.size() > 0) { - for (String concreteIndex : concreteIndices) { + for (String concreteIndex : concreteIndices) { if (maskedFieldsMap.containsKey(concreteIndex)) { maskedFieldsMap.get(concreteIndex).addAll(Sets.newHashSet(maskedFields)); } else { @@ -498,7 +498,7 @@ public boolean impliesTypePermGlobal(Resolved resolved, User user, String[] acti roles.stream().forEach(p -> ipatterns.addAll(p.getIpatterns())); return ConfigModelV7.impliesTypePerm(ipatterns, resolved, user, actions, resolver, cs); } - + private boolean containsDlsFlsConfig() { for (SecurityRole role : roles) { for (IndexPattern ip : role.getIpatterns()) { @@ -562,7 +562,7 @@ private Set getAllResolvedPermittedIndices(Resolved resolved, User user, for (IndexPattern p : ipatterns) { //what if we cannot resolve one (for create purposes) final boolean patternMatch = p.getPerms().matchAll(actions); - + // final Set tperms = p.getTypePerms(); // for (TypePerm tp : tperms) { // if (WildcardMatcher.matchAny(tp.typePattern, resolved.getTypes(-).toArray(new String[0]))) { @@ -810,7 +810,7 @@ public String getDlsQuery(User user) { public boolean hasDlsQuery() { return dlsQuery != null && !dlsQuery.isEmpty(); } - + public Set getFls() { return Collections.unmodifiableSet(fls); } @@ -818,7 +818,7 @@ public Set getFls() { public boolean hasFlsFields() { return fls != null && !fls.isEmpty(); } - + public Set getMaskedFields() { return Collections.unmodifiableSet(maskedFields); } @@ -826,12 +826,12 @@ public Set getMaskedFields() { public boolean hasMaskedFields() { return maskedFields != null && !maskedFields.isEmpty(); } - + public WildcardMatcher getPerms() { return WildcardMatcher.from(perms); } - + } /*public static class TypePerm { @@ -1033,7 +1033,7 @@ private static boolean impliesTypePerm(Set ipatterns, Resolved res ) ); } - + private class TenantHolder { private SetMultimap> tenantsMM = null; @@ -1055,7 +1055,7 @@ public Tuple>> call() throws Exception { final Set> tuples = new HashSet<>(); final List tenants = securityRole.getValue().getTenant_permissions(); if (tenants != null) { - + for (RoleV7.Tenant tenant : tenants) { // find Wildcarded tenant patterns @@ -1166,7 +1166,7 @@ private class RoleMappingHolder { private RoleMappingHolder(final SecurityDynamicConfiguration rolemappings, final String hostResolverMode) { this.hostResolverMode = hostResolverMode; - + if (roles != null) { users = ArrayListMultimap.create(); @@ -1267,10 +1267,10 @@ private Set map(final User user, final TransportAddress caller) { } } - - - - + + + + public Map mapTenants(User user, Set roles) { return tenantHolder.mapTenants(user, roles); diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java index 262eb37cf8..9d8c36576c 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigFactory.java @@ -117,7 +117,7 @@ public final static SecurityDynamicConfiguration addStatics(SecurityDynamicCo return original; } - + protected final Logger log = LogManager.getLogger(this.getClass()); private final ConfigurationRepository cr; private final AtomicBoolean initialized = new AtomicBoolean(); @@ -127,7 +127,7 @@ public final static SecurityDynamicConfiguration addStatics(SecurityDynamicCo private final InternalAuthenticationBackend iab = new InternalAuthenticationBackend(); SecurityDynamicConfiguration config; - + public DynamicConfigFactory(ConfigurationRepository cr, final Settings opensearchSettings, final Path configPath, Client client, ThreadPool threadPool, ClusterInfoHolder cih) { super(); @@ -144,11 +144,11 @@ public DynamicConfigFactory(ConfigurationRepository cr, final Settings opensearc } else { log.info("Static resources will not be loaded."); } - + registerDCFListener(this.iab); this.cr.subscribeOnChange(this); } - + @Override public void onChange(Map> typeToConfig) { @@ -187,7 +187,7 @@ public void onChange(Map> typeToConfig) { if(config.getImplementingClass() == ConfigV7.class) { //statics - + if(roles.containsAny(staticRoles)) { throw new StaticResourceException("Cannot override static roles"); } @@ -205,24 +205,24 @@ public void onChange(Map> typeToConfig) { if(!actionGroups.add(staticActionGroups) && !staticActionGroups.getCEntries().isEmpty()) { throw new StaticResourceException("Unable to load static action groups"); } - + log.debug("Static action groups loaded ({})", staticActionGroups.getCEntries().size()); - + if(tenants.containsAny(staticTenants)) { throw new StaticResourceException("Cannot override static tenants"); } if(!tenants.add(staticTenants) && !staticTenants.getCEntries().isEmpty()) { throw new StaticResourceException("Unable to load static tenants"); } - + log.debug("Static tenants loaded ({})", staticTenants.getCEntries().size()); log.debug("Static configuration loaded (total roles: {}/total action groups: {}/total tenants: {})", roles.getCEntries().size(), actionGroups.getCEntries().size(), tenants.getCEntries().size()); - + //rebuild v7 Models dcm = new DynamicConfigModelV7(getConfigV7(config), opensearchSettings, configPath, iab); @@ -252,26 +252,26 @@ public void onChange(Map> typeToConfig) { } initialized.set(true); - + } - + private static ConfigV6 getConfigV6(SecurityDynamicConfiguration sdc) { @SuppressWarnings("unchecked") SecurityDynamicConfiguration c = (SecurityDynamicConfiguration) sdc; return c.getCEntry("opendistro_security"); } - + private static ConfigV7 getConfigV7(SecurityDynamicConfiguration sdc) { @SuppressWarnings("unchecked") SecurityDynamicConfiguration c = (SecurityDynamicConfiguration) sdc; return c.getCEntry("config"); } - + @Override public final boolean isInitialized() { return initialized.get(); } - + public void registerDCFListener(Object listener) { eventBus.register(listener); } @@ -279,15 +279,15 @@ public void registerDCFListener(Object listener) { public void unregisterDCFListener(Object listener) { eventBus.unregister(listener); } - + private static class InternalUsersModelV7 extends InternalUsersModel { - + private final SecurityDynamicConfiguration internalUserV7SecurityDynamicConfiguration; private final SecurityDynamicConfiguration rolesV7SecurityDynamicConfiguration; private final SecurityDynamicConfiguration rolesMappingsV7SecurityDynamicConfiguration; - + public InternalUsersModelV7(SecurityDynamicConfiguration internalUserV7SecurityDynamicConfiguration, SecurityDynamicConfiguration rolesV7SecurityDynamicConfiguration, SecurityDynamicConfiguration rolesMappingsV7SecurityDynamicConfiguration) { @@ -325,7 +325,7 @@ public String getHash(String user) { InternalUserV7 tmp = internalUserV7SecurityDynamicConfiguration.getCEntry(user); return tmp==null?null:tmp.getHash(); } - + public List getSecurityRoles(String user) { InternalUserV7 tmp = internalUserV7SecurityDynamicConfiguration.getCEntry(user); @@ -341,11 +341,11 @@ private boolean isRolesMappingHidden(String rolename) { return roleMapping!=null && roleMapping.isHidden(); } } - + private static class InternalUsersModelV6 extends InternalUsersModel { - + SecurityDynamicConfiguration configuration; - + public InternalUsersModelV6(SecurityDynamicConfiguration configuration) { super(); @@ -379,7 +379,7 @@ public String getHash(String user) { InternalUserV6 tmp = configuration.getCEntry(user); return tmp==null?null:tmp.getHash(); } - + public List getSecurityRoles(String user) { return Collections.emptyList(); } diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java index f91e768283..22121bca7f 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModel.java @@ -53,7 +53,7 @@ import org.opensearch.security.http.proxy.HTTPExtendedProxyAuthenticator; public abstract class DynamicConfigModel { - + protected final Logger log = LogManager.getLogger(this.getClass()); public abstract SortedSet getRestAuthDomains(); public abstract Set getRestAuthorizers(); @@ -75,17 +75,17 @@ public abstract class DynamicConfigModel { public abstract String getFilteredAliasMode(); public abstract String getHostsResolverMode(); public abstract boolean isDnfofForEmptyResultsEnabled(); - + public abstract List getIpAuthFailureListeners(); public abstract Multimap getAuthBackendFailureListeners(); public abstract List> getIpClientBlockRegistries(); public abstract Multimap> getAuthBackendClientBlockRegistries(); - + protected final Map authImplMap = new HashMap<>(); public DynamicConfigModel() { super(); - + authImplMap.put("intern_c", InternalAuthenticationBackend.class.getName()); authImplMap.put("intern_z", NoOpAuthorizationBackend.class.getName()); @@ -97,7 +97,7 @@ public DynamicConfigModel() { authImplMap.put("ldap_c", "com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend"); authImplMap.put("ldap_z", "com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend"); - + authImplMap.put("ldap2_c", "com.amazon.dlic.auth.ldap2.LDAPAuthenticationBackend2"); authImplMap.put("ldap2_z", "com.amazon.dlic.auth.ldap2.LDAPAuthorizationBackend2"); @@ -109,11 +109,11 @@ public DynamicConfigModel() { authImplMap.put("jwt_h", "com.amazon.dlic.auth.http.jwt.HTTPJwtAuthenticator"); authImplMap.put("openid_h", "com.amazon.dlic.auth.http.jwt.keybyoidc.HTTPJwtKeyByOpenIdConnectAuthenticator"); authImplMap.put("saml_h", "com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator"); - + authImplMap.put("ip_authFailureListener", AddressBasedRateLimiter.class.getName()); authImplMap.put("username_authFailureListener", UserNameBasedRateLimiter.class.getName()); } - - - + + + } diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java index 40b3e3319a..2dce89ba7c 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV6.java @@ -62,7 +62,7 @@ import org.opensearch.security.support.ReflectionHelper; public class DynamicConfigModelV6 extends DynamicConfigModel { - + private final ConfigV6 config; private final Settings opensearchSettings; private final Path configPath; @@ -72,12 +72,12 @@ public class DynamicConfigModelV6 extends DynamicConfigModel { private Set transportAuthorizers; private List destroyableComponents; private final InternalAuthenticationBackend iab; - + private List ipAuthFailureListeners; private Multimap authBackendFailureListeners; private List> ipClientBlockRegistries; private Multimap> authBackendClientBlockRegistries; - + public DynamicConfigModelV6(ConfigV6 config, Settings opensearchSettings, Path configPath, InternalAuthenticationBackend iab) { super(); this.config = config; @@ -158,7 +158,7 @@ public boolean isMultiRolespanEnabled() { public String getFilteredAliasMode() { return config.dynamic.filtered_alias_mode; } - + @Override public boolean isDnfofForEmptyResultsEnabled() { return config.dynamic.do_not_fail_on_forbidden_empty; @@ -168,29 +168,29 @@ public boolean isDnfofForEmptyResultsEnabled() { public String getHostsResolverMode() { return config.dynamic.hosts_resolver_mode; } - + @Override public List getIpAuthFailureListeners() { return Collections.unmodifiableList(ipAuthFailureListeners); } - + @Override public Multimap getAuthBackendFailureListeners() { return Multimaps.unmodifiableMultimap(authBackendFailureListeners); } - + @Override public List> getIpClientBlockRegistries() { return Collections.unmodifiableList(ipClientBlockRegistries); } - + @Override public Multimap> getAuthBackendClientBlockRegistries() { return Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries); } - + private void buildAAA() { - + final SortedSet restAuthDomains0 = new TreeSet<>(); final Set restAuthorizers0 = new HashSet<>(); final SortedSet transportAuthDomains0 = new TreeSet<>(); @@ -214,7 +214,7 @@ private void buildAAA() { final String authzBackendClazz = ad.getValue().authorization_backend.type; final AuthorizationBackend authorizationBackend; - + if(authzBackendClazz.equals(InternalAuthenticationBackend.class.getName()) //NOSONAR || authzBackendClazz.equals("internal") || authzBackendClazz.equals("intern")) { @@ -229,7 +229,7 @@ private void buildAAA() { .put(Settings.builder().loadFromSource(ad.getValue().authorization_backend.configAsJson(), XContentType.JSON).build()).build() , configPath); } - + if (httpEnabled) { restAuthorizers0.add(authorizationBackend); } @@ -237,7 +237,7 @@ private void buildAAA() { if (transportEnabled) { transportAuthorizers0.add(authorizationBackend); } - + if (authorizationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authorizationBackend); } @@ -276,7 +276,7 @@ private void buildAAA() { String httpAuthenticatorType = ad.getValue().http_authenticator.type; //no default HTTPAuthenticator httpAuthenticator = httpAuthenticatorType==null?null: (HTTPAuthenticator) newInstance(httpAuthenticatorType,"h", Settings.builder().put(opensearchSettings) - //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), + //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), .put(Settings.builder().loadFromSource(ad.getValue().http_authenticator.configAsJson(), XContentType.JSON).build()).build() , configPath); @@ -291,15 +291,15 @@ private void buildAAA() { if (transportEnabled) { transportAuthDomains0.add(_ad); } - + if (httpAuthenticator instanceof Destroyable) { destroyableComponents0.add((Destroyable) httpAuthenticator); } - + if (authenticationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authenticationBackend); } - + } catch (final Exception e) { log.error("Unable to initialize auth domain {} due to {}", ad, e.toString(), e); } @@ -308,30 +308,30 @@ private void buildAAA() { } List originalDestroyableComponents = destroyableComponents; - + restAuthDomains = Collections.unmodifiableSortedSet(restAuthDomains0); transportAuthDomains = Collections.unmodifiableSortedSet(transportAuthDomains0); restAuthorizers = Collections.unmodifiableSet(restAuthorizers0); transportAuthorizers = Collections.unmodifiableSet(transportAuthorizers0); - + destroyableComponents = Collections.unmodifiableList(destroyableComponents0); - + if(originalDestroyableComponents != null) { destroyDestroyables(originalDestroyableComponents); } - + originalDestroyableComponents = null; - + createAuthFailureListeners(ipAuthFailureListeners0, authBackendFailureListeners0, ipClientBlockRegistries0, authBackendClientBlockRegistries0, destroyableComponents0); - + ipAuthFailureListeners = Collections.unmodifiableList(ipAuthFailureListeners0); ipClientBlockRegistries = Collections.unmodifiableList(ipClientBlockRegistries0); authBackendClientBlockRegistries = Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries0); authBackendFailureListeners = Multimaps.unmodifiableMultimap(authBackendFailureListeners0); } - + private void destroyDestroyables(List destroyableComponents) { for (Destroyable destroyable : destroyableComponents) { try { @@ -341,7 +341,7 @@ private void destroyDestroyables(List destroyableComponents) { } } } - + private T newInstance(final String clazzOrShortcut, String type, final Settings settings, final Path configPath) { String clazz = clazzOrShortcut; @@ -352,7 +352,7 @@ private T newInstance(final String clazzOrShortcut, String type, final Setti return ReflectionHelper.instantiateAAA(clazz, settings, configPath); } - + private String translateShortcutToClassName(final String clazzOrShortcut, final String type) { if (authImplMap.containsKey(clazzOrShortcut + "_" + type)) { @@ -361,17 +361,17 @@ private String translateShortcutToClassName(final String clazzOrShortcut, final return clazzOrShortcut; } } - + private void createAuthFailureListeners(List ipAuthFailureListeners, Multimap authBackendFailureListeners, List> ipClientBlockRegistries, Multimap> authBackendUserClientBlockRegistries, List destroyableComponents0) { for (Entry entry : config.dynamic.auth_failure_listeners.getListeners().entrySet()) { - + Settings entrySettings = Settings.builder() .put(opensearchSettings) .put(Settings.builder().loadFromSource(entry.getValue().asJson(), XContentType.JSON).build()).build(); - + String type = entry.getValue().type; String authenticationBackend = entry.getValue().authentication_backend; diff --git a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java index 6db5fba0a7..8e92675dcc 100644 --- a/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java +++ b/src/main/java/org/opensearch/security/securityconf/DynamicConfigModelV7.java @@ -62,7 +62,7 @@ import org.opensearch.security.support.ReflectionHelper; public class DynamicConfigModelV7 extends DynamicConfigModel { - + private final ConfigV7 config; private final Settings opensearchSettings; private final Path configPath; @@ -77,7 +77,7 @@ public class DynamicConfigModelV7 extends DynamicConfigModel { private Multimap authBackendFailureListeners; private List> ipClientBlockRegistries; private Multimap> authBackendClientBlockRegistries; - + public DynamicConfigModelV7(ConfigV7 config, Settings opensearchSettings, Path configPath, InternalAuthenticationBackend iab) { super(); this.config = config; @@ -163,35 +163,35 @@ public String getFilteredAliasMode() { public String getHostsResolverMode() { return config.dynamic.hosts_resolver_mode; } - + @Override public boolean isDnfofForEmptyResultsEnabled() { return config.dynamic.do_not_fail_on_forbidden_empty; } - + @Override public List getIpAuthFailureListeners() { return Collections.unmodifiableList(ipAuthFailureListeners); } - + @Override public Multimap getAuthBackendFailureListeners() { return Multimaps.unmodifiableMultimap(authBackendFailureListeners); } - + @Override public List> getIpClientBlockRegistries() { return Collections.unmodifiableList(ipClientBlockRegistries); } - + @Override public Multimap> getAuthBackendClientBlockRegistries() { return Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries); } - - + + private void buildAAA() { - + final SortedSet restAuthDomains0 = new TreeSet<>(); final Set restAuthorizers0 = new HashSet<>(); final SortedSet transportAuthDomains0 = new TreeSet<>(); @@ -214,7 +214,7 @@ private void buildAAA() { final String authzBackendClazz = ad.getValue().authorization_backend.type; final AuthorizationBackend authorizationBackend; - + if(authzBackendClazz.equals(InternalAuthenticationBackend.class.getName()) //NOSONAR || authzBackendClazz.equals("internal") || authzBackendClazz.equals("intern")) { @@ -229,7 +229,7 @@ private void buildAAA() { .put(Settings.builder().loadFromSource(ad.getValue().authorization_backend.configAsJson(), XContentType.JSON).build()).build() , configPath); } - + if (httpEnabled) { restAuthorizers0.add(authorizationBackend); } @@ -237,7 +237,7 @@ private void buildAAA() { if (transportEnabled) { transportAuthorizers0.add(authorizationBackend); } - + if (authorizationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authorizationBackend); } @@ -275,7 +275,7 @@ private void buildAAA() { String httpAuthenticatorType = ad.getValue().http_authenticator.type; //no default HTTPAuthenticator httpAuthenticator = httpAuthenticatorType==null?null: (HTTPAuthenticator) newInstance(httpAuthenticatorType,"h", Settings.builder().put(opensearchSettings) - //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), + //.putProperties(ads.getAsStringMap(DotPath.of("http_authenticator.config")), DynamicConfiguration.checkKeyFunction()).build(), .put(Settings.builder().loadFromSource(ad.getValue().http_authenticator.configAsJson(), XContentType.JSON).build()).build() , configPath); @@ -290,15 +290,15 @@ private void buildAAA() { if (transportEnabled) { transportAuthDomains0.add(_ad); } - + if (httpAuthenticator instanceof Destroyable) { destroyableComponents0.add((Destroyable) httpAuthenticator); } - + if (authenticationBackend instanceof Destroyable) { destroyableComponents0.add((Destroyable) authenticationBackend); } - + } catch (final Exception e) { log.error("Unable to initialize auth domain {} due to {}", ad, e.toString(), e); } @@ -307,23 +307,23 @@ private void buildAAA() { } List originalDestroyableComponents = destroyableComponents; - + restAuthDomains = Collections.unmodifiableSortedSet(restAuthDomains0); transportAuthDomains = Collections.unmodifiableSortedSet(transportAuthDomains0); restAuthorizers = Collections.unmodifiableSet(restAuthorizers0); transportAuthorizers = Collections.unmodifiableSet(transportAuthorizers0); - + destroyableComponents = Collections.unmodifiableList(destroyableComponents0); - + if(originalDestroyableComponents != null) { destroyDestroyables(originalDestroyableComponents); } - + originalDestroyableComponents = null; createAuthFailureListeners(ipAuthFailureListeners0, authBackendFailureListeners0, ipClientBlockRegistries0, authBackendClientBlockRegistries0, destroyableComponents0); - + ipAuthFailureListeners = Collections.unmodifiableList(ipAuthFailureListeners0); ipClientBlockRegistries = Collections.unmodifiableList(ipClientBlockRegistries0); authBackendClientBlockRegistries = Multimaps.unmodifiableMultimap(authBackendClientBlockRegistries0); @@ -340,7 +340,7 @@ private void destroyDestroyables(List destroyableComponents) { } } } - + private T newInstance(final String clazzOrShortcut, String type, final Settings settings, final Path configPath) { String clazz = clazzOrShortcut; @@ -351,7 +351,7 @@ private T newInstance(final String clazzOrShortcut, String type, final Setti return ReflectionHelper.instantiateAAA(clazz, settings, configPath); } - + private String translateShortcutToClassName(final String clazzOrShortcut, final String type) { if (authImplMap.containsKey(clazzOrShortcut + "_" + type)) { @@ -360,17 +360,17 @@ private String translateShortcutToClassName(final String clazzOrShortcut, final return clazzOrShortcut; } } - + private void createAuthFailureListeners(List ipAuthFailureListeners, Multimap authBackendFailureListeners, List> ipClientBlockRegistries, Multimap> authBackendUserClientBlockRegistries, List destroyableComponents0) { for (Entry entry : config.dynamic.auth_failure_listeners.getListeners().entrySet()) { - + Settings entrySettings = Settings.builder() .put(opensearchSettings) .put(Settings.builder().loadFromSource(entry.getValue().asJson(), XContentType.JSON).build()).build(); - + String type = entry.getValue().type; String authenticationBackend = entry.getValue().authentication_backend; diff --git a/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java b/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java index 9100e7dd02..8870cb3aad 100644 --- a/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java +++ b/src/main/java/org/opensearch/security/securityconf/EvaluatedDlsFlsConfig.java @@ -87,7 +87,7 @@ public EvaluatedDlsFlsConfig filter(Resolved indices) { return this; } else { Set allIndices = indices.getAllIndices(); - + return new EvaluatedDlsFlsConfig(filter(dlsQueriesByIndex, allIndices), filter(flsByIndex, allIndices), filter(fieldMaskingByIndex, allIndices)); } @@ -108,7 +108,7 @@ private Map> filter(Map> map, Set> result = new HashMap<>(map.size()); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry> entry : map.entrySet()) { if (WildcardMatcher.from(entry.getKey(), false).matchAny(allIndices)) { result.put(entry.getKey(), entry.getValue()); } diff --git a/src/main/java/org/opensearch/security/securityconf/Hideable.java b/src/main/java/org/opensearch/security/securityconf/Hideable.java index 9b1df8f157..8744575d64 100644 --- a/src/main/java/org/opensearch/security/securityconf/Hideable.java +++ b/src/main/java/org/opensearch/security/securityconf/Hideable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface Hideable { - + boolean isHidden(); boolean isReserved(); diff --git a/src/main/java/org/opensearch/security/securityconf/Initializable.java b/src/main/java/org/opensearch/security/securityconf/Initializable.java index fafc717866..ab1a1ebd4a 100644 --- a/src/main/java/org/opensearch/security/securityconf/Initializable.java +++ b/src/main/java/org/opensearch/security/securityconf/Initializable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface Initializable { - + boolean isInitialized(); } diff --git a/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java b/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java index 3ff1554a94..41c3116874 100644 --- a/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java +++ b/src/main/java/org/opensearch/security/securityconf/InternalUsersModel.java @@ -31,7 +31,7 @@ import java.util.Map; public abstract class InternalUsersModel { - + public abstract boolean exists(String user); public abstract List getBackenRoles(String user); public abstract Map getAttributes(String user); diff --git a/src/main/java/org/opensearch/security/securityconf/Migration.java b/src/main/java/org/opensearch/security/securityconf/Migration.java index 3cb111f11c..ec6a5525b9 100644 --- a/src/main/java/org/opensearch/security/securityconf/Migration.java +++ b/src/main/java/org/opensearch/security/securityconf/Migration.java @@ -55,15 +55,15 @@ public class Migration { - + public static Tuple,SecurityDynamicConfiguration> migrateRoles(SecurityDynamicConfiguration r6cs, SecurityDynamicConfiguration rms6) throws MigrationException { - + final SecurityDynamicConfiguration r7 = SecurityDynamicConfiguration.empty(); r7.setCType(r6cs.getCType()); r7.set_meta(new Meta()); r7.get_meta().setConfig_version(2); r7.get_meta().setType("roles"); - + final SecurityDynamicConfiguration t7 = SecurityDynamicConfiguration.empty(); t7.setCType(CType.TENANTS); t7.set_meta(new Meta()); @@ -71,11 +71,11 @@ public static Tuple,SecurityDynamicConfigur t7.get_meta().setType("tenants"); Set dedupTenants = new HashSet<>(); - + for(final Entry r6e: r6cs.getCEntries().entrySet()) { final String roleName = r6e.getKey(); final RoleV6 r6 = r6e.getValue(); - + if(r6 == null) { RoleV7 noPermRole = new RoleV7(); noPermRole.setDescription("Migrated from v6, was empty"); @@ -84,52 +84,52 @@ public static Tuple,SecurityDynamicConfigur } r7.putCEntry(roleName, new RoleV7(r6)); - + for(Entry tenant: r6.getTenants().entrySet()) { dedupTenants.add(tenant.getKey()); } } - + if(rms6 != null) { for(final Entry r6m: rms6.getCEntries().entrySet()) { final String roleName = r6m.getKey(); //final RoleMappingsV6 r6 = r6m.getValue(); - + if(!r7.exists(roleName)) { //rolemapping but role does not exists RoleV7 noPermRole = new RoleV7(); noPermRole.setDescription("Migrated from v6, was in rolemappings but no role existed"); r7.putCEntry(roleName, noPermRole); } - + } } - + for(String tenantName: dedupTenants) { TenantV7 entry = new TenantV7(); entry.setDescription("Migrated from v6"); t7.putCEntry(tenantName, entry); } - + return new Tuple, SecurityDynamicConfiguration>(r7, t7); - + } - + public static SecurityDynamicConfiguration migrateConfig(SecurityDynamicConfiguration r6cs) throws MigrationException { final SecurityDynamicConfiguration c7 = SecurityDynamicConfiguration.empty(); c7.setCType(r6cs.getCType()); c7.set_meta(new Meta()); c7.get_meta().setConfig_version(2); c7.get_meta().setType("config"); - + if(r6cs.getCEntries().size() != 1) { throw new MigrationException("Unable to migrate config because expected size was 1 but actual size is "+r6cs.getCEntries().size()); } - + if(r6cs.getCEntries().get("opendistro_security") == null) { throw new MigrationException("Unable to migrate config because 'opendistro_security' key not found"); } - + for(final Entry r6c: r6cs.getCEntries().entrySet()) { c7.putCEntry("config", new ConfigV7(r6c.getValue())); } @@ -181,23 +181,23 @@ public static SecurityDynamicConfiguration migrateInternalUsers i7.set_meta(new Meta()); i7.get_meta().setConfig_version(2); i7.get_meta().setType("internalusers"); - + for(final Entry r6i: r6is.getCEntries().entrySet()) { final String username = !Strings.isNullOrEmpty(r6i.getValue().getUsername())?r6i.getValue().getUsername():r6i.getKey(); i7.putCEntry(username, new InternalUserV7(r6i.getValue())); } - + return i7; } - + public static SecurityDynamicConfiguration migrateActionGroups(SecurityDynamicConfiguration r6as) throws MigrationException { - + final SecurityDynamicConfiguration a7 = SecurityDynamicConfiguration.empty(); a7.setCType(r6as.getCType()); a7.set_meta(new Meta()); a7.get_meta().setConfig_version(2); a7.get_meta().setType("actiongroups"); - + if(r6as.getImplementingClass().isAssignableFrom(List.class)) { for(final Entry r6a: r6as.getCEntries().entrySet()) { a7.putCEntry(r6a.getKey(), new ActionGroupsV7(r6a.getKey(), (List) r6a.getValue())); @@ -210,18 +210,18 @@ public static SecurityDynamicConfiguration migrateActionGroups( return a7; } - + public static SecurityDynamicConfiguration migrateRoleMappings(SecurityDynamicConfiguration r6rms) throws MigrationException { final SecurityDynamicConfiguration rms7 = SecurityDynamicConfiguration.empty(); rms7.setCType(r6rms.getCType()); rms7.set_meta(new Meta()); rms7.get_meta().setConfig_version(2); rms7.get_meta().setType("rolesmapping"); - + for(final Entry r6m: r6rms.getCEntries().entrySet()) { rms7.putCEntry(r6m.getKey(), new RoleMappingsV7(r6m.getValue())); } - + return rms7; } diff --git a/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java b/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java index d6ffb106cf..06b92100fa 100644 --- a/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java +++ b/src/main/java/org/opensearch/security/securityconf/StaticDefinable.java @@ -28,7 +28,7 @@ package org.opensearch.security.securityconf; public interface StaticDefinable { - + boolean isStatic(); } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/Meta.java b/src/main/java/org/opensearch/security/securityconf/impl/Meta.java index 42912c1dda..1e9060efa1 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/Meta.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/Meta.java @@ -30,17 +30,17 @@ import com.fasterxml.jackson.annotation.JsonIgnore; public class Meta { - - + + private String type; private int config_version; - + private CType cType; - + public String getType() { return type; } - + public void setType(String type) { this.type = type; cType = CType.fromString(type); @@ -51,7 +51,7 @@ public int getConfig_version() { public void setConfig_version(int config_version) { this.config_version = config_version; } - + @JsonIgnore public CType getCType() { return cType; @@ -61,6 +61,6 @@ public CType getCType() { public String toString() { return "Meta [type=" + type + ", config_version=" + config_version + ", cType=" + cType + "]"; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java b/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java index 09eeee41e3..c282f439e8 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/SecurityDynamicConfiguration.java @@ -52,7 +52,7 @@ import org.opensearch.security.securityconf.StaticDefinable; public class SecurityDynamicConfiguration implements ToXContent { - + private static final TypeReference> typeRefMSO = new TypeReference>() {}; @JsonIgnore @@ -61,7 +61,7 @@ public class SecurityDynamicConfiguration implements ToXContent { private long primaryTerm= -1; private CType ctype; private int version = -1; - + public static SecurityDynamicConfiguration empty() { return new SecurityDynamicConfiguration(); } @@ -83,11 +83,11 @@ public static SecurityDynamicConfiguration fromJson(String json, CType ct sdc = DefaultObjectMapper.readValue(json, DefaultObjectMapper.getTypeFactory().constructParametricType(SecurityDynamicConfiguration.class, implementationClass)); } validate(sdc, version, ctype); - + } else { sdc = new SecurityDynamicConfiguration(); } - + sdc.ctype = ctype; sdc.seqNo = seqNo; sdc.primaryTerm = primaryTerm; @@ -95,35 +95,35 @@ public static SecurityDynamicConfiguration fromJson(String json, CType ct return sdc; } - + public static void validate(SecurityDynamicConfiguration sdc, int version, CType ctype) throws IOException { if(version < 2 && sdc.get_meta() != null) { throw new IOException("A version of "+version+" can not have a _meta key for "+ctype); } - + if(version >= 2 && sdc.get_meta() == null) { throw new IOException("A version of "+version+" must have a _meta key for "+ctype); } - + if(version < 2 && ctype == CType.CONFIG && (sdc.getCEntries().size() != 1 || !sdc.getCEntries().keySet().contains("opendistro_security"))) { throw new IOException("A version of "+version+" must have a single toplevel key named 'opendistro_security' for "+ctype); } - + if(version >= 2 && ctype == CType.CONFIG && (sdc.getCEntries().size() != 1 || !sdc.getCEntries().keySet().contains("config"))) { throw new IOException("A version of "+version+" must have a single toplevel key named 'config' for "+ctype); } - + } public static SecurityDynamicConfiguration fromNode(JsonNode json, CType ctype, int version, long seqNo, long primaryTerm) throws IOException { return fromJson(DefaultObjectMapper.writeValueAsString(json, false), ctype, version, seqNo, primaryTerm); } - + //for Jackson private SecurityDynamicConfiguration() { super(); } - + private Meta _meta; public Meta get_meta() { @@ -134,17 +134,17 @@ public void set_meta(Meta _meta) { this._meta = _meta; } - + @JsonAnySetter void setCEntries(String key, T value) { putCEntry(key, value); } - + @JsonAnyGetter public Map getCEntries() { return centries; } - + @JsonIgnore public void removeHidden() { for(Entry entry: new HashMap(centries).entrySet()) { @@ -153,7 +153,7 @@ public void removeHidden() { } } } - + @JsonIgnore public void removeStatic() { for(Entry entry: new HashMap(centries).entrySet()) { @@ -162,38 +162,38 @@ public void removeStatic() { } } } - + @JsonIgnore public void clearHashes() { for(Entry entry: centries.entrySet()) { if(entry.getValue() instanceof Hashed) { - ((Hashed) entry.getValue()).clearHash(); + ((Hashed) entry.getValue()).clearHash(); } } } - + public void removeOthers(String key) { T tmp = this.centries.get(key); this.centries.clear(); this.centries.put(key, tmp); } - + @JsonIgnore public T putCEntry(String key, T value) { return centries.put(key, value); } - + @JsonIgnore public void putCObject(String key, Object value) { centries.put(key, (T) value); } - + @JsonIgnore public T getCEntry(String key) { return centries.get(key); } - + @JsonIgnore public boolean exists(String key) { return centries.containsKey(key); @@ -216,7 +216,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws final boolean omitDefaults = params != null && params.paramAsBoolean("omit_defaults", false); return builder.map(DefaultObjectMapper.readValue(DefaultObjectMapper.writeValueAsString(this, omitDefaults), typeRefMSO)); } - + @Override @JsonIgnore public boolean isFragment() { @@ -237,7 +237,7 @@ public long getPrimaryTerm() { public CType getCType() { return ctype; } - + @JsonIgnore public void setCType(CType ctype) { this.ctype = ctype; @@ -247,7 +247,7 @@ public void setCType(CType ctype) { public int getVersion() { return version; } - + @JsonIgnore public Class getImplementingClass() { return ctype==null?null:ctype.getImplementationClass().get(getVersion()); @@ -265,7 +265,7 @@ public SecurityDynamicConfiguration deepClone() { @JsonIgnore public void remove(String key) { centries.remove(key); - + } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -273,19 +273,19 @@ public boolean add(SecurityDynamicConfiguration other) { if(other.ctype == null || !other.ctype.equals(this.ctype)) { return false; } - + if(other.getImplementingClass() == null || !other.getImplementingClass().equals(this.getImplementingClass())) { return false; } - + if(other.version != this.version) { return false; } - + this.centries.putAll(other.centries); return true; } - + @JsonIgnore @SuppressWarnings({ "rawtypes" }) public boolean containsAny(SecurityDynamicConfiguration other) { diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java index b64becf0a4..99bef31505 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/ActionGroupsV6.java @@ -35,7 +35,7 @@ public class ActionGroupsV6 implements Hideable { - + private boolean readonly; private boolean hidden; private List permissions = Collections.emptyList(); @@ -43,7 +43,7 @@ public class ActionGroupsV6 implements Hideable { public ActionGroupsV6() { super(); } - + @JsonIgnore public boolean isReserved() { return readonly; @@ -70,6 +70,6 @@ public void setPermissions(List permissions) { public String toString() { return "ActionGroups [readonly=" + readonly + ", hidden=" + hidden + ", permissions=" + permissions + "]"; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java index 6599942d34..7f90e386a8 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/ConfigV6.java @@ -46,8 +46,8 @@ public class ConfigV6 { public Dynamic dynamic; - - + + @Override public String toString() { return "Config [dynamic=" + dynamic + "]"; @@ -71,7 +71,7 @@ public static class Dynamic { public String hosts_resolver_mode = "ip-only"; public String transport_userrname_attribute; public boolean do_not_fail_on_forbidden_empty; - + @Override public String toString() { return "Dynamic [filtered_alias_mode=" + filtered_alias_mode + ", kibana=" + kibana + ", http=" + http + ", authc=" + authc + ", authz=" @@ -96,9 +96,9 @@ public String toString() { return "Kibana [multitenancy_enabled=" + multitenancy_enabled + ", server_username=" + server_username + ", opendistro_role=" + opendistro_role + ", index=" + index + ", do_not_fail_on_forbidden=" + do_not_fail_on_forbidden + "]"; } - - - + + + } public static class Http { @@ -108,8 +108,8 @@ public static class Http { public String toString() { return "Http [anonymous_auth_enabled=" + anonymous_auth_enabled + ", xff=" + xff + "]"; } - - + + } public static class AuthFailureListeners { @@ -126,7 +126,7 @@ public Map getListeners() { return listeners; } - + } public static class AuthFailureListener { @@ -137,11 +137,11 @@ public static class AuthFailureListener { public int block_expiry_seconds = 60 * 10; public int max_blocked_clients = 100_000; public int max_tracked_clients = 100_000; - + public AuthFailureListener() { super(); } - + @JsonIgnore public String asJson() { try { @@ -171,12 +171,12 @@ public String toString() { return "Xff [enabled=" + enabled + ", internalProxies=" + internalProxies + ", remoteIpHeader=" + remoteIpHeader + ", proxiesHeader=" + proxiesHeader + ", trustedProxies=" + trustedProxies + "]"; } - - + + } public static class Authc { - + @JsonIgnore private final Map domains = new HashMap<>(); @@ -194,8 +194,8 @@ public Map getDomains() { public String toString() { return "Authc [domains=" + domains + "]"; } - - + + } public static class AuthcDomain { @@ -213,8 +213,8 @@ public String toString() { return "AuthcDomain [http_enabled=" + http_enabled + ", transport_enabled=" + transport_enabled + ", enabled=" + enabled + ", order=" + order + ", http_authenticator=" + http_authenticator + ", authentication_backend=" + authentication_backend + "]"; } - - + + } public static class HttpAuthenticator { @@ -222,7 +222,7 @@ public static class HttpAuthenticator { public boolean challenge = true; public String type; public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -236,14 +236,14 @@ public String configAsJson() { public String toString() { return "HttpAuthenticator [challenge=" + challenge + ", type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthzBackend { public String type = "noop"; public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -257,14 +257,14 @@ public String configAsJson() { public String toString() { return "AuthzBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthcBackend { public String type = InternalAuthenticationBackend.class.getName(); public Map config = Collections.emptyMap(); - + @JsonIgnore public String configAsJson() { try { @@ -278,8 +278,8 @@ public String configAsJson() { public String toString() { return "AuthcBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class Authz { @@ -300,8 +300,8 @@ public Map getDomains() { public String toString() { return "Authz [domains=" + domains + "]"; } - - + + } public static class AuthzDomain { @@ -316,8 +316,8 @@ public static class AuthzDomain { public String toString() { return "AuthzDomain [http_enabled=" + http_enabled + ", transport_enabled=" + transport_enabled + ", enabled=" + enabled + ", authorization_backend=" + authorization_backend + "]"; } - - + + } - + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java index 827e573a3a..f650101b64 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/InternalUserV6.java @@ -37,7 +37,7 @@ import org.opensearch.security.securityconf.Hideable; public class InternalUserV6 implements Hideable, Hashed { - + private String hash; private boolean readonly; private boolean hidden; @@ -45,7 +45,7 @@ public class InternalUserV6 implements Hideable, Hashed { private Map attributes = Collections.emptyMap(); private String username; - + public InternalUserV6(String hash, boolean readonly, boolean hidden, List roles, Map attributes, String username) { super(); @@ -69,7 +69,7 @@ public InternalUserV6() { super(); //default constructor } - + public String getHash() { return hash; } @@ -80,7 +80,7 @@ public void setHash(String hash) { public void setPassword(String password){ // no-op setter. Due to a bug in 6.x, empty "password" may be saved to the internalusers doc. Ignore it. } - + public boolean isReadonly() { return readonly; } @@ -111,7 +111,7 @@ public String toString() { return "SgInternalUser [hash=" + hash + ", readonly=" + readonly + ", hidden=" + hidden + ", roles=" + roles + ", attributes=" + attributes + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; @@ -122,7 +122,7 @@ public boolean isReserved() { public void clearHash() { hash = ""; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java index 1c28f99113..bb10fd8812 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleMappingsV6.java @@ -82,7 +82,7 @@ public String toString() { return "RoleMappings [readonly=" + readonly + ", hidden=" + hidden + ", backendroles=" + backendroles + ", hosts=" + getHosts() + ", users=" + getUsers() + ", andBackendroles=" + andBackendroles + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java index f0377f797b..e8254d4530 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v6/RoleV6.java @@ -60,13 +60,13 @@ void setTypes0(String key, List value) { public Map> getTypes() { return types; } - + private String _dls_; private List _fls_; private List _masked_fields_; - - + + public String get_dls_() { return _dls_; } @@ -84,7 +84,7 @@ public String toString() { return "Index [types=" + types + ", _dls_=" + _dls_ + ", _fls_=" + _fls_ + ", _masked_fields_=" + _masked_fields_ + "]"; } - + } @@ -132,7 +132,7 @@ public void setIndices(Map indices) { public String toString() { return "Role [readonly=" + readonly + ", hidden=" + hidden + ", cluster=" + cluster + ", tenants=" + tenants + ", indices=" + indices + "]"; } - + @JsonIgnore public boolean isReserved() { return readonly; diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java index d728dfb8cf..f38978eec2 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/ActionGroupsV7.java @@ -38,8 +38,8 @@ public class ActionGroupsV7 implements Hideable, StaticDefinable { - - + + private boolean reserved; private boolean hidden; @JsonProperty(value = "static") @@ -47,7 +47,7 @@ public class ActionGroupsV7 implements Hideable, StaticDefinable { private List allowed_actions = Collections.emptyList(); private String type; private String description; - + public ActionGroupsV7() { super(); } @@ -76,8 +76,8 @@ public String getDescription() { public void setDescription(String description) { this.description = description; } - - + + public boolean isReserved() { return reserved; } @@ -109,8 +109,8 @@ public String toString() { return "ActionGroupsV7 [reserved=" + reserved + ", hidden=" + hidden + ", _static=" + _static + ", allowed_actions=" + allowed_actions + ", type=" + type + ", description=" + description + "]"; } - - - - + + + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java index 3029b42abf..337dec8e31 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/ConfigV7.java @@ -53,7 +53,7 @@ public ConfigV7() { public ConfigV7(ConfigV6 c6) { dynamic = new Dynamic(); - + dynamic.filtered_alias_mode = c6.dynamic.filtered_alias_mode; dynamic.disable_rest_auth = c6.dynamic.disable_rest_auth; dynamic.disable_intertransport_auth = c6.dynamic.disable_intertransport_auth; @@ -64,40 +64,40 @@ public ConfigV7(ConfigV6 c6) { dynamic.multi_rolespan_enabled = c6.dynamic.multi_rolespan_enabled; dynamic.hosts_resolver_mode = c6.dynamic.hosts_resolver_mode; dynamic.transport_userrname_attribute = c6.dynamic.transport_userrname_attribute; - + dynamic.kibana = new Kibana(); - + dynamic.kibana.index = c6.dynamic.kibana.index; dynamic.kibana.multitenancy_enabled = c6.dynamic.kibana.multitenancy_enabled; dynamic.kibana.private_tenant_enabled = true; dynamic.kibana.default_tenant = ""; dynamic.kibana.server_username = c6.dynamic.kibana.server_username; - + dynamic.http = new Http(); - + dynamic.http.anonymous_auth_enabled = c6.dynamic.http.anonymous_auth_enabled; - + dynamic.http.xff = new Xff(); - + dynamic.http.xff.enabled = c6.dynamic.http.xff.enabled; dynamic.http.xff.internalProxies = c6.dynamic.http.xff.internalProxies; dynamic.http.xff.remoteIpHeader = c6.dynamic.http.xff.remoteIpHeader; - + dynamic.authc = new Authc(); - + dynamic.authc.domains.putAll(c6.dynamic.authc.getDomains().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthcDomain(entry.getValue())))); - + dynamic.authz = new Authz(); - + dynamic.authz.domains.putAll(c6.dynamic.authz.getDomains().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthzDomain(entry.getValue())))); - + dynamic.auth_failure_listeners = new AuthFailureListeners(); dynamic.auth_failure_listeners.listeners.putAll(c6.dynamic.auth_failure_listeners.getListeners().entrySet().stream().collect(Collectors.toMap( - entry -> entry.getKey(), + entry -> entry.getKey(), entry -> new AuthFailureListener(entry.getValue())))); } @@ -125,7 +125,7 @@ public static class Dynamic { public String hosts_resolver_mode = "ip-only"; public String transport_userrname_attribute; public boolean do_not_fail_on_forbidden_empty; - + @Override public String toString() { return "Dynamic [filtered_alias_mode=" + filtered_alias_mode + ", kibana=" + kibana + ", http=" + http + ", authc=" + authc + ", authz=" @@ -151,9 +151,9 @@ public String toString() { server_username + ", opendistro_role=" + opendistro_role + ", index=" + index + "]"; } - - - + + + } public static class Http { @@ -163,8 +163,8 @@ public static class Http { public String toString() { return "Http [anonymous_auth_enabled=" + anonymous_auth_enabled + ", xff=" + xff + "]"; } - - + + } public static class AuthFailureListeners { @@ -181,7 +181,7 @@ public Map getListeners() { return listeners; } - + } public static class AuthFailureListener { @@ -192,9 +192,9 @@ public static class AuthFailureListener { public int block_expiry_seconds = 60 * 10; public int max_blocked_clients = 100_000; public int max_tracked_clients = 100_000; - - - + + + public AuthFailureListener() { super(); } @@ -209,7 +209,7 @@ public AuthFailureListener(ConfigV6.AuthFailureListener v6) { this.max_blocked_clients = v6.max_blocked_clients; this.max_tracked_clients = v6.max_tracked_clients; } - + @JsonIgnore public String asJson() { try { @@ -235,12 +235,12 @@ public static class Xff { public String toString() { return "Xff [enabled=" + enabled + ", internalProxies=" + internalProxies + ", remoteIpHeader=" + remoteIpHeader+"]"; } - - + + } public static class Authc { - + @JsonIgnore private final Map domains = new HashMap<>(); @@ -258,9 +258,9 @@ public Map getDomains() { public String toString() { return "Authc [domains=" + domains + "]"; } - - - + + + } public static class AuthcDomain { @@ -274,11 +274,11 @@ public static class AuthcDomain { public HttpAuthenticator http_authenticator = new HttpAuthenticator(); public AuthcBackend authentication_backend = new AuthcBackend(); public String description; - + public AuthcDomain() { super(); } - + public AuthcDomain(ConfigV6.AuthcDomain v6) { super(); http_enabled = v6.http_enabled && v6.enabled; @@ -299,8 +299,8 @@ public String toString() { + ", http_authenticator=" + http_authenticator + ", authentication_backend=" + authentication_backend + ", description=" + description + "]"; } - - + + } public static class HttpAuthenticator { @@ -308,7 +308,7 @@ public static class HttpAuthenticator { public boolean challenge = true; public String type; public Map config = Collections.emptyMap(); - + public HttpAuthenticator() { super(); } @@ -335,16 +335,16 @@ public String configAsJson() { public String toString() { return "HttpAuthenticator [challenge=" + challenge + ", type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthzBackend { public String type = "noop"; public Map config = Collections.emptyMap(); - - - + + + public AuthzBackend() { super(); } @@ -373,16 +373,16 @@ public String configAsJson() { public String toString() { return "AuthzBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class AuthcBackend { public String type = InternalAuthenticationBackend.class.getName(); public Map config = Collections.emptyMap(); - - - + + + public AuthcBackend() { super(); } @@ -411,8 +411,8 @@ public String configAsJson() { public String toString() { return "AuthcBackend [type=" + type + ", config=" + config + "]"; } - - + + } public static class Authz { @@ -433,8 +433,8 @@ public Map getDomains() { public String toString() { return "Authz [domains=" + domains + "]"; } - - + + } public static class AuthzDomain { @@ -444,11 +444,11 @@ public static class AuthzDomain { public boolean transport_enabled = true; public AuthzBackend authorization_backend = new AuthzBackend(); public String description; - + public AuthzDomain() { super(); } - + public AuthzDomain(ConfigV6.AuthzDomain v6) { http_enabled = v6.http_enabled && v6.enabled; transport_enabled = v6.transport_enabled && v6.enabled; @@ -461,8 +461,8 @@ public String toString() { return "AuthzDomain [http_enabled=" + http_enabled + ", transport_enabled=" + transport_enabled + ", authorization_backend=" + authorization_backend + ", description=" + description + "]"; } - - + + } - + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java index b697a9485b..a7aed05cc1 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/InternalUserV7.java @@ -40,7 +40,7 @@ import org.opensearch.security.securityconf.impl.v6.InternalUserV6; public class InternalUserV7 implements Hideable, Hashed, StaticDefinable { - + private String hash; private boolean reserved; private boolean hidden; @@ -79,7 +79,7 @@ public InternalUserV7() { super(); //default constructor } - + public InternalUserV7(InternalUserV6 u6) { hash = u6.getHash(); reserved = u6.isReserved(); @@ -95,15 +95,15 @@ public String getHash() { public void setHash(String hash) { this.hash = hash; } - - + + public boolean isHidden() { return hidden; } public void setHidden(boolean hidden) { this.hidden = hidden; } - + public List getBackend_roles() { return backend_roles; @@ -171,7 +171,7 @@ public boolean isReserved() { public void setReserved(boolean reserved) { this.reserved = reserved; } - + @JsonProperty(value = "static") public boolean isStatic() { return _static; @@ -180,6 +180,6 @@ public boolean isStatic() { public void setStatic(boolean _static) { this._static = _static; } - - + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java index c97ad2f92f..364d524497 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleMappingsV7.java @@ -124,6 +124,6 @@ public String toString() { } - + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java index 262f8ed21d..dce4652d63 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/RoleV7.java @@ -51,11 +51,11 @@ public class RoleV7 implements Hideable, StaticDefinable { private List cluster_permissions = Collections.emptyList(); private List index_permissions = Collections.emptyList(); private List tenant_permissions = Collections.emptyList(); - + public RoleV7() { - + } - + public RoleV7(RoleV6 roleV6) { this.reserved = roleV6.isReserved(); this.hidden = roleV6.isHidden(); @@ -63,24 +63,24 @@ public RoleV7(RoleV6 roleV6) { this.cluster_permissions = roleV6.getCluster(); index_permissions = new ArrayList<>(); tenant_permissions = new ArrayList<>(); - + for(Entry v6i: roleV6.getIndices().entrySet()) { index_permissions.add(new Index(v6i.getKey(), v6i.getValue())); } - + //rw tenants List rwTenants = roleV6.getTenants().entrySet().stream().filter(e-> "rw".equalsIgnoreCase(e.getValue())).map(e->e.getKey()).collect(Collectors.toList()); - + if(rwTenants != null && !rwTenants.isEmpty()) { Tenant t = new Tenant(); t.setAllowed_actions(Collections.singletonList("kibana_all_write")); t.setTenant_patterns(rwTenants); tenant_permissions.add(t); } - - + + List roTenants = roleV6.getTenants().entrySet().stream().filter(e-> "ro".equalsIgnoreCase(e.getValue())).map(e->e.getKey()).collect(Collectors.toList()); - + if(roTenants != null && !roTenants.isEmpty()) { Tenant t = new Tenant(); t.setAllowed_actions(Collections.singletonList("kibana_all_read")); @@ -97,25 +97,25 @@ public static class Index { private List fls = Collections.emptyList(); private List masked_fields = Collections.emptyList(); private List allowed_actions = Collections.emptyList(); - + public Index(String pattern, RoleV6.Index v6Index) { super(); index_patterns = Collections.singletonList(pattern); dls = v6Index.get_dls_(); fls = v6Index.get_fls_(); masked_fields = v6Index.get_masked_fields_(); - Set tmpActions = new HashSet<>(); + Set tmpActions = new HashSet<>(); for(Entry> type: v6Index.getTypes().entrySet()) { tmpActions.addAll(type.getValue()); } allowed_actions = new ArrayList<>(tmpActions); } - - + + public Index() { super(); } - + public List getIndex_patterns() { return index_patterns; } @@ -152,27 +152,27 @@ public String toString() { + ", allowed_actions=" + allowed_actions + "]"; } } - - + + public static class Tenant { private List tenant_patterns = Collections.emptyList(); private List allowed_actions = Collections.emptyList(); - + /*public Index(String pattern, RoleV6.Index v6Index) { super(); index_patterns = Collections.singletonList(pattern); dls = v6Index.get_dls_(); fls = v6Index.get_fls_(); masked_fields = v6Index.get_masked_fields_(); - Set tmpActions = new HashSet<>(); + Set tmpActions = new HashSet<>(); for(Entry> type: v6Index.getTypes().entrySet()) { tmpActions.addAll(type.getValue()); } allowed_actions = new ArrayList<>(tmpActions); }*/ - - + + public Tenant() { super(); } @@ -197,10 +197,10 @@ public void setAllowed_actions(List allowed_actions) { public String toString() { return "Tenant [tenant_patterns=" + tenant_patterns + ", allowed_actions=" + allowed_actions + "]"; } - - + + } - + public boolean isHidden() { return hidden; @@ -226,7 +226,7 @@ public void setCluster_permissions(List cluster_permissions) { this.cluster_permissions = cluster_permissions; } - + public List getIndex_permissions() { return index_permissions; @@ -267,9 +267,9 @@ public String toString() { + ", cluster_permissions=" + cluster_permissions + ", index_permissions=" + index_permissions + ", tenant_permissions=" + tenant_permissions + "]"; } - - - + + + } diff --git a/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java b/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java index 210fada185..1c55d0cd95 100644 --- a/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java +++ b/src/main/java/org/opensearch/security/securityconf/impl/v7/TenantV7.java @@ -39,7 +39,7 @@ public class TenantV7 implements Hideable, StaticDefinable { @JsonProperty(value = "static") private boolean _static; private String description; - + public boolean isHidden() { return hidden; } @@ -58,8 +58,8 @@ public boolean isReserved() { public void setReserved(boolean reserved) { this.reserved = reserved; } - - + + @JsonProperty(value = "static") public boolean isStatic() { return _static; @@ -72,6 +72,6 @@ public void setStatic(boolean _static) { public String toString() { return "TenantV7 [reserved=" + reserved + ", hidden=" + hidden + ", _static=" + _static + ", description=" + description + "]"; } - - + + } diff --git a/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java b/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java index 3fbbab69d6..87713a1d3a 100644 --- a/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java +++ b/src/main/java/org/opensearch/security/ssl/ExternalSecurityKeyStore.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -45,13 +45,13 @@ public ExternalSecurityKeyStore(final Settings settings) { this.settings = Objects.requireNonNull(settings); final String externalContextId = settings .get(SSLConfigConstants.SECURITY_SSL_CLIENT_EXTERNAL_CONTEXT_ID, null); - + if(externalContextId == null || externalContextId.length() == 0) { throw new OpenSearchException("no external ssl context id was set"); } - + externalSslContext = contextMap.get(externalContextId); - + if(externalSslContext == null) { throw new OpenSearchException("no external ssl context for id "+externalContextId); } @@ -70,7 +70,7 @@ public SSLEngine createServerTransportSSLEngine() throws SSLException { @Override public SSLEngine createClientTransportSSLEngine(final String peerHost, final int peerPort) throws SSLException { if (peerHost != null) { - final SSLEngine engine = externalSslContext.createSSLEngine(peerHost, peerPort); + final SSLEngine engine = externalSslContext.createSSLEngine(peerHost, peerPort); final SSLParameters sslParams = new SSLParameters(); sslParams.setEndpointIdentificationAlgorithm("HTTPS"); engine.setSSLParameters(sslParams); @@ -135,31 +135,31 @@ public String getSubjectAlternativeNames(X509Certificate cert) { public static void registerExternalSslContext(String id, SSLContext externalSsslContext) { contextMap.put(Objects.requireNonNull(id), Objects.requireNonNull(externalSsslContext)); } - + public static boolean hasExternalSslContext(Settings settings) { - + final String externalContextId = settings .get(SSLConfigConstants.SECURITY_SSL_CLIENT_EXTERNAL_CONTEXT_ID, null); - + if(externalContextId == null || externalContextId.length() == 0) { return false; } - + return contextMap.containsKey(externalContextId); } - + public static boolean hasExternalSslContext(String id) { return contextMap.containsKey(id); } - + public static void removeExternalSslContext(String id) { contextMap.remove(id); } - + public static void removeAllExternalSslContexts() { contextMap.clear(); } - + private String[] evalSecure(String[] engineEnabled, String[] secure) { List tmp = new ArrayList<>(Arrays.asList(engineEnabled)); tmp.retainAll(Arrays.asList(secure)); diff --git a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java index 755a2b188f..ab96c7bb3e 100644 --- a/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java +++ b/src/main/java/org/opensearch/security/ssl/OpenSearchSecuritySSLPlugin.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -122,7 +122,7 @@ protected OpenSearchSecuritySSLPlugin(final Settings settings, final Path config this.sks = null; this.configPath = null; SSLConfig = new SSLConfig(false, false); - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -130,36 +130,36 @@ public Object run() { return null; } }); - - + + return; } SSLConfig = new SSLConfig(settings); this.configPath = configPath; - + if(this.configPath != null) { log.info("OpenSearch Config path is {}", this.configPath.toAbsolutePath()); } else { log.info("OpenSearch Config path is not set"); } - + final boolean allowClientInitiatedRenegotiation = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_ALLOW_CLIENT_INITIATED_RENEGOTIATION, false); final boolean rejectClientInitiatedRenegotiation = Boolean.parseBoolean(System.getProperty(SSLConfigConstants.JDK_TLS_REJECT_CLIENT_INITIATED_RENEGOTIATION)); - + if(allowClientInitiatedRenegotiation && !rejectClientInitiatedRenegotiation) { final String renegoMsg = "Client side initiated TLS renegotiation enabled. This can open a vulnerablity for DoS attacks through client side initiated TLS renegotiation."; log.warn(renegoMsg); System.out.println(renegoMsg); System.err.println(renegoMsg); - } else { + } else { if(!rejectClientInitiatedRenegotiation) { - + final SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new SpecialPermission()); } - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -198,7 +198,7 @@ public Object run() { NonValidatingObjectMapper.inject(injectableValues); client = !"node".equals(this.settings.get(OpenSearchSecuritySSLPlugin.CLIENT_TYPE)); - + httpSSLEnabled = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED, SSLConfigConstants.SECURITY_SSL_HTTP_ENABLED_DEFAULT); transportSSLEnabled = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED, @@ -211,7 +211,7 @@ public Object run() { System.out.println("SSL not activated for http and/or transport."); System.err.println("SSL not activated for http and/or transport."); } - + if(ExternalSecurityKeyStore.hasExternalSslContext(settings)) { this.sks = new ExternalSecurityKeyStore(settings); } else { @@ -223,9 +223,9 @@ public Object run() { public Map> getHttpTransports(Settings settings, ThreadPool threadPool, BigArrays bigArrays, PageCacheRecycler pageCacheRecycler, CircuitBreakerService circuitBreakerService, NamedXContentRegistry xContentRegistry, NetworkService networkService, Dispatcher dispatcher, ClusterSettings clusterSettings) { - + if (!client && httpSSLEnabled) { - + final ValidatingDispatcher validatingDispatcher = new ValidatingDispatcher(threadPool.getThreadContext(), dispatcher, settings, configPath, NOOP_SSL_EXCEPTION_HANDLER); final SecuritySSLNettyHttpServerTransport sgsnht = new SecuritySSLNettyHttpServerTransport(settings, networkService, bigArrays, threadPool, @@ -233,7 +233,7 @@ public Map> getHttpTransports(Settings set sharedGroupFactory); return Collections.singletonMap("org.opensearch.security.ssl.http.netty.SecuritySSLNettyHttpServerTransport", () -> sgsnht); - + } return Collections.emptyMap(); @@ -243,35 +243,35 @@ public Map> getHttpTransports(Settings set public List getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier nodesInCluster) { - + final List handlers = new ArrayList(1); - + if (!client) { handlers.add(new SecuritySSLInfoAction(settings, configPath, restController, sks, Objects.requireNonNull(principalExtractor))); } - + return handlers; } - - - + + + @Override public List getTransportInterceptors(NamedWriteableRegistry namedWriteableRegistry, ThreadContext threadContext) { List interceptors = new ArrayList(1); - + if(transportSSLEnabled && !client) { interceptors.add(new SecuritySSLTransportInterceptor(settings, null, null, SSLConfig, NOOP_SSL_EXCEPTION_HANDLER)); } - + return interceptors; } - - + + @Override public Map> getTransports(Settings settings, ThreadPool threadPool, PageCacheRecycler pageCacheRecycler, CircuitBreakerService circuitBreakerService, NamedWriteableRegistry namedWriteableRegistry, NetworkService networkService) { - + Map> transports = new HashMap>(); if (transportSSLEnabled) { transports.put("org.opensearch.security.ssl.http.netty.SecuritySSLNettyTransport", @@ -290,11 +290,11 @@ public Collection createComponents(Client localClient, ClusterService cl IndexNameExpressionResolver indexNameExpressionResolver, Supplier repositoriesServiceSupplier) { final List components = new ArrayList<>(1); - + if(client) { return components; } - + final String principalExtractorClass = settings.get(SSLConfigConstants.SECURITY_SSL_TRANSPORT_PRINCIPAL_EXTRACTOR_CLASS, null); if(principalExtractorClass == null) { @@ -309,9 +309,9 @@ public Collection createComponents(Client localClient, ClusterService cl throw new OpenSearchException(e); } } - + components.add(principalExtractor); - + return components; } @@ -389,24 +389,24 @@ public List> getSettings() { @Override public Settings additionalSettings() { final Settings.Builder builder = Settings.builder(); - + if(!client && httpSSLEnabled) { - + if(settings.get("http.compression") == null) { builder.put("http.compression", false); log.info("Disabled https compression by default to mitigate BREACH attacks. You can enable it by setting 'http.compression: true' in opensearch.yml"); } - + builder.put(NetworkModule.HTTP_TYPE_KEY, "org.opensearch.security.ssl.http.netty.SecuritySSLNettyHttpServerTransport"); } - + if (transportSSLEnabled) { builder.put(NetworkModule.TRANSPORT_TYPE_KEY, "org.opensearch.security.ssl.http.netty.SecuritySSLNettyTransport"); } - + return builder.build(); } - + @Override public List getSettingsFilter() { List settingsFilter = new ArrayList<>(); diff --git a/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java b/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java index a14e8e7df1..107c48f0f5 100644 --- a/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java +++ b/src/main/java/org/opensearch/security/ssl/SecurityKeyStore.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -33,7 +33,7 @@ public interface SecurityKeyStore { public String getHTTPProviderName(); public String getTransportServerProviderName(); public String getTransportClientProviderName(); - public String getSubjectAlternativeNames(X509Certificate cert); + public String getSubjectAlternativeNames(X509Certificate cert); public void initHttpSSLConfig(); public void initTransportSSLConfig(); diff --git a/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java b/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java index 531711dc54..427debfdba 100644 --- a/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java +++ b/src/main/java/org/opensearch/security/ssl/SslExceptionHandler.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -22,15 +22,15 @@ import org.opensearch.transport.TransportRequest; public interface SslExceptionHandler { - + default void logError(Throwable t, RestRequest request, int type) { //no-op } - + default void logError(Throwable t, boolean isRest) { //no-op } - + default void logError(Throwable t, final TransportRequest request, String action, Task task, int type) { //no-op } diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java b/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java index 7c53b6268a..b6012f036e 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/SecuritySSLNettyHttpServerTransport.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.http.netty; @@ -45,7 +45,7 @@ public class SecuritySSLNettyHttpServerTransport extends Netty4HttpServerTranspo private static final Logger logger = LogManager.getLogger(SecuritySSLNettyHttpServerTransport.class); private final SecurityKeyStore sks; private final SslExceptionHandler errorHandler; - + public SecuritySSLNettyHttpServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, final ThreadPool threadPool, final SecurityKeyStore sks, final NamedXContentRegistry namedXContentRegistry, final ValidatingDispatcher dispatcher, final SslExceptionHandler errorHandler, ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { @@ -94,7 +94,7 @@ protected void configurePipeline(ChannelHandlerContext ctx, String protocol) thr throw new IllegalStateException("Unknown application protocol: " + protocol); } } - + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); @@ -119,7 +119,7 @@ protected void initChannel(Channel ch) throws Exception { final SslHandler sslHandler = new SslHandler(SecuritySSLNettyHttpServerTransport.this.sks.createHTTPSSLEngine()); ch.pipeline().addFirst("ssl_http", sslHandler); } - + @Override protected void configurePipeline(Channel ch) { ch.pipeline().addLast(new Http2OrHttpHandler()); diff --git a/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java b/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java index 66976a930b..32a1f73568 100644 --- a/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java +++ b/src/main/java/org/opensearch/security/ssl/http/netty/ValidatingDispatcher.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.http.netty; @@ -47,7 +47,7 @@ public class ValidatingDispatcher implements Dispatcher { private final Settings settings; private final Path configPath; - public ValidatingDispatcher(final ThreadContext threadContext, final Dispatcher originalDispatcher, + public ValidatingDispatcher(final ThreadContext threadContext, final Dispatcher originalDispatcher, final Settings settings, final Path configPath, final SslExceptionHandler errorHandler) { super(); this.threadContext = threadContext; @@ -68,15 +68,15 @@ public void dispatchBadRequest(RestChannel channel, ThreadContext threadContext, checkRequest(channel.request(), channel); originalDispatcher.dispatchBadRequest(channel, threadContext, cause); } - + protected void checkRequest(final RestRequest request, final RestChannel channel) { - + if(SSLRequestHelper.containsBadHeader(threadContext, "_opendistro_security_ssl_")) { final OpenSearchException exception = ExceptionUtils.createBadHeaderException(); errorHandler.logError(exception, request, 1); throw exception; } - + try { if(SSLRequestHelper.getSSLInfo(settings, configPath, request, null) == null) { logger.error("Not an SSL request"); diff --git a/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java b/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java index f5050d3242..5b1fae01e5 100644 --- a/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java +++ b/src/main/java/org/opensearch/security/ssl/rest/SecuritySSLInfoAction.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.rest; @@ -68,11 +68,11 @@ public SecuritySSLInfoAction(final Settings settings, final Path configPath, fin public List routes() { return routes; } - + @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { return new RestChannelConsumer() { - + final Boolean showDn = request.paramAsBoolean("show_dn", Boolean.FALSE); @Override @@ -81,7 +81,7 @@ public void accept(RestChannel channel) throws Exception { BytesRestResponse response = null; try { - + SSLInfo sslInfo = SSLRequestHelper.getSSLInfo(settings, configPath, request, principalExtractor); X509Certificate[] certs = sslInfo == null?null:sslInfo.getX509Certs(); X509Certificate[] localCerts = sslInfo == null?null:sslInfo.getLocalCertificates(); @@ -123,7 +123,7 @@ public void accept(RestChannel channel) throws Exception { builder.close(); } } - + channel.sendResponse(response); } }; diff --git a/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java b/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java index d717df2da6..001059eefa 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/DefaultPrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.transport; @@ -38,7 +38,7 @@ public class DefaultPrincipalExtractor implements PrincipalExtractor { protected final Logger log = LogManager.getLogger(this.getClass()); - + @Override @SuppressWarnings("removal") public String extractPrincipal(final X509Certificate x509Certificate, final Type type) { @@ -54,7 +54,7 @@ public String extractPrincipal(final X509Certificate x509Certificate, final Type String dnString = AccessController.doPrivileged(new PrivilegedAction() { @Override - public String run() { + public String run() { final X500Principal principal = x509Certificate.getSubjectX500Principal(); return principal.toString(); } @@ -69,12 +69,12 @@ public String run() { } catch (InvalidNameException e) { log.error("Unable to parse: {}",dnString, e); } - - + + if(log.isTraceEnabled()) { log.trace("principal: {}", dnString); } - + return dnString; } diff --git a/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java b/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java index 06213af642..cccca06e0c 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/PrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.transport; @@ -20,7 +20,7 @@ import java.security.cert.X509Certificate; public interface PrincipalExtractor { - + public enum Type { HTTP, TRANSPORT @@ -28,13 +28,13 @@ public enum Type { /** * Extract the principal name - * + * * Please note that this method gets called for principal extraction of other nodes * as well as transport clients. It's up to the implementer to distinguish between them * and handle them appropriately. - * + * * Implementations must be public classes with a default public default constructor. - * + * * @param x509Certificate The first X509 certificate in the peer certificate chain * This can be null, in this case the method must also return null. * @return The principal as string. This may be null in case where x509Certificate is null diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java index 58da4cb55e..5a38909f81 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLNettyTransport.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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. - * + * */ /* @@ -101,7 +101,7 @@ public void onException(TcpChannel channel, Exception e) { protected ChannelHandler getServerChannelInitializer(String name) { return new SSLServerChannelInitializer(name); } - + @Override protected ChannelHandler getClientChannelInitializer(DiscoveryNode node) { return new SSLClientChannelInitializer(node); @@ -127,7 +127,7 @@ protected void initChannel(Channel ch) throws Exception { ch.pipeline().addFirst("ssl_server", sslHandler); } } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { @@ -147,7 +147,7 @@ protected static class ClientSSLHandler extends ChannelOutboundHandlerAdapter { private final boolean hostnameVerificationEnabled; private final boolean hostnameVerificationResovleHostName; private final SslExceptionHandler errorHandler; - + private ClientSSLHandler(final SecurityKeyStore sks, final boolean hostnameVerificationEnabled, final boolean hostnameVerificationResovleHostName, final SslExceptionHandler errorHandler) { @@ -156,14 +156,14 @@ private ClientSSLHandler(final SecurityKeyStore sks, final boolean hostnameVerif this.hostnameVerificationResovleHostName = hostnameVerificationResovleHostName; this.errorHandler = errorHandler; } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { cause = cause.getCause(); } - + errorHandler.logError(cause, false); logger.error("Exception during establishing a SSL connection: " + cause, cause); @@ -186,7 +186,7 @@ public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, Sock if(log.isDebugEnabled()) { log.debug("Hostname of peer is {} ({}/{}) with hostnameVerificationResovleHostName: {}", hostname, inetSocketAddress.getHostName(), inetSocketAddress.getHostString(), hostnameVerificationResovleHostName); } - + engine = sks.createClientTransportSSLEngine(hostname, inetSocketAddress.getPort()); } else { engine = sks.createClientTransportSSLEngine(null, -1); @@ -239,7 +239,7 @@ protected void initChannel(Channel ch) throws Exception { logger.debug("Connection to {} needs to be non ssl", node.getHostName()); } } - + @Override public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof DecoderException && cause != null) { @@ -249,7 +249,7 @@ public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) th errorHandler.logError(cause, false); logger.error("Exception during establishing a SSL connection: " + cause, cause); - + super.exceptionCaught(ctx, cause); } } diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java index 925f5cf0e9..53877df0f0 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLRequestHandler.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.transport; @@ -47,7 +47,7 @@ public class SecuritySSLRequestHandler implements TransportRequestHandler { - + private final String action; private final TransportRequestHandler actualHandler; private final ThreadPool threadPool; @@ -68,7 +68,7 @@ public SecuritySSLRequestHandler(String action, TransportRequestHandler actua this.SSLConfig = SSLConfig; this.errorHandler = errorHandler; } - + protected ThreadContext getThreadContext() { if(threadPool == null) { return null; @@ -80,7 +80,7 @@ protected ThreadContext getThreadContext() { @Override public final void messageReceived(T request, TransportChannel channel, Task task) throws Exception { ThreadContext threadContext = getThreadContext() ; - + if(SSLRequestHelper.containsBadHeader(threadContext, "_opendistro_security_ssl_")) { final Exception exception = ExceptionUtils.createBadHeaderException(); channel.sendResponse(exception); @@ -91,12 +91,12 @@ public final void messageReceived(T request, TransportChannel channel, Task task if (!channelType.equals("direct") && !channelType.equals("transport")) { channel = getInnerChannel(channel); } - + if (!"transport".equals(channel.getChannelType())) { //netty4 messageReceivedDecorate(request, actualHandler, channel, task); return; } - + try { Netty4TcpChannel nettyChannel = null; @@ -111,7 +111,7 @@ public final void messageReceived(T request, TransportChannel channel, Task task } else { throw new Exception("Invalid channel of type "+channel.getClass()+ " ("+channel.getChannelType()+")"); } - + final SslHandler sslhandler = (SslHandler) nettyChannel.getNettyChannel().pipeline().get("ssl_server"); if (sslhandler == null) { @@ -131,11 +131,11 @@ public final void messageReceived(T request, TransportChannel channel, Task task final Certificate[] peerCerts = sslhandler.engine().getSession().getPeerCertificates(); final Certificate[] localCerts = sslhandler.engine().getSession().getLocalCertificates(); - - if (peerCerts != null - && peerCerts.length > 0 - && peerCerts[0] instanceof X509Certificate - && localCerts != null && localCerts.length > 0 + + if (peerCerts != null + && peerCerts.length > 0 + && peerCerts[0] instanceof X509Certificate + && localCerts != null && localCerts.length > 0 && localCerts[0] instanceof X509Certificate) { final X509Certificate[] x509PeerCerts = Arrays.copyOf(peerCerts, peerCerts.length, X509Certificate[].class); final X509Certificate[] x509LocalCerts = Arrays.copyOf(localCerts, localCerts.length, X509Certificate[].class); @@ -168,7 +168,7 @@ public final void messageReceived(T request, TransportChannel channel, Task task errorHandler.logError(e, request, action, task, 0); throw e; } - + } protected TransportChannel getInnerChannel(TransportChannel transportChannel) throws Exception { @@ -182,12 +182,12 @@ protected TransportChannel getInnerChannel(TransportChannel transportChannel) th throw new RuntimeException("Unknown channel type " + transportChannel.getChannelType() + " does not implement getInnerChannel method."); } } - + protected void addAdditionalContextValues(final String action, final TransportRequest request, final X509Certificate[] localCerts, final X509Certificate[] peerCerts, final String principal) throws Exception { // no-op } - + protected void messageReceivedDecorate(final T request, final TransportRequestHandler actualHandler, final TransportChannel transportChannel, Task task) throws Exception { actualHandler.messageReceived(request, transportChannel, task); } diff --git a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java index 165662d429..aa83265125 100644 --- a/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java +++ b/src/main/java/org/opensearch/security/ssl/transport/SecuritySSLTransportInterceptor.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.transport; @@ -28,7 +28,7 @@ import org.opensearch.transport.TransportRequestHandler; public final class SecuritySSLTransportInterceptor implements TransportInterceptor { - + protected final Logger log = LogManager.getLogger(this.getClass()); protected final ThreadPool threadPool; protected final PrincipalExtractor principalExtractor; @@ -49,6 +49,6 @@ public TransportRequestHandler interceptHandler( TransportRequestHandler actualHandler) { return new SecuritySSLRequestHandler(action, actualHandler, threadPool, principalExtractor, SSLConfig, errorHandler); } - - + + } diff --git a/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java b/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java index 0a12ffc2b5..b0a975b618 100644 --- a/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java +++ b/src/main/java/org/opensearch/security/ssl/util/CertificateValidator.java @@ -59,14 +59,14 @@ * Allows specifying Certificate Revocation List (CRL), as well as enabling * CRL Distribution Points Protocol (CRLDP) certificate extension support, * and also enabling On-Line Certificate Status Protocol (OCSP) support. - * + * * IMPORTANT: at least one of the above mechanisms *MUST* be configured and * operational, otherwise certificate validation *WILL FAIL* unconditionally. */ // CS-ENFORCE-SINGLE public class CertificateValidator { - + boolean isPreferCrl() { return preferCrl; } @@ -95,16 +95,16 @@ void setCheckOnlyEndEntities(boolean checkOnlyEndEntities) { private boolean _enableOCSP = false; /** Location of OCSP Responder */ private String _ocspResponderURL; - + private boolean preferCrl = false; private boolean checkOnlyEndEntities = true; private Date date = null; //current date - + /** - * creates an instance of the certificate validator + * creates an instance of the certificate validator * - * @param trustStore the truststore to use - * @param crls the Certificate Revocation List to use + * @param trustStore the truststore to use + * @param crls the Certificate Revocation List to use */ public CertificateValidator(KeyStore trustStore, Collection crls) { @@ -112,18 +112,18 @@ public CertificateValidator(KeyStore trustStore, Collection crls) { throw new InvalidParameterException("TrustStore must be specified for CertificateValidator."); } - + _trustStore = trustStore; _crls = crls; } - + public CertificateValidator(X509Certificate[] trustedCert, Collection crls) { if (trustedCert == null || trustedCert.length == 0) { throw new InvalidParameterException("trustedCert must be specified for CertificateValidator."); } - + _trustedCert = trustedCert; _crls = crls; } @@ -137,7 +137,7 @@ public void validate(Certificate[] certChain) throws CertificateException { if (item == null) continue; - + if (!(item instanceof X509Certificate)) { throw new IllegalStateException("Invalid certificate type in chain"); @@ -149,34 +149,34 @@ public void validate(Certificate[] certChain) throws CertificateException if (certList.isEmpty()) { throw new IllegalStateException("Invalid certificate chain"); - + } - + X509CertSelector certSelect = new X509CertSelector(); certSelect.setCertificate(certList.get(0)); - + CertPathBuilder certPathBuilder = CertPathBuilder.getInstance("PKIX"); PKIXRevocationChecker revocationChecker = (PKIXRevocationChecker) certPathBuilder.getRevocationChecker(); Set opts = new HashSet<>(); - + if(preferCrl) { opts.add(PKIXRevocationChecker.Option.PREFER_CRLS); } - + //opts.add(PKIXRevocationChecker.Option.SOFT_FAIL); - + //opts.add(PKIXRevocationChecker.Option.NO_FALLBACK); - + if(checkOnlyEndEntities) { opts.add(PKIXRevocationChecker.Option.ONLY_END_ENTITY); } - + revocationChecker.setOptions(opts); // Configure certification path builder parameters PKIXBuilderParameters pbParams = null; - + if(_trustStore != null) { pbParams = new PKIXBuilderParameters(_trustStore, certSelect); } else { @@ -189,25 +189,25 @@ public void validate(Certificate[] certChain) throws CertificateException pbParams = new PKIXBuilderParameters(trustAnchors, certSelect); } - + pbParams.addCertPathChecker(revocationChecker); - + pbParams.setDate(date); - + pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList))); - + // Set maximum certification path length pbParams.setMaxPathLength(_maxCertPathLength); - + // Enable revocation checking pbParams.setRevocationEnabled(true); - + // Set static Certificate Revocation List if (_crls != null && !_crls.isEmpty()) { pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls))); } - + // Enable On-Line Certificate Status Protocol (OCSP) support if (_enableOCSP) { @@ -218,10 +218,10 @@ public void validate(Certificate[] certChain) throws CertificateException { System.setProperty("com.sun.security.enableCRLDP","true"); } - + // Build certification path - CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); - + CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); + // Validate certification path CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams); } @@ -255,9 +255,9 @@ public void setMaxCertPathLength(int maxCertPathLength) { _maxCertPathLength = maxCertPathLength; } - + /* ------------------------------------------------------------ */ - /** + /** * @return true if CRL Distribution Points support is enabled */ public boolean isEnableCRLDP() @@ -275,7 +275,7 @@ public void setEnableCRLDP(boolean enableCRLDP) } /* ------------------------------------------------------------ */ - /** + /** * @return true if On-Line Certificate Status Protocol support is enabled */ public boolean isEnableOCSP() @@ -293,7 +293,7 @@ public void setEnableOCSP(boolean enableOCSP) } /* ------------------------------------------------------------ */ - /** + /** * @return Location of the OCSP Responder */ public String getOcspResponderURL() diff --git a/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java b/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java index f06c4d9808..e2af22844f 100644 --- a/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java +++ b/src/main/java/org/opensearch/security/ssl/util/ExceptionUtils.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.util; @@ -20,30 +20,30 @@ import org.opensearch.OpenSearchException; public class ExceptionUtils { - + public static Throwable getRootCause(final Throwable e) { - + if(e == null) { return null; } - + final Throwable cause = e.getCause(); if(cause == null) { return e; } return getRootCause(cause); } - + public static Throwable findMsg(final Throwable e, String msg) { - + if(e == null) { return null; } - + if(e.getMessage() != null && e.getMessage().contains(msg)) { return e; } - + final Throwable cause = e.getCause(); if(cause == null) { return null; diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java b/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java index ff36cc40a8..42b44a3817 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLCertificateHelper.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.util; @@ -40,20 +40,20 @@ public class SSLCertificateHelper { private static final Logger log = LogManager.getLogger(SSLCertificateHelper.class); private static boolean stripRootFromChain = true; //TODO check - + public static X509Certificate[] exportRootCertificates(final KeyStore ks, final String alias) throws KeyStoreException { logKeyStore(ks); - + final List trustedCerts = new ArrayList(); - + if (Strings.isNullOrEmpty(alias)) { - + if(log.isDebugEnabled()) { log.debug("No alias given, will trust all of the certificates in the store"); } - + final List aliases = toList(ks.aliases()); - + for (final String _alias : aliases) { if (ks.isCertificateEntry(_alias)) { @@ -79,12 +79,12 @@ public static X509Certificate[] exportRootCertificates(final KeyStore ks, final } return trustedCerts.toArray(new X509Certificate[0]); - } - + } + public static X509Certificate[] exportServerCertChain(final KeyStore ks, String alias) throws KeyStoreException { logKeyStore(ks); final List aliases = toList(ks.aliases()); - + if (Strings.isNullOrEmpty(alias)) { if(aliases.isEmpty()) { log.error("Keystore does not contain any aliases"); @@ -92,7 +92,7 @@ public static X509Certificate[] exportServerCertChain(final KeyStore ks, String alias = aliases.get(0); log.info("No alias given, use the first one: {}", alias); } - } + } final Certificate[] certs = ks.getCertificateChain(alias); if (certs != null && certs.length > 0) { @@ -103,7 +103,7 @@ public static X509Certificate[] exportServerCertChain(final KeyStore ks, String if (lastCertificate.getBasicConstraints() > -1 && lastCertificate.getSubjectX500Principal().equals(lastCertificate.getIssuerX500Principal())) { log.warn("Certificate chain for alias {} contains a root certificate", alias); - + if(stripRootFromChain ) { x509Certs = Arrays.copyOf(certs, certs.length-1, X509Certificate[].class); } @@ -143,7 +143,7 @@ public static PrivateKey exportDecryptedKey(final KeyStore ks, final String alia return null; } - + private static void logKeyStore(final KeyStore ks) { try { final List aliases = toList(ks.aliases()); @@ -175,14 +175,14 @@ private static void logKeyStore(final KeyStore ks) { log.error("Error logging keystore due to "+e, e); } } - + private static List toList(final Enumeration enumeration) { final List aliases = new ArrayList<>(); while (enumeration.hasMoreElements()) { aliases.add(enumeration.nextElement()); } - + return Collections.unmodifiableList(aliases); } } diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java b/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java index 65eaec238a..63b2ae5502 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLConfigConstants.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.util; @@ -88,15 +88,15 @@ public final class SSLConfigConstants { public static final String SECURITY_SSL_ALLOW_CLIENT_INITIATED_RENEGOTIATION = "plugins.security.ssl.allow_client_initiated_renegotiation"; public static final String DEFAULT_STORE_PASSWORD = "changeit"; //#16 - + public static final String JDK_TLS_REJECT_CLIENT_INITIATED_RENEGOTIATION = "jdk.tls.rejectClientInitiatedRenegotiation"; - + private static final String[] _SECURE_SSL_PROTOCOLS = {"TLSv1.3", "TLSv1.2", "TLSv1.1"}; - + public static final String[] getSecureSSLProtocols(Settings settings, boolean http) { List configuredProtocols = null; - + if(settings != null) { if(http) { configuredProtocols = settings.getAsList(SECURITY_SSL_HTTP_ENABLED_PROTOCOLS, Collections.emptyList()); @@ -104,26 +104,26 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht configuredProtocols = settings.getAsList(SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, Collections.emptyList()); } } - + if(configuredProtocols != null && configuredProtocols.size() > 0) { return configuredProtocols.toArray(new String[0]); } - + return _SECURE_SSL_PROTOCOLS.clone(); } - + // @formatter:off - private static final String[] _SECURE_SSL_CIPHERS = + private static final String[] _SECURE_SSL_CIPHERS = { //TLS__WITH_ - + //Example (including unsafe ones) //Protocol: TLS, SSL //Key Exchange RSA, Diffie-Hellman, ECDH, SRP, PSK //Authentication RSA, DSA, ECDSA //Bulk Ciphers RC4, 3DES, AES //Message Authentication HMAC-SHA256, HMAC-SHA1, HMAC-MD5 - + //thats what chrome 48 supports (https://cc.dcsec.uni-hannover.de/) //(c0,2b)ECDHE-ECDSA-AES128-GCM-SHA256128 BitKey exchange: ECDH, encryption: AES, MAC: SHA256. @@ -141,7 +141,7 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht //(00,35)RSA-AES256-SHA256 BitKey exchange: RSA, encryption: AES, MAC: SHA1. //(00,2f)RSA-AES128-SHA128 BitKey exchange: RSA, encryption: AES, MAC: SHA1. //(00,0a)RSA-3DES-EDE-SHA168 BitKey exchange: RSA, encryption: 3DES, MAC: SHA1. - + //thats what firefox 42 supports (https://cc.dcsec.uni-hannover.de/) //(c0,2b) ECDHE-ECDSA-AES128-GCM-SHA256 //(c0,2f) ECDHE-RSA-AES128-GCM-SHA256 @@ -176,18 +176,18 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", - + //TLS 1.3 "TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256", //Open SSL >= 1.1.1 and Java >= 12 - + //TLS 1.2 CHACHA20 POLY1305 supported by Java >= 12 and //OpenSSL >= 1.1.0 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", - + //IBM "SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", @@ -211,14 +211,14 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht "SSL_DHE_RSA_WITH_AES_256_CBC_SHA256", "SSL_DHE_DSS_WITH_AES_256_CBC_SHA", "SSL_DHE_RSA_WITH_AES_256_CBC_SHA" - + //some others //"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", //"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", - //"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", - //"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", + //"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + //"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", //"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", - //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + //"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", //"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", //"TLS_DHE_RSA_WITH_AES_128_CBC_SHA", //"TLS_RSA_WITH_AES_128_CBC_SHA256", @@ -227,11 +227,11 @@ public static final String[] getSecureSSLProtocols(Settings settings, boolean ht //"TLS_RSA_WITH_AES_256_CBC_SHA", }; // @formatter:on - + public static final List getSecureSSLCiphers(Settings settings, boolean http) { - + List configuredCiphers = null; - + if(settings != null) { if(http) { configuredCiphers = settings.getAsList(SECURITY_SSL_HTTP_ENABLED_CIPHERS, Collections.emptyList()); @@ -239,14 +239,14 @@ public static final List getSecureSSLCiphers(Settings settings, boolean configuredCiphers = settings.getAsList(SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, Collections.emptyList()); } } - + if(configuredCiphers != null && configuredCiphers.size() > 0) { return configuredCiphers; } return Collections.unmodifiableList(Arrays.asList(_SECURE_SSL_CIPHERS)); } - + private SSLConfigConstants() { } diff --git a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java index 87452f8a9c..42aad19a09 100644 --- a/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java +++ b/src/main/java/org/opensearch/security/ssl/util/SSLRequestHelper.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.util; @@ -55,7 +55,7 @@ public class SSLRequestHelper { private static final Logger log = LogManager.getLogger(SSLRequestHelper.class); - + public static class SSLInfo { private final X509Certificate[] x509Certs; private final X509Certificate[] localCertificates; @@ -79,7 +79,7 @@ public SSLInfo(final X509Certificate[] x509Certs, final String principal, final public X509Certificate[] getX509Certs() { return x509Certs == null ? null : x509Certs.clone(); } - + public X509Certificate[] getLocalCertificates() { return localCertificates == null ? null : localCertificates.clone(); } @@ -106,7 +106,7 @@ public String toString() { @SuppressWarnings("removal") public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, final RestRequest request, PrincipalExtractor principalExtractor) throws SSLPeerUnverifiedException { - + if(request == null || request.getHttpChannel() == null || !(request.getHttpChannel() instanceof Netty4HttpChannel)) { return null; } @@ -138,7 +138,7 @@ public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, if (certs != null && certs.length > 0 && certs[0] instanceof X509Certificate) { x509Certs = Arrays.copyOf(certs, certs.length, X509Certificate[].class); final X509Certificate[] x509CertsF = x509Certs; - + final SecurityManager sm = System.getSecurityManager(); if (sm != null) { @@ -147,7 +147,7 @@ public static SSLInfo getSSLInfo(final Settings settings, final Path configPath, validationFailure = AccessController.doPrivileged(new PrivilegedAction() { @Override - public Boolean run() { + public Boolean run() { return !validate(x509CertsF, settings, configPath); } }); @@ -171,7 +171,7 @@ public Boolean run() { Certificate[] localCerts = session.getLocalCertificates(); return new SSLInfo(x509Certs, principal, protocol, cipher, localCerts==null?null:Arrays.copyOf(localCerts, localCerts.length, X509Certificate[].class)); } - + public static boolean containsBadHeader(final ThreadContext context, String prefix) { if (context != null) { for (final Entry header : context.getHeaders().entrySet()) { @@ -180,27 +180,27 @@ public static boolean containsBadHeader(final ThreadContext context, String pref } } } - + return false; } - + private static boolean validate(X509Certificate[] x509Certs, final Settings settings, final Path configPath) { - + final boolean validateCrl = settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_VALIDATE, false); final boolean isTraceEnabled = log.isTraceEnabled(); if (isTraceEnabled) { log.trace("validateCrl: {}", validateCrl); } - + if(!validateCrl) { return true; } - + final Environment env = new Environment(settings, configPath); - + try { - + Collection crls = null; final String crlFile = settings.get(SSLConfigConstants.SSECURITY_SSL_HTTP_CRL_FILE); @@ -209,7 +209,7 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett try(FileInputStream crlin = new FileInputStream(crl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + if (isTraceEnabled) { log.trace("crls from file: {}", crls.size()); } @@ -218,15 +218,15 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett log.trace("no crl file configured"); } } - + final String truststore = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_FILEPATH); CertificateValidator validator = null; - + if(truststore != null) { final String truststoreType = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_TYPE, "JKS"); final String truststorePassword = SECURITY_SSL_HTTP_TRUSTSTORE_PASSWORD.getSetting(settings); //final String truststoreAlias = settings.get(SSLConfigConstants.SECURITY_SSL_HTTP_TRUSTSTORE_ALIAS, null); - + final KeyStore ts = KeyStore.getInstance(truststoreType); try(FileInputStream fin = new FileInputStream(new File(env.configDir().resolve(truststore).toAbsolutePath().toString()))) { ts.load(fin, (truststorePassword == null || truststorePassword.length() == 0) ?null:truststorePassword.toCharArray()); @@ -237,9 +237,9 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett try(FileInputStream trin = new FileInputStream(trustedCas)) { Collection cert = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); validator = new CertificateValidator(cert.toArray(new X509Certificate[0]), crls); - } + } } - + validator.setEnableCRLDP(!settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_DISABLE_CRLDP, false)); validator.setEnableOCSP(!settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_DISABLE_OCSP, false)); validator.setCheckOnlyEndEntities(settings.getAsBoolean(SSLConfigConstants.SECURITY_SSL_HTTP_CRL_CHECK_ONLY_END_ENTITIES, true)); @@ -250,13 +250,13 @@ private static boolean validate(X509Certificate[] x509Certs, final Settings sett } validator.setDate(dateTimestamp==null?null:new Date(dateTimestamp.longValue())); validator.validate(x509Certs); - + return true; - + } catch (Exception e) { log.warn("Unable to validate CRL: ", ExceptionUtils.getRootCause(e)); } - + return false; } } diff --git a/src/main/java/org/opensearch/security/ssl/util/Utils.java b/src/main/java/org/opensearch/security/ssl/util/Utils.java index 2035c4fb1e..2a6fcd2550 100644 --- a/src/main/java/org/opensearch/security/ssl/util/Utils.java +++ b/src/main/java/org/opensearch/security/ssl/util/Utils.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl.util; @@ -23,18 +23,18 @@ public static T coalesce(T first, T... more) { if (first != null) { return first; } - + if(more == null || more.length == 0) { return null; } - + for (int i = 0; i < more.length; i++) { T t = more[i]; if(t != null) { return t; } } - + return null; } diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index 83281c9d0b..f5c64bccd3 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -49,7 +49,7 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_ORIGIN_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"origin_header"; public static final String OPENDISTRO_SECURITY_DLS_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"dls_query"; - + public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"dls_filter_level_query"; public static final String OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX+"dls_filter_level_query_t"; @@ -57,7 +57,7 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_DLS_MODE_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX+"dls_mode_t"; public static final String OPENDISTRO_SECURITY_FLS_FIELDS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"fls_fields"; - + public static final String OPENDISTRO_SECURITY_MASKED_FIELD_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"masked_fields"; @@ -65,7 +65,7 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_DOC_ALLOWLIST_TRANSIENT = OPENDISTRO_SECURITY_CONFIG_PREFIX+"doc_allowlist_t"; public static final String OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE = OPENDISTRO_SECURITY_CONFIG_PREFIX+"filter_level_dls_done"; - + public static final String OPENDISTRO_SECURITY_DLS_QUERY_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX+"dls_query_ccs"; public static final String OPENDISTRO_SECURITY_FLS_FIELDS_CCS = OPENDISTRO_SECURITY_CONFIG_PREFIX+"fls_fields_ccs"; @@ -76,7 +76,7 @@ public class ConfigConstants { public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS = OPENDISTRO_SECURITY_CONFIG_PREFIX+"remote_address"; public static final String OPENDISTRO_SECURITY_REMOTE_ADDRESS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"remote_address_header"; - + public static final String OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER = OPENDISTRO_SECURITY_CONFIG_PREFIX+"initial_action_class_header"; /** @@ -118,7 +118,7 @@ public class ConfigConstants { public static final String SSO_LOGOUT_URL = OPENDISTRO_SECURITY_CONFIG_PREFIX+"sso_logout_url"; - + public static final String OPENDISTRO_SECURITY_DEFAULT_CONFIG_INDEX = ".opendistro_security"; public static final String SECURITY_ENABLE_SNAPSHOT_RESTORE_PRIVILEGE = "plugins.security.enable_snapshot_restore_privilege"; @@ -141,7 +141,7 @@ public class ConfigConstants { public static final String SECURITY_CONFIG_INDEX_NAME = "plugins.security.config_index_name"; public static final String SECURITY_AUTHCZ_IMPERSONATION_DN = "plugins.security.authcz.impersonation_dn"; public static final String SECURITY_AUTHCZ_REST_IMPERSONATION_USERS="plugins.security.authcz.rest_impersonation_user"; - + public static final String SECURITY_AUDIT_TYPE_DEFAULT = "plugins.security.audit.type"; public static final String SECURITY_AUDIT_CONFIG_DEFAULT = "plugins.security.audit.config"; public static final String SECURITY_AUDIT_CONFIG_ROUTES = "plugins.security.audit.routes"; @@ -162,14 +162,14 @@ public class ConfigConstants { public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_VERIFY_HOSTNAMES_DEFAULT = true; public static final boolean OPENDISTRO_SECURITY_AUDIT_SSL_ENABLE_SSL_CLIENT_AUTH_DEFAULT = false; public static final String OPENDISTRO_SECURITY_AUDIT_EXCLUDE_SENSITIVE_HEADERS = "opendistro_security.audit.exclude_sensitive_headers"; - + public static final String SECURITY_AUDIT_CONFIG_DEFAULT_PREFIX = "plugins.security.audit.config."; // Internal / External OpenSearch public static final String SECURITY_AUDIT_OPENSEARCH_INDEX = "index"; public static final String SECURITY_AUDIT_OPENSEARCH_TYPE = "type"; - + // External OpenSearch public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_HTTP_ENDPOINTS = "http_endpoints"; public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_USERNAME = "username"; @@ -188,22 +188,22 @@ public class ConfigConstants { public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_CIPHERS = "enabled_ssl_ciphers"; public static final String SECURITY_AUDIT_EXTERNAL_OPENSEARCH_ENABLED_SSL_PROTOCOLS = "enabled_ssl_protocols"; - // Webhooks + // Webhooks public static final String SECURITY_AUDIT_WEBHOOK_URL = "webhook.url"; public static final String SECURITY_AUDIT_WEBHOOK_FORMAT = "webhook.format"; public static final String SECURITY_AUDIT_WEBHOOK_SSL_VERIFY = "webhook.ssl.verify"; public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_FILEPATH = "webhook.ssl.pemtrustedcas_filepath"; public static final String SECURITY_AUDIT_WEBHOOK_PEMTRUSTEDCAS_CONTENT = "webhook.ssl.pemtrustedcas_content"; - + // Log4j public static final String SECURITY_AUDIT_LOG4J_LOGGER_NAME = "log4j.logger_name"; public static final String SECURITY_AUDIT_LOG4J_LEVEL = "log4j.level"; - + //retry public static final String SECURITY_AUDIT_RETRY_COUNT = "plugins.security.audit.config.retry_count"; public static final String SECURITY_AUDIT_RETRY_DELAY_MS = "plugins.security.audit.config.retry_delay_ms"; - + public static final String SECURITY_KERBEROS_KRB5_FILEPATH = "plugins.security.kerberos.krb5_filepath"; public static final String SECURITY_KERBEROS_ACCEPTOR_KEYTAB_FILEPATH = "plugins.security.kerberos.acceptor_keytab_filepath"; public static final String SECURITY_KERBEROS_ACCEPTOR_PRINCIPAL = "plugins.security.kerberos.acceptor_principal"; diff --git a/src/main/java/org/opensearch/security/support/HTTPHelper.java b/src/main/java/org/opensearch/security/support/HTTPHelper.java index e7554f120d..5e9fc78f8c 100644 --- a/src/main/java/org/opensearch/security/support/HTTPHelper.java +++ b/src/main/java/org/opensearch/security/support/HTTPHelper.java @@ -55,7 +55,7 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log // username:pass:word //blank password // username: - + final int firstColonIndex = decodedBasicHeader.indexOf(':'); String username = null; @@ -63,7 +63,7 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log if (firstColonIndex > 0) { username = decodedBasicHeader.substring(0, firstColonIndex); - + if(decodedBasicHeader.length() - 1 != firstColonIndex) { password = decodedBasicHeader.substring(firstColonIndex + 1); } else { @@ -83,20 +83,20 @@ public static AuthCredentials extractCredentials(String authorizationHeader, Log return null; } } - + public static boolean containsBadHeader(final RestRequest request) { - + final Map> headers; - + if (request != null && ( headers = request.getHeaders()) != null) { for (final String key: headers.keySet()) { - if ( key != null + if ( key != null && key.trim().toLowerCase().startsWith(ConfigConstants.OPENDISTRO_SECURITY_CONFIG_PREFIX.toLowerCase())) { return true; } } } - + return false; } } diff --git a/src/main/java/org/opensearch/security/support/HeaderHelper.java b/src/main/java/org/opensearch/security/support/HeaderHelper.java index 1a7484a781..af8da305d4 100644 --- a/src/main/java/org/opensearch/security/support/HeaderHelper.java +++ b/src/main/java/org/opensearch/security/support/HeaderHelper.java @@ -39,7 +39,7 @@ public static boolean isInterClusterRequest(final ThreadContext context) { } public static boolean isDirectRequest(final ThreadContext context) { - + return "direct".equals(context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE)) || context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_CHANNEL_TYPE) == null; } @@ -49,7 +49,7 @@ public static boolean isExtensionRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_EXTENSION_REQUEST) == Boolean.TRUE; } // CS-ENFORCE-SINGLE - + public static String getSafeFromHeader(final ThreadContext context, final String headerName) { if (context == null || headerName == null || headerName.isEmpty()) { @@ -73,7 +73,7 @@ public static Serializable deserializeSafeFromHeader(final ThreadContext context return null; } - + public static boolean isTrustedClusterRequest(final ThreadContext context) { return context.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_TRUSTED_CLUSTER_REQUEST) == Boolean.TRUE; } diff --git a/src/main/java/org/opensearch/security/support/MapUtils.java b/src/main/java/org/opensearch/security/support/MapUtils.java index 65aa6f7f9d..a50505eae9 100644 --- a/src/main/java/org/opensearch/security/support/MapUtils.java +++ b/src/main/java/org/opensearch/security/support/MapUtils.java @@ -32,11 +32,11 @@ import java.util.Map; public class MapUtils { - + public static void deepTraverseMap(final Map map, final Callback cb) { deepTraverseMap(map, cb, null); } - + private static void deepTraverseMap(final Map map, final Callback cb, final List stack) { final List localStack; if(stack == null) { @@ -58,7 +58,7 @@ private static void deepTraverseMap(final Map map, final Callbac } } } - + public static interface Callback { public void call(String key, Map map, List stack); } diff --git a/src/main/java/org/opensearch/security/support/ModuleInfo.java b/src/main/java/org/opensearch/security/support/ModuleInfo.java index 994e49046c..c8558b1c13 100644 --- a/src/main/java/org/opensearch/security/support/ModuleInfo.java +++ b/src/main/java/org/opensearch/security/support/ModuleInfo.java @@ -36,16 +36,16 @@ import org.opensearch.common.io.stream.Writeable; public class ModuleInfo implements Serializable, Writeable{ - + private static final long serialVersionUID = -1077651823194285138L; - + private ModuleType moduleType; private String classname; private String classpath = ""; private String version = ""; private String buildTime = ""; private String gitsha1 = ""; - + public ModuleInfo(ModuleType moduleType, String classname) { assert(moduleType != null); this.moduleType = moduleType; @@ -73,7 +73,7 @@ public void setVersion(String version) { public void setBuildTime(String buildTime) { this.buildTime = buildTime; } - + public String getGitsha1() { return gitsha1; } @@ -85,7 +85,7 @@ public void setGitsha1(String gitsha1) { public ModuleType getModuleType() { return moduleType; } - + public Map getAsMap() { Map infoMap = new HashMap<>(); infoMap.put("type", moduleType.name()); @@ -99,7 +99,7 @@ public Map getAsMap() { infoMap.put("gitsha1", this.gitsha1); return infoMap; } - + @Override public void writeTo(StreamOutput out) throws IOException { out.writeEnum(moduleType); @@ -109,8 +109,8 @@ public void writeTo(StreamOutput out) throws IOException { out.writeString(buildTime); out.writeString(gitsha1); } - - + + /* (non-Javadoc) * @see java.lang.Object#hashCode() @@ -180,5 +180,5 @@ public boolean equals(Object obj) { public String toString() { return "Module [type=" + this.moduleType.name() + ", implementing class=" + this.classname + "]"; } - + } diff --git a/src/main/java/org/opensearch/security/support/PemKeyReader.java b/src/main/java/org/opensearch/security/support/PemKeyReader.java index fb3a595f9e..7d37fee4f3 100644 --- a/src/main/java/org/opensearch/security/support/PemKeyReader.java +++ b/src/main/java/org/opensearch/security/support/PemKeyReader.java @@ -72,12 +72,12 @@ import org.opensearch.env.Environment; public final class PemKeyReader { - + //private static final String[] EMPTY_STRING_ARRAY = new String[0]; protected static final Logger log = LogManager.getLogger(PemKeyReader.class); static final String JKS = "JKS"; static final String PKCS12 = "PKCS12"; - + private static final Pattern KEY_PATTERN = Pattern.compile( "-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+" + // Header "([a-z0-9+/=\\r\\n]+)" + // Base64 text @@ -147,7 +147,7 @@ private static void safeClose(OutputStream out) { //ignore } } - + public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException { if (keyFile == null) { @@ -155,7 +155,7 @@ public static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws N } return getPrivateKeyFromByteBuffer(PemKeyReader.readPrivateKey(keyFile), keyPassword); } - + public static PrivateKey toPrivateKey(InputStream in, String keyPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidAlgorithmParameterException, KeyException, IOException { if (in == null) { @@ -182,7 +182,7 @@ private static PrivateKey getPrivateKeyFromByteBuffer(byte[] encodedKey, String } } } - + private static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException, InvalidAlgorithmParameterException { @@ -201,27 +201,27 @@ private static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) return encryptedPrivateKeyInfo.getKeySpec(cipher); } - + public static X509Certificate loadCertificateFromFile(String file) throws Exception { if(file == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); try(FileInputStream is = new FileInputStream(file)) { return (X509Certificate) fact.generateCertificate(is); } } - + public static X509Certificate loadCertificateFromStream(InputStream in) throws Exception { if(in == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); return (X509Certificate) fact.generateCertificate(in); } - + public static KeyStore loadKeyStore(String storePath, String keyStorePassword, String type) throws Exception { if(storePath == null) { return null; @@ -230,36 +230,36 @@ public static KeyStore loadKeyStore(String storePath, String keyStorePassword, S if(type == null || !type.toUpperCase().equals(JKS) || !type.toUpperCase().equals(PKCS12)) { type = JKS; } - + final KeyStore store = KeyStore.getInstance(type.toUpperCase()); store.load(new FileInputStream(storePath), keyStorePassword==null?null:keyStorePassword.toCharArray()); return store; } public static PrivateKey loadKeyFromFile(String password, String keyFile) throws Exception { - + if(keyFile == null) { return null; } - + return PemKeyReader.toPrivateKey(new File(keyFile), password); } - + public static PrivateKey loadKeyFromStream(String password, InputStream in) throws Exception { - + if(in == null) { return null; } - + return PemKeyReader.toPrivateKey(in, password); } - + public static void checkPath(String keystoreFilePath, String fileNameLogOnly) { - + if (keystoreFilePath == null || keystoreFilePath.length() == 0) { throw new OpenSearchException("Empty file path for "+fileNameLogOnly); } - + if (Files.isDirectory(Paths.get(keystoreFilePath), LinkOption.NOFOLLOW_LINKS)) { throw new OpenSearchException("Is a directory: " + keystoreFilePath+" Expected a file for "+fileNameLogOnly); } @@ -268,34 +268,34 @@ public static void checkPath(String keystoreFilePath, String fileNameLogOnly) { throw new OpenSearchException("Unable to read " + keystoreFilePath + " ("+Paths.get(keystoreFilePath)+"). Please make sure this files exists and is readable regarding to permissions. Property: "+fileNameLogOnly); } } - + public static X509Certificate[] loadCertificatesFromFile(String file) throws Exception { if(file == null) { return null; } - + try(FileInputStream is = new FileInputStream(file)) { return loadCertificatesFromStream(is); } - + } public static X509Certificate[] loadCertificatesFromFile(File file) throws Exception { if(file == null) { return null; } - + try(FileInputStream is = new FileInputStream(file)) { return loadCertificatesFromStream(is); } - + } - + public static X509Certificate[] loadCertificatesFromStream(InputStream in) throws Exception { if(in == null) { return null; } - + CertificateFactory fact = CertificateFactory.getInstance("X.509"); Collection certs = fact.generateCertificates(in); X509Certificate[] x509Certs = new X509Certificate[certs.size()]; @@ -304,21 +304,21 @@ public static X509Certificate[] loadCertificatesFromStream(InputStream in) throw x509Certs[i++] = (X509Certificate) cert; } return x509Certs; - + } - + public static InputStream resolveStream(String propName, Settings settings) { final String content = settings.get(propName, null); - + if(content == null) { return null; } return new ByteArrayInputStream(content.getBytes(StandardCharsets.US_ASCII)); } - - public static String resolve(String propName, Settings settings, Path configPath, boolean mustBeValid) { + + public static String resolve(String propName, Settings settings, Path configPath, boolean mustBeValid) { final String originalPath = settings.get(propName, null); return resolve(originalPath, propName, settings, configPath, mustBeValid); } @@ -327,32 +327,32 @@ public static String resolve(String originalPath, String propName, Settings sett log.debug("Path is is {}", originalPath); String path = originalPath; final Environment env = new Environment(settings, configPath); - + if(env != null && originalPath != null && originalPath.length() > 0) { path = env.configDir().resolve(originalPath).toAbsolutePath().toString(); log.debug("Resolved {} to {} against {}", originalPath, path, env.configDir().toAbsolutePath().toString()); } - + if(mustBeValid) { checkPath(path, propName); } - + if("".equals(path)) { path = null; } - - return path; + + return path; } - + public static KeyStore toTruststore(final String trustCertificatesAliasPrefix, final X509Certificate[] trustCertificates) throws Exception { - + if(trustCertificates == null) { return null; } - + KeyStore ks = KeyStore.getInstance(JKS); ks.load(null); - + if(trustCertificates != null && trustCertificates.length > 0) { for (int i = 0; i < trustCertificates.length; i++) { X509Certificate x509Certificate = trustCertificates[i]; @@ -361,10 +361,10 @@ public static KeyStore toTruststore(final String trustCertificatesAliasPrefix, f } return ks; } - + public static KeyStore toKeystore(final String authenticationCertificateAlias, final char[] password, final X509Certificate authenticationCertificate[], final PrivateKey authenticationKey) throws Exception { - if(authenticationCertificateAlias != null && authenticationCertificate != null && authenticationKey != null) { + if(authenticationCertificateAlias != null && authenticationCertificate != null && authenticationKey != null) { KeyStore ks = KeyStore.getInstance(JKS); ks.load(null, null); ks.setKeyEntry(authenticationCertificateAlias, authenticationKey, password, authenticationCertificate); @@ -374,7 +374,7 @@ public static KeyStore toKeystore(final String authenticationCertificateAlias, f } } - + public static char[] randomChars(int len) { final SecureRandom r = new SecureRandom(); final char[] ret = new char[len]; diff --git a/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java b/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java index 8f12ffaf61..8ddc52f428 100644 --- a/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java +++ b/src/main/java/org/opensearch/security/support/ReflectiveAttributeAccessors.java @@ -28,7 +28,7 @@ public static Function objectAttr(String name) { public static Function objectAttr(String name, Class type) { return new ReflectiveAttributeGetter(name, type); } - + public static Function protectedObjectAttr(String name, Class type) { return new ProtectedReflectiveAttributeGetter(name, type); } @@ -114,7 +114,7 @@ public R apply(O object) { } } - + static class ReflectiveAttributeSetter implements BiFunction { private final String attribute; private final String methodName; diff --git a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java index 472ab2bb86..d1e2f4d34e 100644 --- a/src/main/java/org/opensearch/security/support/SecurityJsonNode.java +++ b/src/main/java/org/opensearch/security/support/SecurityJsonNode.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2018 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.support; @@ -28,22 +28,22 @@ import org.opensearch.security.DefaultObjectMapper; public final class SecurityJsonNode { - + private final JsonNode node; public SecurityJsonNode(JsonNode node) { this.node = node; } - + public SecurityJsonNode get(String name) { if(isNull(node)) { return new SecurityJsonNode(null); } - + JsonNode val = node.get(name); return new SecurityJsonNode(val); } - + public String asString() { if(isNull(node)) { return null; @@ -51,11 +51,11 @@ public String asString() { return node.asText(null); } } - + private static boolean isNull(JsonNode node) { return node == null || node.isNull(); } - + public boolean isNull() { return isNull(this.node); } @@ -73,25 +73,25 @@ public SecurityJsonNode getDotted(String string) { for(String part: string.split("\\.")) { tmp = tmp.get(part); } - + return tmp; - + } public List asList() { if(isNull(node) || node.getNodeType() != JsonNodeType.ARRAY) { return null; } - + List retVal = new ArrayList(); - + for(int i=0; i> map, final String in .findAny() .orElse(null); } - + @SafeVarargs public static Map mapFromArray(T ... keyValues) { if(keyValues == null) { @@ -109,25 +109,25 @@ public static Map mapFromArray(T ... keyValues) { return null; } Map map = new HashMap<>(); - + for(int i = 0; i resolveOriginalIndices(RestoreSnapshotRequest restoreRequest) { final SnapshotInfo snapshotInfo = getSnapshotInfo(restoreRequest); @@ -57,17 +57,17 @@ public static List resolveOriginalIndices(RestoreSnapshotRequest restore return null; } else { return SnapshotUtils.filterIndices(snapshotInfo.indices(), restoreRequest.indices(), restoreRequest.indicesOptions()); - } - - + } + + } - + public static SnapshotInfo getSnapshotInfo(RestoreSnapshotRequest restoreRequest) { final RepositoriesService repositoriesService = Objects.requireNonNull(OpenSearchSecurityPlugin.GuiceHolder.getRepositoriesService(), "RepositoriesService not initialized"); final Repository repository = repositoriesService.repository(restoreRequest.repository()); final String threadName = Thread.currentThread().getName(); SnapshotInfo snapshotInfo = null; - + try { setCurrentThreadName("[" + ThreadPool.Names.GENERIC + "]"); for (SnapshotId snapshotId : PlainActionFuture.get(repository::getRepositoryData).getSnapshotIds()) { @@ -86,7 +86,7 @@ public static SnapshotInfo getSnapshotInfo(RestoreSnapshotRequest restoreRequest } return snapshotInfo; } - + @SuppressWarnings("removal") private static void setCurrentThreadName(final String name) { final SecurityManager sm = System.getSecurityManager(); @@ -94,7 +94,7 @@ private static void setCurrentThreadName(final String name) { if (sm != null) { sm.checkPermission(new SpecialPermission()); } - + AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { @@ -103,5 +103,5 @@ public Object run() { } }); } - + } diff --git a/src/main/java/org/opensearch/security/support/SourceFieldsContext.java b/src/main/java/org/opensearch/security/support/SourceFieldsContext.java index 175415a5b6..8f61bcbaf5 100644 --- a/src/main/java/org/opensearch/security/support/SourceFieldsContext.java +++ b/src/main/java/org/opensearch/security/support/SourceFieldsContext.java @@ -97,7 +97,7 @@ public String[] getExcludes() { public boolean hasIncludesOrExcludes() { return (includes != null && includes.length > 0) || (excludes != null && excludes.length > 0); } - + public boolean isFetchSource() { return fetchSource; } diff --git a/src/main/java/org/opensearch/security/support/WildcardMatcher.java b/src/main/java/org/opensearch/security/support/WildcardMatcher.java index f22f981fd2..302736fe67 100644 --- a/src/main/java/org/opensearch/security/support/WildcardMatcher.java +++ b/src/main/java/org/opensearch/security/support/WildcardMatcher.java @@ -296,7 +296,7 @@ public static List getAllMatchingPatterns(final Collection val = Migration.migrateConfig(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.CONFIG, 1, 0, 0)); return backupAndWrite(file, val, backup); @@ -121,12 +121,12 @@ public static boolean migrateFile(File file, CType cType, boolean backup) { boolean roles = backupAndWrite(file, tup.v1(), backup); return roles && backupAndWrite(new File(file.getParent(),"tenants.yml"), tup.v2(), backup); } - + if(cType == CType.ROLESMAPPING) { SecurityDynamicConfiguration val = Migration.migrateRoleMappings(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.ROLESMAPPING, 1, 0, 0)); return backupAndWrite(file, val, backup); } - + if(cType == CType.INTERNALUSERS) { SecurityDynamicConfiguration val = Migration.migrateInternalUsers(SecurityDynamicConfiguration.fromNode(DefaultObjectMapper.YAML_MAPPER.readTree(file), CType.INTERNALUSERS, 1, 0, 0)); return backupAndWrite(file, val, backup); @@ -147,11 +147,11 @@ public static boolean migrateFile(File file, CType cType, boolean backup) { } catch (Exception e) { System.out.println("Can not migrate "+file+" due to "+e); } - - + + return false; } - + private static boolean backupAndWrite(File file, SecurityDynamicConfiguration val, boolean backup) { try { if(val == null) { @@ -169,7 +169,7 @@ private static boolean backupAndWrite(File file, SecurityDynamicConfiguration System.out.println(" Details: "+e.getMessage()); e.printStackTrace(); } - + return false; } } diff --git a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java index 2427a48f8a..738e0e6b20 100644 --- a/src/main/java/org/opensearch/security/tools/SecurityAdmin.java +++ b/src/main/java/org/opensearch/security/tools/SecurityAdmin.java @@ -162,7 +162,7 @@ public class SecurityAdmin { private static final Settings ENABLE_ALL_ALLOCATIONS_SETTINGS = Settings.builder() .put("cluster.routing.allocation.enable", "all") .build(); - + public static void main(final String[] args) { try { final int returnCode = execute(args); @@ -173,7 +173,7 @@ public static void main(final String[] args) { System.out.println(ExceptionsHelper.stackTrace(e)); System.out.println(); System.exit(-1); - } + } catch (IndexNotFoundException e) { System.out.println("ERR: No OpenSearch Security configuration index found. Please execute securityadmin with different command line parameters"); System.out.println("When you run it for the first time do not specify -us, -era, -dra or -rl"); @@ -181,16 +181,16 @@ public static void main(final String[] args) { System.exit(-1); } catch (Throwable e) { - + if (e instanceof OpenSearchException - && e.getMessage() != null + && e.getMessage() != null && e.getMessage().contains("no permissions")) { - System.out.println("ERR: You try to connect with a TLS node certificate instead of an admin client certificate"); + System.out.println("ERR: You try to connect with a TLS node certificate instead of an admin client certificate"); System.out.println(); System.exit(-1); } - + System.out.println("ERR: An unexpected "+e.getClass().getSimpleName()+" occured: "+e.getMessage()); System.out.println("Trace:"); System.out.println(ExceptionsHelper.stackTrace(e)); @@ -200,7 +200,7 @@ public static void main(final String[] args) { } public static int execute(final String[] args) throws Exception { - + System.out.println("Security Admin v7"); System.setProperty("security.nowarn.client","true"); System.setProperty("jdk.tls.rejectClientInitiatedRenegotiation","true"); @@ -256,16 +256,16 @@ public static int execute(final String[] args) throws Exception { options.addOption(Option.builder("backup").hasArg().argName("folder").desc("Backup configuration to folder").build()); options.addOption(Option.builder("migrate").hasArg().argName("folder").desc("Migrate and use folder to store migrated files").build()); - + options.addOption(Option.builder("rev").longOpt("resolve-env-vars").desc("Resolve/Substitute env vars in config with their value before uploading").build()); options.addOption(Option.builder("vc").numberOfArgs(1).optionalArg(true).argName("version").longOpt("validate-configs").desc("Validate config for version 6 or 7 (default 7)").build()); options.addOption(Option.builder("mo").longOpt("migrate-offline").hasArg().argName("folder").desc("Migrate and use folder to store migrated files").build()); - + //when adding new options also adjust validate(CommandLine line) - + String hostname = "localhost"; int port = 9200; String kspass = System.getenv(OPENDISTRO_SECURITY_KS_PASS); @@ -293,7 +293,7 @@ public static int execute(final String[] args) throws Exception { boolean deleteConfigIndex = false; boolean enableShardAllocation = false; boolean acceptRedCluster = false; - + String keypass = System.getenv(OPENDISTRO_SECURITY_KEYPASS); String cacert = null; String cert = null; @@ -316,28 +316,28 @@ public static int execute(final String[] args) throws Exception { CommandLineParser parser = new DefaultParser(); try { CommandLine line = parser.parse( options, args ); - + validate(line); - + hostname = line.getOptionValue("h", hostname); port = Integer.parseInt(line.getOptionValue("p", String.valueOf(port))); promptForPassword = line.hasOption("prompt"); - + if(kspass == null || kspass.isEmpty()) { kspass = line.getOptionValue("kspass",promptForPassword?null:"changeit"); } - + if(tspass == null || tspass.isEmpty()) { tspass = line.getOptionValue("tspass",promptForPassword?null:kspass); } cd = line.getOptionValue("cd", cd); - + if(!cd.endsWith(File.separator)) { cd += File.separator; } - + ks = line.getOptionValue("ks",ks); ts = line.getOptionValue("ts",ts); kst = line.getOptionValue("kst", kst); @@ -349,87 +349,87 @@ public static int execute(final String[] args) throws Exception { retrieve = line.hasOption("r"); ksAlias = line.getOptionValue("ksalias", ksAlias); index = line.getOptionValue("i", index); - + String enabledCiphersString = line.getOptionValue("ec", null); String enabledProtocolsString = line.getOptionValue("ep", null); - + if(enabledCiphersString != null) { enabledCiphers = enabledCiphersString.split(","); } - + if(enabledProtocolsString != null) { enabledProtocols = enabledProtocolsString.split(","); } - + updateSettings = line.hasOption("us")?Integer.parseInt(line.getOptionValue("us")):null; reload = line.hasOption("rl"); - + if(line.hasOption("era")) { replicaAutoExpand = true; } - + if(line.hasOption("dra")) { replicaAutoExpand = false; } - + failFast = line.hasOption("ff"); diagnose = line.hasOption("dg"); deleteConfigIndex = line.hasOption("dci"); enableShardAllocation = line.hasOption("esa"); acceptRedCluster = line.hasOption("arc"); - + cacert = line.getOptionValue("cacert"); cert = line.getOptionValue("cert"); key = line.getOptionValue("key"); keypass = line.getOptionValue("keypass", keypass); si = line.hasOption("si"); - + whoami = line.hasOption("w"); - + explicitReplicas = line.getOptionValue("er", explicitReplicas); - + backup = line.getOptionValue("backup"); - + migrate = line.getOptionValue("migrate"); - + resolveEnvVars = line.hasOption("rev"); - + validateConfig = !line.hasOption("vc")?null:Integer.parseInt(line.getOptionValue("vc", "7")); - + if(validateConfig != null && validateConfig.intValue() != 6 && validateConfig.intValue() != 7) { throw new ParseException("version must be 6 or 7"); } - + migrateOffline = line.getOptionValue("mo"); - + } catch( ParseException exp ) { System.out.println("ERR: Parsing failed. Reason: " + exp.getMessage()); formatter.printHelp("securityadmin.sh", options, true); return -1; } - + if(validateConfig != null) { System.out.println("Validate configuration for Version "+validateConfig.intValue()); return validateConfig(cd, file, type, validateConfig.intValue()); } - + if(migrateOffline != null) { System.out.println("Migrate "+migrateOffline+" offline"); final boolean retVal = Migrater.migrateDirectory(new File(migrateOffline), true); return retVal?0:-1; } - + System.out.print("Will connect to "+hostname+":"+port); Socket socket = new Socket(); - + try { - + socket.connect(new InetSocketAddress(hostname, port)); - + } catch (java.net.ConnectException ex) { System.out.println(); System.out.println("ERR: Seems there is no OpenSearch running on "+hostname+":"+port+" - Will exit"); @@ -450,13 +450,13 @@ public static int execute(final String[] args) throws Exception { kspass = promptForPassword("Keystore", "kspass", OPENDISTRO_SECURITY_KS_PASS); } } - + if(ts != null) { tst = tst==null?(ts.endsWith(".jks")?"JKS":"PKCS12"):tst; if(tspass == null && promptForPassword) { tspass = promptForPassword("Truststore", "tspass", OPENDISTRO_SECURITY_TS_PASS); } - } + } if(key != null) { @@ -549,7 +549,7 @@ public static int execute(final String[] args) throws Exception { System.out.println("Reload config on all nodes"); return 0; } - + if(si) { return (0); } @@ -558,9 +558,9 @@ public static int execute(final String[] args) throws Exception { System.out.println(whoAmIResNode.toPrettyString()); return (0); } - - - if(replicaAutoExpand != null) { + + + if(replicaAutoExpand != null) { Settings indexSettings = Settings.builder() .put("index.auto_expand_replicas", replicaAutoExpand?"0-all":"false") .build(); @@ -594,10 +594,10 @@ public static int execute(final String[] args) throws Exception { } else { System.out.println("ERR: Unable to enable shard allocation"); } - + return (successful?0:-1); - } - + } + if(failFast) { System.out.println("Fail-fast is activated"); } @@ -620,11 +620,11 @@ public static int execute(final String[] args) throws Exception { } catch (Exception e) { Throwable rootCause = ExceptionUtils.getRootCause(e); - + if(!failFast) { System.out.println("Cannot retrieve cluster state due to: "+e.getMessage()+". This is not an error, will keep on trying ..."); System.out.println(" Root cause: "+rootCause+" ("+e.getClass().getName()+"/"+rootCause.getClass().getName()+")"); - System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); + System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); @@ -634,12 +634,12 @@ public static int execute(final String[] args) throws Exception { System.out.println(" Root cause: "+rootCause+" ("+e.getClass().getName()+"/"+rootCause.getClass().getName()+")"); System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make also sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); - System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); + System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); return (-1); } - + Thread.sleep(3000); continue; } @@ -651,7 +651,7 @@ public static int execute(final String[] args) throws Exception { System.out.println("ERR: Timed out while waiting for a green or yellow cluster state."); System.out.println(" * Try running securityadmin.sh with -icl (but no -cl) and -nhnv (If that works you need to check your clustername as well as hostnames in your TLS certificates)"); System.out.println(" * Make also sure that your keystore or PEM certificate is a client certificate (not a node certificate) and configured properly in opensearch.yml"); - System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); + System.out.println(" * If this is not working, try running securityadmin.sh with --diagnose and see diagnose trace log file)"); System.out.println(" * Add --accept-red-cluster to allow securityadmin to operate on a red cluster."); return (-1); } @@ -680,7 +680,7 @@ public static int execute(final String[] args) throws Exception { if(deleteConfigIndex) { return deleteConfigIndex(restHighLevelClient, index, indexExists); } - + if (!indexExists) { System.out.print(index +" index does not exists, attempt to create it ... "); final int created = createConfigIndex(restHighLevelClient, index, explicitReplicas); @@ -690,7 +690,7 @@ public static int execute(final String[] args) throws Exception { } else { System.out.println(index+" index already exists, so we do not need to create one."); - + try { ClusterHealthResponse clusterHealthResponse = restHighLevelClient.cluster().health(new ClusterHealthRequest(index), RequestOptions.DEFAULT); @@ -705,7 +705,7 @@ public static int execute(final String[] args) throws Exception { if (clusterHealthResponse.getStatus() == ClusterHealthStatus.YELLOW) { System.out.println("INFO: "+index+" index state is YELLOW, it seems you miss some replicas"); } - + } catch (Exception e) { if(!failFast) { System.out.println("Cannot retrieve "+index+" index state state due to "+e.getMessage()+". This is not an error, will keep on trying ..."); @@ -726,7 +726,7 @@ public static int execute(final String[] args) throws Exception { && securityIndex.getMappings() != null && securityIndex.getMappings().get(index) != null && securityIndex.getMappings().get(index).getSourceAsMap().containsKey("security")); - + if(legacy) { System.out.println("Legacy index '"+index+"' (ES 6) detected (or forced). You should migrate the configuration!"); } @@ -765,9 +765,9 @@ public static int execute(final String[] args) throws Exception { } boolean isCdAbs = new File(cd).isAbsolute(); - + System.out.println("Populate config from "+(isCdAbs?cd:new File(".", cd).getCanonicalPath())); - + if(file != null) { if(type != null) { System.out.println("Force type: "+type); @@ -828,7 +828,7 @@ private static boolean checkConfigUpdateResponse(Response response, int expected } else { System.out.println("SUCC: Expected " + expectedConfigCount + " config types for node " + n + " is " + n.get("updated_config_size").asInt() + " (" + n.get("updated_config_types") + ") due to: " + (n.get("message") == null ? "unknown reason" : n.get("message"))); } - + success = success && successNode; } @@ -843,7 +843,7 @@ private static boolean uploadFile(final RestHighLevelClient restHighLevelClient, final boolean populateEmptyIfMissing) { String id = _id; - + if(legacy) { id = _id; @@ -892,12 +892,12 @@ private static boolean retrieveFile(final RestHighLevelClient restHighLevelClien private static boolean retrieveFile(final RestHighLevelClient restHighLevelClient, final String filepath, final String index, final String _id, final boolean legacy, final boolean populateFileIfEmpty) { String id = _id; - + if(legacy) { id = _id; - + } - + System.out.println("Will retrieve '"+"/" +id+"' into "+filepath+" "+(legacy?"(legacy mode)":"")); try (Writer writer = new FileWriter(filepath, StandardCharsets.UTF_8)) { @@ -944,7 +944,7 @@ private static boolean retrieveFile(final RestHighLevelClient restHighLevelClien } catch (Exception e) { System.out.println(" FAIL: Get configuration for '"+_id+"' failed because of "+e.toString()); } - + return false; } @@ -962,23 +962,23 @@ private static BytesReference readXContent(final String content, final MediaType parser.close(); } } - + //validate return retVal; } - + private static String convertToYaml(String type, BytesReference bytes, boolean prettyPrint) throws IOException { - + try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, bytes.streamInput())) { parser.nextToken(); parser.nextToken(); - + if(!type.equals((parser.currentName()))) { return null; } - + parser.nextToken(); - + XContentBuilder builder = XContentFactory.yamlBuilder(); if (prettyPrint) { builder.prettyPrint(); @@ -991,7 +991,7 @@ private static String convertToYaml(String type, BytesReference bytes, boolean p protected static void generateDiagnoseTrace(final RestHighLevelClient restHighLevelClient) { final String date = DATE_FORMAT.format(new Date()); - + final StringBuilder sb = new StringBuilder(); sb.append("Diagnostic securityadmin trace"+System.lineSeparator()); sb.append("OpenSearch client version: "+Version.CURRENT+System.lineSeparator()); @@ -1061,19 +1061,19 @@ private static void validate(CommandLine line) throws ParseException { if(line.hasOption("ts") && line.hasOption("cacert")) { System.out.println("WARN: It makes no sense to specify -ts as well as -cacert"); } - + if(line.hasOption("ks") && line.hasOption("cert")) { System.out.println("WARN: It makes no sense to specify -ks as well as -cert"); } - + if(line.hasOption("ks") && line.hasOption("key")) { System.out.println("WARN: It makes no sense to specify -ks as well as -key"); } - + if(line.hasOption("cd") && line.hasOption("rl")) { System.out.println("WARN: It makes no sense to specify -cd as well as -r"); } - + if(line.hasOption("cd") && line.hasOption("f")) { System.out.println("WARN: It makes no sense to specify -cd as well as -f"); } @@ -1089,15 +1089,15 @@ private static void validate(CommandLine line) throws ParseException { if(!line.hasOption("vc") && !line.hasOption("ks") && !line.hasOption("cert") /*&& !line.hasOption("simple-auth")*/) { throw new ParseException("Specify at least -ks or -cert"); } - - if(!line.hasOption("vc") && !line.hasOption("mo") + + if(!line.hasOption("vc") && !line.hasOption("mo") && !line.hasOption("ts") && !line.hasOption("cacert")) { throw new ParseException("Specify at least -ts or -cacert"); } - + //TODO add more validation rules } - + private static String promptForPassword(String passwordName, String commandLineOption, String envVarName) throws Exception { final Console console = System.console(); if(console == null) { @@ -1132,7 +1132,7 @@ private static int issueWarnings(RestHighLevelClient restHighLevelClient) throws if(!ALLOW_MIXED) { return -1; } - + } else { System.out.println("OpenSearch Version: "+minVersion.toString()); } @@ -1161,14 +1161,14 @@ private static int deleteConfigIndex(RestHighLevelClient restHighLevelClient, St } else { System.out.print("No index '"+index+"' exists, so no need to delete it"); } - + return (success?0:-1); } private static int createConfigIndex(RestHighLevelClient restHighLevelClient, String index, String explicitReplicas) throws IOException { Map indexSettings = new HashMap<>(); indexSettings.put("index.number_of_shards", 1); - + if(explicitReplicas != null) { if(explicitReplicas.contains("-")) { indexSettings.put("index.auto_expand_replicas", explicitReplicas); @@ -1218,11 +1218,11 @@ private static int upload(RestHighLevelClient tc, String index, String cd, boole boolean success = uploadFile(tc, cd + "config.yml", index, "config", legacy, resolveEnvVars); success = uploadFile(tc, cd+"roles.yml", index, "roles", legacy, resolveEnvVars) && success; success = uploadFile(tc, cd+"roles_mapping.yml", index, "rolesmapping", legacy, resolveEnvVars) && success; - + success = uploadFile(tc, cd+"internal_users.yml", index, "internalusers", legacy, resolveEnvVars) && success; success = uploadFile(tc, cd+"action_groups.yml", index, "actiongroups", legacy, resolveEnvVars) && success; - + if(!legacy) { success = uploadFile(tc, cd+"tenants.yml", index, "tenants", legacy, resolveEnvVars) && success; } @@ -1252,18 +1252,18 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, System.out.println("== Migration started =="); System.out.println("======================="); - + System.out.println("-> Backup current configuration to "+backupDir.getAbsolutePath()); - + if(backup(tc, index, backupDir, true) != 0) { return -1; } System.out.println(" done"); - + File v7Dir = new File(backupDir,"v7"); v7Dir.mkdirs(); - + try { System.out.println("-> Migrate configuration to new format and store it here: "+v7Dir.getAbsolutePath()); @@ -1303,13 +1303,13 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, e.printStackTrace(); return -1; } - + System.out.println(" done"); - + System.out.println("-> Delete old "+index+" index"); deleteConfigIndex(tc, index, true); System.out.println(" done"); - + System.out.println("-> Upload new configuration into OpenSearch cluster"); int uploadResult = upload(tc, index, v7Dir.getAbsolutePath() + "/", false, expectedNodeCount, resolveEnvVars); @@ -1319,10 +1319,10 @@ private static int migrate(RestHighLevelClient tc, String index, File backupDir, }else { System.out.println(" ERR: unable to upload"); } - + return uploadResult; } - + private static String readTypeFromFile(File file) throws IOException { if(!file.exists() || !file.isFile()) { System.out.println("ERR: No such file "+file.getAbsolutePath()); @@ -1335,16 +1335,16 @@ private static String readTypeFromFile(File file) throws IOException { private static int validateConfig(String cd, String file, String type, int version) { if (file != null) { try { - + if(type == null) { type = readTypeFromFile(new File(file)); } - + if(type == null) { System.out.println("ERR: Unable to read type from "+file); return -1; } - + ConfigHelper.fromYamlFile(file, CType.fromString(type), version==7?2:1, 0, 0); return 0; } catch (Exception e) { @@ -1357,7 +1357,7 @@ private static int validateConfig(String cd, String file, String type, int versi success = validateConfigFile(cd+"roles.yml", CType.ROLES, version) && success; success = validateConfigFile(cd+"roles_mapping.yml", CType.ROLESMAPPING, version) && success; success = validateConfigFile(cd+"config.yml", CType.CONFIG, version) && success; - + if(new File(cd+"tenants.yml").exists() && version != 6) { success = validateConfigFile(cd+"tenants.yml", CType.TENANTS, version) && success; } @@ -1368,10 +1368,10 @@ private static int validateConfig(String cd, String file, String type, int versi return success?0:-1; } - + return -1; } - + private static boolean validateConfigFile(String file, CType cType, int version) { try { ConfigHelper.fromYamlFile(file, cType, version==7?2:1, 0, 0); diff --git a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java index 6a7917b385..84087b5ed9 100644 --- a/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/DefaultInterClusterRequestEvaluator.java @@ -81,9 +81,9 @@ private WildcardMatcher getNodesDnToEvaluate() { @Override public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] localCerts, X509Certificate[] peerCerts, final String principal) { - + String[] principals = new String[2]; - + if (principal != null && principal.length() > 0) { principals[0] = principal; principals[1] = principal.replace(" ",""); @@ -93,14 +93,14 @@ public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] final boolean isTraceEnabled = log.isTraceEnabled(); if (principals[0] != null && nodesDn.matchAny(principals)) { - + if (isTraceEnabled) { log.trace("Treat certificate with principal {} as other node because of it matches one of {}", Arrays.toString(principals), nodesDn); } - + return true; - + } else { if (isTraceEnabled) { log.trace("Treat certificate with principal {} NOT as other node because we it does not matches one of {}", Arrays.toString(principals), diff --git a/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java b/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java index 38f4426420..81cfa9e345 100644 --- a/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java +++ b/src/main/java/org/opensearch/security/transport/InterClusterRequestEvaluator.java @@ -42,18 +42,18 @@ public interface InterClusterRequestEvaluator { /** * Determine if request is a message from * another node in the cluster - * + * * @param request The transport request to evaluate * @param localCerts Local certs to use for evaluating the request which include criteria * specific to the implementation for confirming intercluster * communication - * + * * @param peerCerts Certs to use for evaluating the request which include criteria * specific to the implementation for confirming intercluster * communication - * + * * @param principal The principal evaluated by the configured principal extractor - * + * * @return True when determined to be intercluster, false otherwise */ boolean isInterClusterRequest(final TransportRequest request, final X509Certificate[] localCerts, final X509Certificate[] peerCerts, diff --git a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java index e17560a000..5456d36d9c 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java +++ b/src/main/java/org/opensearch/security/transport/SecurityInterceptor.java @@ -142,7 +142,7 @@ public void sendRequestDecorate(AsyncSender sender || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DOC_ALLOWLIST_HEADER) || k.equals(ConfigConstants.OPENDISTRO_SECURITY_FILTER_LEVEL_DLS_DONE) || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_MODE_HEADER) - || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER) + || k.equals(ConfigConstants.OPENDISTRO_SECURITY_DLS_FILTER_LEVEL_QUERY_HEADER) || (k.equals("_opendistro_security_source_field_context") && ! (request instanceof SearchRequest) && !(request instanceof GetRequest)) || k.startsWith("_opendistro_security_trace") || k.startsWith(ConfigConstants.OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER) @@ -269,18 +269,18 @@ public T read(StreamInput in) throws IOException { @Override public void handleResponse(T response) { - + ThreadContext threadContext = getThreadContext(); Map> responseHeaders = threadContext.getResponseHeaders(); List flsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_FLS_FIELDS_HEADER); List dlsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_DLS_QUERY_HEADER); List maskedFieldsResponseHeader = responseHeaders.get(ConfigConstants.OPENDISTRO_SECURITY_MASKED_FIELD_HEADER); - + contextToRestore.restore(); final boolean isDebugEnabled = log.isDebugEnabled(); - if (response instanceof ClusterSearchShardsResponse) { + if (response instanceof ClusterSearchShardsResponse) { if (flsResponseHeader != null && !flsResponseHeader.isEmpty()) { if (isDebugEnabled) { log.debug("add flsResponseHeader as transient"); diff --git a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java index c6c80ba50e..4a2919fdb2 100644 --- a/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java +++ b/src/main/java/org/opensearch/security/transport/SecurityRequestHandler.java @@ -296,7 +296,7 @@ else if(!Strings.isNullOrEmpty(injectedUserHeader)) { } } } - + private void putInitialActionClassHeader(String initialActionClassValue, String resolvedActionClass) { if(initialActionClassValue == null) { if(getThreadContext().getHeader(ConfigConstants.OPENDISTRO_SECURITY_INITIAL_ACTION_CLASS_HEADER) == null) { diff --git a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java b/src/main/java/org/opensearch/security/user/CustomAttributesAware.java index 89d62d3d5d..f5db96db8a 100644 --- a/src/main/java/org/opensearch/security/user/CustomAttributesAware.java +++ b/src/main/java/org/opensearch/security/user/CustomAttributesAware.java @@ -29,6 +29,6 @@ import java.util.Map; public interface CustomAttributesAware { - + Map getCustomAttributesMap(); } diff --git a/src/main/java/org/opensearch/security/user/User.java b/src/main/java/org/opensearch/security/user/User.java index 83c7ea2eb5..86089afd35 100644 --- a/src/main/java/org/opensearch/security/user/User.java +++ b/src/main/java/org/opensearch/security/user/User.java @@ -56,7 +56,7 @@ public class User implements Serializable, Writeable, CustomAttributesAware { // This is to be used in scenarios where some of the nodes do not have security enabled, and therefore do not pass any user information in threadcontext, yet we need the communication to not break between the nodes. // Attach the required permissions to either the user or the backend role. public static final User DEFAULT_TRANSPORT_USER = new User("opendistro_security_default_transport_user", Lists.newArrayList("opendistro_security_default_transport_backendrole"), null); - + private static final long serialVersionUID = -5500938501822658596L; private final String name; /** @@ -76,10 +76,10 @@ public User(final StreamInput in) throws IOException { attributes = Collections.synchronizedMap(in.readMap(StreamInput::readString, StreamInput::readString)); securityRoles.addAll(in.readList(StreamInput::readString)); } - + /** * Create a new authenticated user - * + * * @param name The username (must not be null or empty) * @param roles Roles of which the user is a member off (maybe null) * @param customAttributes Custom attributes associated with this (maybe null) @@ -97,7 +97,7 @@ public User(final String name, final Collection roles, final AuthCredent if (roles != null) { this.addRoles(roles); } - + if(customAttributes != null) { this.attributes.putAll(customAttributes.getAttributes()); } @@ -106,7 +106,7 @@ public User(final String name, final Collection roles, final AuthCredent /** * Create a new authenticated user without roles and attributes - * + * * @param name The username (must not be null or empty) * @throws IllegalArgumentException if name is null or empty */ @@ -119,7 +119,7 @@ public final String getName() { } /** - * + * * @return A unmodifiable set of the backend roles this user is a member of */ public final Set getRoles() { @@ -128,7 +128,7 @@ public final Set getRoles() { /** * Associate this user with a backend role - * + * * @param role The backend role */ public final void addRole(final String role) { @@ -137,7 +137,7 @@ public final void addRole(final String role) { /** * Associate this user with a set of backend roles - * + * * @param roles The backend roles */ public final void addRoles(final Collection roles) { @@ -148,7 +148,7 @@ public final void addRoles(final Collection roles) { /** * Check if this user is a member of a backend role - * + * * @param role The backend role * @return true if this user is a member of the backend role, false otherwise */ @@ -158,7 +158,7 @@ public final boolean isUserInRole(final String role) { /** * Associate this user with a set of backend roles - * + * * @param roles The backend roles */ public final void addAttributes(final Map attributes) { @@ -166,7 +166,7 @@ public final void addAttributes(final Map attributes) { this.attributes.putAll(attributes); } } - + public final String getRequestedTenant() { return requestedTenant; } @@ -174,8 +174,8 @@ public final String getRequestedTenant() { public final void setRequestedTenant(String requestedTenant) { this.requestedTenant = requestedTenant; } - - + + public boolean isInjected() { return isInjected; } @@ -225,7 +225,7 @@ public final boolean equals(final Object obj) { /** * Copy all backend roles from another user - * + * * @param user The user from which the backend roles should be copied over */ public final void copyRolesFrom(final User user) { @@ -245,7 +245,7 @@ public void writeTo(StreamOutput out) throws IOException { /** * Get the custom attributes associated with this user - * + * * @return A modifiable map with all the current custom attributes associated with this user */ public synchronized final Map getCustomAttributesMap() { @@ -254,13 +254,13 @@ public synchronized final Map getCustomAttributesMap() { } return attributes; } - + public final void addSecurityRoles(final Collection securityRoles) { if(securityRoles != null && this.securityRoles != null) { this.securityRoles.addAll(securityRoles); } } - + public final Set getSecurityRoles() { return this.securityRoles == null ? Collections.synchronizedSet(Collections.emptySet()) : Collections.unmodifiableSet(this.securityRoles); } diff --git a/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java index 37a9817b34..537d4d8fc7 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/HeapBasedRateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.util.ratetracking; @@ -131,7 +131,7 @@ private void shiftFull(long timestamp) { this.startTime = timestamp; return; } - + int shiftOffset = this.timeOffsets[this.timeOffsetStart]; this.startTime += shiftOffset; diff --git a/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java index 5de531f0cb..c90680cd4a 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/RateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.util.ratetracking; diff --git a/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java b/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java index c56639d04a..4f6bd371ed 100644 --- a/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java +++ b/src/main/java/org/opensearch/security/util/ratetracking/SingleTryRateTracker.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.util.ratetracking; diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java index 0aeb4df082..04a30ba2db 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticatorTest.java @@ -41,7 +41,7 @@ public class HTTPJwtAuthenticatorTest { final static byte[] secretKeyBytes = new byte[1024]; final static SecretKey secretKey; - + static { new SecureRandom().nextBytes(secretKeyBytes); secretKey = Keys.hmacShaKeyFor(secretKeyBytes); @@ -50,29 +50,29 @@ public class HTTPJwtAuthenticatorTest { @Test public void testNoKey() throws Exception { - final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder(), - Jwts.builder().setSubject("Leonard McCoy")); + final AuthCredentials credentials = extractCredentialsFromJwtHeader(Settings.builder(), Jwts.builder().setSubject("Leonard McCoy")); Assert.assertNull(credentials); } @Test public void testEmptyKey() throws Exception { - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", ""), - Jwts.builder().setSubject("Leonard McCoy")); + Settings.builder().put("signing_key", ""), + Jwts.builder().setSubject("Leonard McCoy") + ); - Assert.assertNull(credentials); + Assert.assertNull(credentials); } @Test public void testBadKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(new byte[]{1,3,3,4,3,6,7,8,3,10})), - Jwts.builder().setSubject("Leonard McCoy")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(new byte[] { 1, 3, 3, 4, 3, 6, 7, 8, 3, 10 })), + Jwts.builder().setSubject("Leonard McCoy") + ); Assert.assertNull(credentials); } @@ -99,7 +99,7 @@ public void testInvalid() throws Exception { HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); Map headers = new HashMap(); - headers.put("Authorization", "Bearer "+jwsToken); + headers.put("Authorization", "Bearer " + jwsToken); AuthCredentials credentials = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); Assert.assertNull(credentials); @@ -110,11 +110,15 @@ public void testBearer() throws Exception { Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).build(); - String jwsToken = Jwts.builder().setSubject("Leonard McCoy").setAudience("myaud").signWith(secretKey, SignatureAlgorithm.HS512).compact(); + String jwsToken = Jwts.builder() + .setSubject("Leonard McCoy") + .setAudience("myaud") + .signWith(secretKey, SignatureAlgorithm.HS512) + .compact(); HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); Map headers = new HashMap(); - headers.put("Authorization", "Bearer "+jwsToken); + headers.put("Authorization", "Bearer " + jwsToken); AuthCredentials credentials = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); @@ -140,7 +144,6 @@ public void testBearerWrongPosition() throws Exception { Assert.assertNull(credentials); } - @Test public void testBasicAuthHeader() throws Exception { Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).build(); @@ -157,8 +160,9 @@ public void testBasicAuthHeader() throws Exception { public void testRoles() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), + Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2") + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -169,8 +173,9 @@ public void testRoles() throws Exception { public void testNullClaim() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", null)); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), + Jwts.builder().setSubject("Leonard McCoy").claim("roles", null) + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -181,21 +186,23 @@ public void testNullClaim() throws Exception { public void testNonStringClaim() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", 123L)); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), + Jwts.builder().setSubject("Leonard McCoy").claim("roles", 123L) + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); Assert.assertEquals(1, credentials.getBackendRoles().size()); - Assert.assertTrue( credentials.getBackendRoles().contains("123")); + Assert.assertTrue(credentials.getBackendRoles().contains("123")); } @Test public void testRolesMissing() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - Jwts.builder().setSubject("Leonard McCoy")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), + Jwts.builder().setSubject("Leonard McCoy") + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -206,8 +213,9 @@ public void testRolesMissing() throws Exception { public void testWrongSubjectKey() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "missing"), - Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "missing"), + Jwts.builder().claim("roles", "role1,role2").claim("asub", "Dr. Who") + ); Assert.assertNull(credentials); } @@ -216,8 +224,9 @@ public void testWrongSubjectKey() throws Exception { public void testAlternativeSubject() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", "Dr. Who")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), + Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", "Dr. Who") + ); Assert.assertNotNull(credentials); Assert.assertEquals("Dr. Who", credentials.getUsername()); @@ -228,8 +237,9 @@ public void testAlternativeSubject() throws Exception { public void testNonStringAlternativeSubject() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), - Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", false)); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("subject_key", "asub"), + Jwts.builder().setSubject("Leonard McCoy").claim("roles", "role1,role2").claim("asub", false) + ); Assert.assertNotNull(credentials); Assert.assertEquals("false", credentials.getUsername()); @@ -239,7 +249,10 @@ public void testNonStringAlternativeSubject() throws Exception { @Test public void testUrlParam() throws Exception { - Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("jwt_url_parameter", "abc").build(); + Settings settings = Settings.builder() + .put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)) + .put("jwt_url_parameter", "abc") + .build(); String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(secretKey, SignatureAlgorithm.HS512).compact(); @@ -259,8 +272,9 @@ public void testUrlParam() throws Exception { public void testExp() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), - Jwts.builder().setSubject("Expired").setExpiration(new Date(100))); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), + Jwts.builder().setSubject("Expired").setExpiration(new Date(100)) + ); Assert.assertNull(credentials); } @@ -269,9 +283,10 @@ public void testExp() throws Exception { public void testNbf() throws Exception { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), - Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis()+(1000*36000)))); - + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)), + Jwts.builder().setSubject("Expired").setNotBefore(new Date(System.currentTimeMillis() + (1000 * 36000))) + ); + Assert.assertNull(credentials); } @@ -285,11 +300,16 @@ public void testRS256() throws Exception { PublicKey pub = pair.getPublic(); String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.RS256).compact(); - Settings settings = Settings.builder().put("signing_key", "-----BEGIN PUBLIC KEY-----\n"+BaseEncoding.base64().encode(pub.getEncoded())+"-----END PUBLIC KEY-----").build(); + Settings settings = Settings.builder() + .put( + "signing_key", + "-----BEGIN PUBLIC KEY-----\n" + BaseEncoding.base64().encode(pub.getEncoded()) + "-----END PUBLIC KEY-----" + ) + .build(); HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); Map headers = new HashMap(); - headers.put("Authorization", "Bearer "+jwsToken); + headers.put("Authorization", "Bearer " + jwsToken); AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap()), null); @@ -306,10 +326,10 @@ public void testES512() throws Exception { KeyPair pair = keyGen.generateKeyPair(); PrivateKey priv = pair.getPrivate(); PublicKey pub = pair.getPublic(); - + Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(pub.getEncoded())).build(); String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.ES512).compact(); - + HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); Map headers = new HashMap(); headers.put("Authorization", jwsToken); @@ -324,16 +344,13 @@ public void testES512() throws Exception { @Test public void testRolesArray() throws Exception { - JwtBuilder builder = Jwts.builder() - .setPayload("{"+ - "\"sub\": \"John Doe\","+ - "\"roles\": [\"a\",\"b\",\"3rd\"]"+ - "}"); + JwtBuilder builder = Jwts.builder().setPayload("{" + "\"sub\": \"John Doe\"," + "\"roles\": [\"a\",\"b\",\"3rd\"]" + "}"); final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), - builder); - + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("roles_key", "roles"), + builder + ); + Assert.assertNotNull(credentials); Assert.assertEquals("John Doe", credentials.getUsername()); Assert.assertEquals(3, credentials.getBackendRoles().size()); @@ -346,9 +363,10 @@ public void testRolesArray() throws Exception { public void testRequiredAudienceWithCorrectAudience() { final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), - Jwts.builder().setSubject("Leonard McCoy").setAudience("test_audience")); - + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), + Jwts.builder().setSubject("Leonard McCoy").setAudience("test_audience") + ); + Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); } @@ -356,19 +374,21 @@ public void testRequiredAudienceWithCorrectAudience() { @Test public void testRequiredAudienceWithIncorrectAudience() { - final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), - Jwts.builder().setSubject("Leonard McCoy").setAudience("wrong_audience")); - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_audience", "test_audience"), + Jwts.builder().setSubject("Leonard McCoy").setAudience("wrong_audience") + ); + Assert.assertNull(credentials); } @Test public void testRequiredIssuerWithCorrectAudience() { - + final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), - Jwts.builder().setSubject("Leonard McCoy").setIssuer("test_issuer")); + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), + Jwts.builder().setSubject("Leonard McCoy").setIssuer("test_issuer") + ); Assert.assertNotNull(credentials); Assert.assertEquals("Leonard McCoy", credentials.getUsername()); @@ -376,18 +396,17 @@ public void testRequiredIssuerWithCorrectAudience() { @Test public void testRequiredIssuerWithIncorrectAudience() { - - final AuthCredentials credentials = extractCredentialsFromJwtHeader( - Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), - Jwts.builder().setSubject("Leonard McCoy").setIssuer("wrong_issuer")); - + + final AuthCredentials credentials = extractCredentialsFromJwtHeader( + Settings.builder().put("signing_key", BaseEncoding.base64().encode(secretKeyBytes)).put("required_issuer", "test_issuer"), + Jwts.builder().setSubject("Leonard McCoy").setIssuer("wrong_issuer") + ); + Assert.assertNull(credentials); } /** extracts a default user credential from a request header */ - private AuthCredentials extractCredentialsFromJwtHeader( - final Settings.Builder settingsBuilder, - final JwtBuilder jwtBuilder) { + private AuthCredentials extractCredentialsFromJwtHeader(final Settings.Builder settingsBuilder, final JwtBuilder jwtBuilder) { final Settings settings = settingsBuilder.build(); final String jwsToken = jwtBuilder.signWith(secretKey, SignatureAlgorithm.HS512).compact(); final HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null); diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/CxfTestTools.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/CxfTestTools.java index e9920995ac..b2958193c2 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/CxfTestTools.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/CxfTestTools.java @@ -16,7 +16,7 @@ class CxfTestTools { - static String toJson(JsonMapObject jsonMapObject) { - return new JsonMapObjectReaderWriter().toJson(jsonMapObject); - } + static String toJson(JsonMapObject jsonMapObject) { + return new JsonMapObjectReaderWriter().toJson(jsonMapObject); + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java index 3bcaba970f..578fef7202 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/HTTPJwtKeyByOpenIdConnectAuthenticatorTest.java @@ -25,340 +25,369 @@ public class HTTPJwtKeyByOpenIdConnectAuthenticatorTest { - protected static MockIpdServer mockIdpServer; - - @BeforeClass - public static void setUp() throws Exception { - mockIdpServer = new MockIpdServer(TestJwk.Jwks.ALL); - } - - @AfterClass - public static void tearDown() { - if (mockIdpServer != null) { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Test - public void basicTest() { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap()), null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } - - - @Test - public void jwksUriTest() { - Settings settings = Settings.builder() - .put("jwks_uri", mockIdpServer.getJwksUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } - - @Test - public void jwksMissingRequiredIssuerInClaimTest() { - Settings settings = Settings.builder() - .put("jwks_uri", mockIdpServer.getJwksUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_ISSUER_OCT_1), new HashMap<>()), null); - - Assert.assertNull(creds); - } - - @Test - public void jwksNotMatchingRequiredIssuerInClaimTest() { - Settings settings = Settings.builder() - .put("jwks_uri", mockIdpServer.getJwksUri()) - .put("required_issuer", "Wrong Issuer") - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); - - Assert.assertNull(creds); - } - - @Test - public void jwksMissingRequiredAudienceInClaimTest() { - Settings settings = Settings.builder() - .put("jwks_uri", mockIdpServer.getJwksUri()) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_AUDIENCE_OCT_1), new HashMap<>()), null); - - Assert.assertNull(creds); - } - - @Test - public void jwksNotMatchingRequiredAudienceInClaimTest() { - Settings settings = Settings.builder() - .put("jwks_uri", mockIdpServer.getJwksUri()) - .put("required_audience", "Wrong Audience") - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), null); - - Assert.assertNull(creds); - } - - @Test - public void jwksUriMissingTest() { - var exception = Assert.assertThrows(Exception.class, () -> { - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(Settings.builder().build(), null); - jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()), - null); - }); - - Assert.assertEquals("Authentication backend failed", exception.getMessage()); - Assert.assertEquals(OpenSearchSecurityException.class, exception.getClass()); - } - - @Test - public void testEscapeKid() { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_SIGNED_OCT_1_INVALID_KID), new HashMap()), null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } - - @Test - public void bearerTest() { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_SIGNED_OCT_1), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } - - @Test - public void testRoles() throws Exception { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("roles_key", TestJwts.ROLES_CLAIM) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap()), null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_ROLES, creds.getBackendRoles()); - } - - @Test - public void testExp() throws Exception { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_EXPIRED_SIGNED_OCT_1), - new HashMap()), - null); - - Assert.assertNull(creds); - } - - @Test - public void testExpInSkew() throws Exception { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("jwt_clock_skew_tolerance_seconds", "10") - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - long expiringDate = System.currentTimeMillis()/1000-5; - long notBeforeDate = System.currentTimeMillis()/1000-25; - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest( - ImmutableMap.of( - "Authorization", - "Bearer "+TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), - new HashMap()), - null); - - Assert.assertNotNull(creds); - } - - @Test - public void testNbf() throws Exception { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("jwt_clock_skew_tolerance_seconds", "0") - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - long expiringDate = 20+System.currentTimeMillis()/1000; - long notBeforeDate = 5+System.currentTimeMillis()/1000; - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest( - ImmutableMap.of( - "Authorization", - "Bearer "+TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), - new HashMap()), - null); - - Assert.assertNull(creds); - } - - @Test - public void testNbfInSkew() throws Exception { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("jwt_clock_skew_tolerance_seconds", "10") - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - long expiringDate = 20+System.currentTimeMillis()/1000; - long notBeforeDate = 5+System.currentTimeMillis()/1000;; - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest( - ImmutableMap.of("Authorization", "Bearer "+TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), - new HashMap()), - null); - - Assert.assertNotNull(creds); - } - - - @Test - public void testRS256() throws Exception { - - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), new HashMap()), null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } - - @Test - public void testBadSignature() throws Exception { - - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials(new FakeRestRequest( - ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_X), new HashMap()), null); - - Assert.assertNull(creds); - } - - @Test - public void testPeculiarJsonEscaping() { - Settings settings = Settings.builder() - .put("openid_connect_url", mockIdpServer.getDiscoverUri()) - .put("required_issuer", TestJwts.TEST_ISSUER) - .put("required_audience", TestJwts.TEST_AUDIENCE) - .build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.PeculiarEscaping.MC_COY_SIGNED_RSA_1), new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } + protected static MockIpdServer mockIdpServer; + + @BeforeClass + public static void setUp() throws Exception { + mockIdpServer = new MockIpdServer(TestJwk.Jwks.ALL); + } + + @AfterClass + public static void tearDown() { + if (mockIdpServer != null) { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Test + public void basicTest() { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void jwksUriTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void jwksMissingRequiredIssuerInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_ISSUER_OCT_1), new HashMap<>()), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void jwksNotMatchingRequiredIssuerInClaimTest() { + Settings settings = Settings.builder().put("jwks_uri", mockIdpServer.getJwksUri()).put("required_issuer", "Wrong Issuer").build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void jwksMissingRequiredAudienceInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_NO_AUDIENCE_OCT_1), new HashMap<>()), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void jwksNotMatchingRequiredAudienceInClaimTest() { + Settings settings = Settings.builder() + .put("jwks_uri", mockIdpServer.getJwksUri()) + .put("required_audience", "Wrong Audience") + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_2), new HashMap<>()), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void jwksUriMissingTest() { + var exception = Assert.assertThrows(Exception.class, () -> { + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(Settings.builder().build(), null); + jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()), + null + ); + }); + + Assert.assertEquals("Authentication backend failed", exception.getMessage()); + Assert.assertEquals(OpenSearchSecurityException.class, exception.getClass()); + } + + @Test + public void testEscapeKid() { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_SIGNED_OCT_1_INVALID_KID), + new HashMap() + ), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void bearerTest() { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_SIGNED_OCT_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void testRoles() throws Exception { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("roles_key", TestJwts.ROLES_CLAIM) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_ROLES, creds.getBackendRoles()); + } + + @Test + public void testExp() throws Exception { + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", "Bearer " + TestJwts.MC_COY_EXPIRED_SIGNED_OCT_1), + new HashMap() + ), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void testExpInSkew() throws Exception { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("jwt_clock_skew_tolerance_seconds", "10") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + long expiringDate = System.currentTimeMillis() / 1000 - 5; + long notBeforeDate = System.currentTimeMillis() / 1000 - 25; + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", "Bearer " + TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), + new HashMap() + ), + null + ); + + Assert.assertNotNull(creds); + } + + @Test + public void testNbf() throws Exception { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("jwt_clock_skew_tolerance_seconds", "0") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + long expiringDate = 20 + System.currentTimeMillis() / 1000; + long notBeforeDate = 5 + System.currentTimeMillis() / 1000; + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", "Bearer " + TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), + new HashMap() + ), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void testNbfInSkew() throws Exception { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("jwt_clock_skew_tolerance_seconds", "10") + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + long expiringDate = 20 + System.currentTimeMillis() / 1000; + long notBeforeDate = 5 + System.currentTimeMillis() / 1000; + ; + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", "Bearer " + TestJwts.createMcCoySignedOct1(notBeforeDate, expiringDate)), + new HashMap() + ), + null + ); + + Assert.assertNotNull(creds); + } + + @Test + public void testRS256() throws Exception { + + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } + + @Test + public void testBadSignature() throws Exception { + + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_X), new HashMap()), + null + ); + + Assert.assertNull(creds); + } + + @Test + public void testPeculiarJsonEscaping() { + Settings settings = Settings.builder() + .put("openid_connect_url", mockIdpServer.getDiscoverUri()) + .put("required_issuer", TestJwts.TEST_ISSUER) + .put("required_audience", TestJwts.TEST_AUDIENCE) + .build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest( + ImmutableMap.of("Authorization", TestJwts.PeculiarEscaping.MC_COY_SIGNED_RSA_1), + new HashMap() + ), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetrieverTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetrieverTest.java index b30a6326b6..07c0250504 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetrieverTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/KeySetRetrieverTest.java @@ -78,12 +78,10 @@ public void cacheTest() { @Test public void clientCertTest() throws Exception { - try (MockIpdServer sslMockIdpServer = new MockIpdServer(TestJwk.Jwks.ALL, SocketUtils.findAvailableTcpPort(), - true) { + try (MockIpdServer sslMockIdpServer = new MockIpdServer(TestJwk.Jwks.ALL, SocketUtils.findAvailableTcpPort(), true) { @Override - protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) - throws IOException, HttpException { - + protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) throws IOException, + HttpException { SSLSession sslSession = ((HttpCoreContext) context).getSSLSession(); @@ -92,8 +90,7 @@ protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse re try { String sha256Fingerprint = Hashing.sha256().hashBytes(peerCert.getEncoded()).toString(); - Assert.assertEquals("04b2b8baea7a0a893f0223d95b72081e9a1e154a0f9b1b4e75998085972b1b68", - sha256Fingerprint); + Assert.assertEquals("04b2b8baea7a0a893f0223d95b72081e9a1e154a0f9b1b4e75998085972b1b68", sha256Fingerprint); } catch (CertificateEncodingException e) { throw new RuntimeException(e); @@ -105,13 +102,11 @@ protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse re SSLContextBuilder sslContextBuilder = SSLContexts.custom(); KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); trustStore.load(trustStream, "changeit".toCharArray()); KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/spock-keystore.jks").toFile()); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/spock-keystore.jks").toFile()); keyStore.load(keyStream, "changeit".toCharArray()); @@ -126,8 +121,19 @@ public String chooseAlias(Map aliases, SSLParameters }); SettingsBasedSSLConfigurator.SSLConfig sslConfig = new SettingsBasedSSLConfigurator.SSLConfig( - sslContextBuilder.build(), new String[] { "TLSv1.2", "TLSv1.1" }, null, null, false, false, false, - trustStore, null, keyStore, null, null); + sslContextBuilder.build(), + new String[] { "TLSv1.2", "TLSv1.1" }, + null, + null, + false, + false, + false, + trustStore, + null, + keyStore, + null, + null + ); KeySetRetriever keySetRetriever = new KeySetRetriever(sslMockIdpServer.getDiscoverUri(), sslConfig, false); diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java index 35e51919cb..68f852da5c 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/MockIpdServer.java @@ -45,127 +45,131 @@ import static com.amazon.dlic.auth.http.jwt.keybyoidc.CxfTestTools.toJson; class MockIpdServer implements Closeable { - final static String CTX_DISCOVER = "/discover"; - final static String CTX_KEYS = "/api/oauth/keys"; - - private final HttpServer httpServer; - private final int port; - private final String uri; - private final boolean ssl; - private final JsonWebKeys jwks; - - MockIpdServer(JsonWebKeys jwks) throws IOException { - this(jwks, SocketUtils.findAvailableTcpPort(), false); - } - - MockIpdServer(JsonWebKeys jwks, int port, boolean ssl) throws IOException { - this.port = port; - this.uri = (ssl ? "https" : "http") + "://localhost:" + port; - this.ssl = ssl; - this.jwks = jwks; - - ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap().setListenerPort(port) - .register(CTX_DISCOVER, new HttpRequestHandler() { - - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { - handleDiscoverRequest(request, response, context); - } - }).register(CTX_KEYS, new HttpRequestHandler() { - - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { - handleKeysRequest(request, response, context); - } - }); - - if (ssl) { - serverBootstrap = serverBootstrap.setSslContext(createSSLContext()) - .setSslSetupHandler(new Callback() { - @Override - public void execute(SSLParameters object) { - object.setNeedClientAuth(true); - } - }).setConnectionFactory(new HttpConnectionFactory() { - @Override - public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { - final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(ssl ? "https" : "http", Http1Config.DEFAULT); - conn.bind(socket); - return conn; - } - }); - } - - this.httpServer = serverBootstrap.create(); - - httpServer.start(); - } - - @Override - public void close() throws IOException { - httpServer.stop(); - } - - public HttpServer getHttpServer() { - return httpServer; - } - - public String getUri() { - return uri; - } - - public String getDiscoverUri() { - return uri + CTX_DISCOVER; - } - - public String getJwksUri() { - return uri + CTX_KEYS; - } - - public int getPort() { - return port; - } - - protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) - throws HttpException, IOException { - response.setCode(200); - response.setHeader("Cache-Control", "public, max-age=31536000"); - response.setEntity(new StringEntity("{\"jwks_uri\": \"" + uri + CTX_KEYS + "\",\n" + "\"issuer\": \"" + uri - + "\", \"unknownPropertyToBeIgnored\": 42}")); - } - - protected void handleKeysRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) - throws HttpException, IOException { - response.setCode(200); - response.setEntity(new StringEntity(toJson(jwks))); - } - - private SSLContext createSSLContext() { - if (!this.ssl) { - return null; - } - - try { - final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - final KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); - trustStore.load(trustStream, "changeit".toCharArray()); - tmf.init(trustStore); - - final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - final KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/node-0-keystore.jks").toFile()); - - keyStore.load(keyStream, "changeit".toCharArray()); - kmf.init(keyStore, "changeit".toCharArray()); - - SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - return sslContext; - } catch (GeneralSecurityException | IOException e) { - throw new RuntimeException(e); - } - } + final static String CTX_DISCOVER = "/discover"; + final static String CTX_KEYS = "/api/oauth/keys"; + + private final HttpServer httpServer; + private final int port; + private final String uri; + private final boolean ssl; + private final JsonWebKeys jwks; + + MockIpdServer(JsonWebKeys jwks) throws IOException { + this(jwks, SocketUtils.findAvailableTcpPort(), false); + } + + MockIpdServer(JsonWebKeys jwks, int port, boolean ssl) throws IOException { + this.port = port; + this.uri = (ssl ? "https" : "http") + "://localhost:" + port; + this.ssl = ssl; + this.jwks = jwks; + + ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap() + .setListenerPort(port) + .register(CTX_DISCOVER, new HttpRequestHandler() { + + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + handleDiscoverRequest(request, response, context); + } + }) + .register(CTX_KEYS, new HttpRequestHandler() { + + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + handleKeysRequest(request, response, context); + } + }); + + if (ssl) { + serverBootstrap = serverBootstrap.setSslContext(createSSLContext()).setSslSetupHandler(new Callback() { + @Override + public void execute(SSLParameters object) { + object.setNeedClientAuth(true); + } + }).setConnectionFactory(new HttpConnectionFactory() { + @Override + public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { + final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(ssl ? "https" : "http", Http1Config.DEFAULT); + conn.bind(socket); + return conn; + } + }); + } + + this.httpServer = serverBootstrap.create(); + + httpServer.start(); + } + + @Override + public void close() throws IOException { + httpServer.stop(); + } + + public HttpServer getHttpServer() { + return httpServer; + } + + public String getUri() { + return uri; + } + + public String getDiscoverUri() { + return uri + CTX_DISCOVER; + } + + public String getJwksUri() { + return uri + CTX_KEYS; + } + + public int getPort() { + return port; + } + + protected void handleDiscoverRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + response.setCode(200); + response.setHeader("Cache-Control", "public, max-age=31536000"); + response.setEntity( + new StringEntity( + "{\"jwks_uri\": \"" + uri + CTX_KEYS + "\",\n" + "\"issuer\": \"" + uri + "\", \"unknownPropertyToBeIgnored\": 42}" + ) + ); + } + + protected void handleKeysRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + response.setCode(200); + response.setEntity(new StringEntity(toJson(jwks))); + } + + private SSLContext createSSLContext() { + if (!this.ssl) { + return null; + } + + try { + final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + final KeyStore trustStore = KeyStore.getInstance("JKS"); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); + trustStore.load(trustStream, "changeit".toCharArray()); + tmf.init(trustStore); + + final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + final KeyStore keyStore = KeyStore.getInstance("JKS"); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/node-0-keystore.jks").toFile()); + + keyStore.load(keyStream, "changeit".toCharArray()); + kmf.init(keyStore, "changeit".toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return sslContext; + } catch (GeneralSecurityException | IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySetTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySetTest.java index 50bd2fcc0e..6bbce7d85d 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySetTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SelfRefreshingKeySetTest.java @@ -22,100 +22,97 @@ public class SelfRefreshingKeySetTest { - @Test - public void basicTest() throws AuthenticatorUnavailableException, BadCredentialsException { - SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(new MockKeySetProvider()); + @Test + public void basicTest() throws AuthenticatorUnavailableException, BadCredentialsException { + SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(new MockKeySetProvider()); - JsonWebKey key1 = selfRefreshingKeySet.getKey("kid/a"); - Assert.assertEquals(TestJwk.OCT_1_K, key1.getProperty("k")); - Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); + JsonWebKey key1 = selfRefreshingKeySet.getKey("kid/a"); + Assert.assertEquals(TestJwk.OCT_1_K, key1.getProperty("k")); + Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); - JsonWebKey key2 = selfRefreshingKeySet.getKey("kid/b"); - Assert.assertEquals(TestJwk.OCT_2_K, key2.getProperty("k")); - Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); + JsonWebKey key2 = selfRefreshingKeySet.getKey("kid/b"); + Assert.assertEquals(TestJwk.OCT_2_K, key2.getProperty("k")); + Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); - try { - selfRefreshingKeySet.getKey("kid/X"); - Assert.fail("Expected a BadCredentialsException"); - } catch (BadCredentialsException e) { - Assert.assertEquals(2, selfRefreshingKeySet.getRefreshCount()); - } + try { + selfRefreshingKeySet.getKey("kid/X"); + Assert.fail("Expected a BadCredentialsException"); + } catch (BadCredentialsException e) { + Assert.assertEquals(2, selfRefreshingKeySet.getRefreshCount()); + } - } + } + @Test(timeout = 10000) + public void twoThreadedTest() throws Exception { + BlockingMockKeySetProvider provider = new BlockingMockKeySetProvider(); + final SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(provider); - @Test(timeout = 10000) - public void twoThreadedTest() throws Exception { - BlockingMockKeySetProvider provider = new BlockingMockKeySetProvider(); + ExecutorService executorService = Executors.newCachedThreadPool(); - final SelfRefreshingKeySet selfRefreshingKeySet = new SelfRefreshingKeySet(provider); + Future f1 = executorService.submit(() -> selfRefreshingKeySet.getKey("kid/a")); - ExecutorService executorService = Executors.newCachedThreadPool(); + provider.waitForCalled(); - Future f1 = executorService.submit(() -> selfRefreshingKeySet.getKey("kid/a")); + Future f2 = executorService.submit(() -> selfRefreshingKeySet.getKey("kid/b")); - provider.waitForCalled(); + while (selfRefreshingKeySet.getQueuedGetCount() == 0) { + Thread.sleep(10); + } - Future f2 = executorService.submit(() -> selfRefreshingKeySet.getKey("kid/b")); + provider.unblock(); - while (selfRefreshingKeySet.getQueuedGetCount() == 0) { - Thread.sleep(10); - } + Assert.assertEquals(TestJwk.OCT_1_K, f1.get().getProperty("k")); + Assert.assertEquals(TestJwk.OCT_2_K, f2.get().getProperty("k")); - provider.unblock(); + Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); + Assert.assertEquals(1, selfRefreshingKeySet.getQueuedGetCount()); - Assert.assertEquals(TestJwk.OCT_1_K, f1.get().getProperty("k")); - Assert.assertEquals(TestJwk.OCT_2_K, f2.get().getProperty("k")); + } - Assert.assertEquals(1, selfRefreshingKeySet.getRefreshCount()); - Assert.assertEquals(1, selfRefreshingKeySet.getQueuedGetCount()); + static class MockKeySetProvider implements KeySetProvider { - } + @Override + public JsonWebKeys get() throws AuthenticatorUnavailableException { + return TestJwk.OCT_1_2_3; + } - static class MockKeySetProvider implements KeySetProvider { + } - @Override - public JsonWebKeys get() throws AuthenticatorUnavailableException { - return TestJwk.OCT_1_2_3; - } + static class BlockingMockKeySetProvider extends MockKeySetProvider { + private boolean blocked = true; + private boolean called = false; - } + @Override + public synchronized JsonWebKeys get() throws AuthenticatorUnavailableException { - static class BlockingMockKeySetProvider extends MockKeySetProvider { - private boolean blocked = true; - private boolean called = false; + called = true; + notifyAll(); - @Override - public synchronized JsonWebKeys get() throws AuthenticatorUnavailableException { + waitForUnblock(); - called = true; - notifyAll(); + return super.get(); + } - waitForUnblock(); + public synchronized void unblock() { + blocked = false; + notifyAll(); + } - return super.get(); - } + public synchronized void waitForCalled() throws InterruptedException { + while (!called) { + wait(); + } + } - public synchronized void unblock() { - blocked = false; - notifyAll(); - } + private synchronized void waitForUnblock() { + while (blocked) { + try { + wait(); + } catch (InterruptedException e) {} - public synchronized void waitForCalled() throws InterruptedException { - while (!called) { - wait(); - } - } - - private synchronized void waitForUnblock() { - while (blocked) { - try { - wait(); - } catch (InterruptedException e) { - } - - } - } - } + } + } + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java index 4285ee07ae..21f0c362d9 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest.java @@ -23,186 +23,185 @@ public class SingleKeyHTTPJwtKeyByOpenIdConnectAuthenticatorTest { - @Test - public void basicTest() throws Exception { - MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); - try { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Test - public void wrongSigTest() throws Exception { - MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); - try { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_X), - new HashMap()), - null); - - Assert.assertNull(creds); - - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Test - public void noAlgTest() throws Exception { - MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1_NO_ALG); - try { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - @Test - public void mismatchedAlgTest() throws Exception { - MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1_WRONG_ALG); - try { - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), - new HashMap()), - null); - - Assert.assertNull(creds); - - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - - @Test - public void keyExchangeTest() throws Exception { - MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); - - Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); - - HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - try { - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - - creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_2), - new HashMap()), - null); - - Assert.assertNull(creds); - - creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_X), - new HashMap()), - null); - - Assert.assertNull(creds); - - creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_2); - settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); //port changed - jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); - - try { - AuthCredentials creds = jwtAuth.extractCredentials( - new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_2), - new HashMap()), - null); - - Assert.assertNotNull(creds); - Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); - Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); - Assert.assertEquals(0, creds.getBackendRoles().size()); - Assert.assertEquals(4, creds.getAttributes().size()); - - } finally { - try { - mockIdpServer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } + @Test + public void basicTest() throws Exception { + MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); + try { + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Test + public void wrongSigTest() throws Exception { + MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); + try { + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_X), new HashMap()), + null + ); + + Assert.assertNull(creds); + + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Test + public void noAlgTest() throws Exception { + MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1_NO_ALG); + try { + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Test + public void mismatchedAlgTest() throws Exception { + MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1_WRONG_ALG); + try { + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNull(creds); + + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @Test + public void keyExchangeTest() throws Exception { + MockIpdServer mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_1); + + Settings settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); + + HTTPJwtKeyByOpenIdConnectAuthenticator jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + try { + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + + creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_2), new HashMap()), + null + ); + + Assert.assertNull(creds); + + creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_X), new HashMap()), + null + ); + + Assert.assertNull(creds); + + creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_1), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + mockIdpServer = new MockIpdServer(TestJwk.Jwks.RSA_2); + settings = Settings.builder().put("openid_connect_url", mockIdpServer.getDiscoverUri()).build(); // port changed + jwtAuth = new HTTPJwtKeyByOpenIdConnectAuthenticator(settings, null); + + try { + AuthCredentials creds = jwtAuth.extractCredentials( + new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.NoKid.MC_COY_SIGNED_RSA_2), new HashMap()), + null + ); + + Assert.assertNotNull(creds); + Assert.assertEquals(TestJwts.MCCOY_SUBJECT, creds.getUsername()); + Assert.assertEquals(TestJwts.TEST_AUDIENCE, creds.getAttributes().get("attr.jwt.aud")); + Assert.assertEquals(0, creds.getBackendRoles().size()); + Assert.assertEquals(4, creds.getAttributes().size()); + + } finally { + try { + mockIdpServer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwk.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwk.java index b0f996a03f..5b0d5738a3 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwk.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwk.java @@ -20,94 +20,102 @@ class TestJwk { - // Keys generated with https://mkjwk.org/ - - static final String OCT_1_K = "eTDZjSqRD9Abhod9iqeGX_7o93a-eElTeXWAF6FmzQshmRIrPD-C9ET3pFjJ_IBrzmWIZDk8ig-X_PIyGmKsxNMsrU-0BNWF5gJq5xOp4rYTl8z66Tw9wr8tHLxLxgJqkLSuUCRBZvlZlQ7jNdhBBxgM-hdSSzsN1T33qdIwhrUeJ-KXI5yKUXHjoWFYb9tETbYQ4NvONowkCsXK_flp-E3F_OcKe_z5iVUszAV8QfCod1zhbya540kDejXCL6N_XMmhWJqum7UJ3hgf6DEtroPSnVpHt4iR5w9ArKK-IBgluPght03gNcoNqwz7p77TFbdOmUKF_PWy1bcdbaUoSg"; - static final String OCT_2_K = "YP6Q3IF2qJEagV948dsicXKpG43Ci2W7ZxUpiVTBLZr1vFN9ZGUKxeXGgVWuMFYTmoHvv5AOC8BvoNOpcE3rcJNuNOqTMdujxD92CxjOykiLEKQ0Te_7xQ4LnSQjlqdIJ4U3S7qCnJLd1LxhKOGZcUhE_pjhwf7q2RUUpvC3UOyZZLog9yeflnp9nqqDy5yVqRYWZRcPI06kJTh3Z8IFi2JRJV14iUFQtOHQKuyJRMcsldKnfWl7YW3JdQ9IRN-c1lEYSEBmsavEejcqHZkbli2svqLfmCBJVWffXDRxhq0_VafiL83HC0bP9qeNKivhemw6foVmg8UMs7yJ6ao02A"; - static final String OCT_3_K = "r3aeW3OK7-B4Hs3hq9BmlT1D3jRiolH9PL82XUz9xAS7dniAdmvMnN5GkOc1vqibOe2T-CC_103UglDm9D0iU9S9zn6wTuQt1L5wfZIoHd9f5IjJ_YFEzZMvsoUY_-ji_0K_ugVvBPwi9JnBQHHS4zrgmP06dGjmcnZDcIf4W_iFas3lDYSXilL1V2QhNaynpSqTarpfBGSphKv4Zg2JhsX8xB0VSaTlEq4lF8pzvpWSxXCW9CtomhB80daSuTizrmSTEPpdN3XzQ2-Tovo1ieMOfDU4csvjEk7Bwc2ThjpnA8ucKQUYpUv9joBxKuCdUltssthWnetrogjYOn_xGA"; - - static final JsonWebKey OCT_1 = createOct("kid/a", "HS256", OCT_1_K); - static final JsonWebKey OCT_2 = createOct("kid/b", "HS256", OCT_2_K); - static final JsonWebKey OCT_3 = createOct("kid/c", "HS256", OCT_3_K); - static final JsonWebKey ESCAPED_SLASH_KID_OCT_1 = createOct("kid\\/_a", "HS256", OCT_1_K); - static final JsonWebKey FORWARD_SLASH_KID_OCT_1 = createOct("kid/_a", "HS256", OCT_1_K); - - static final JsonWebKeys OCT_1_2_3 = createJwks(OCT_1, OCT_2, OCT_3, FORWARD_SLASH_KID_OCT_1,ESCAPED_SLASH_KID_OCT_1); - - static final String RSA_1_D = "On8XGMmdM5Fm5hvuhQk-qAkIP2CoK5QMx0OH5m_WDzKXZv8lZ2eg89I4ehBiOKGdw1h_mjmWwTah-evpXV-BF5QpejPQqxkXS-8s5r2AvietQq32jl-gwIwZWTvfzjpT9On0YJZ4q01tMDj3r-YOLUW2xrz3za9tl6pPU_5kP63C-hoj1ybTwcC7ujbCPwhY6yAopMA1v10uVmCxsjsNikEjB6YePgHixez51wO3Z8mXNwefWukFWYJ5T7t4kHMSf5P_8FJZ14u5yvYZnngE_tJCyHFdIDb6UWsrgxomtlQU-SdZYK_NY6gw6mCkjjlqOoYqlsrRJ16kJ81Ds269oQ"; - static final String RSA_1_N = "hMSoV74FRtoaU7xpp0llsXbHE4oUseKoSNga-C_YIXuoGc3pajHh1WtJppZQNYM1Xy07nHchLJAdgqL2_q_Lk8cFHmmL1KTjwPflK9zZ9C0-8QTOrrqU9vkp3gT00jWWJ0HJbUvXIGxPGPnxoJoI--ToE0EWsYEWqWyx1TqYol--oUUPlY5r7vXRKIn5UZNz6VGkW8nI4fXaqDUpXH9uVM9A-nJX2B0Xjwu3VOn2zrgkCZeGTHjNgfLISOTFe9m8lHWLKcuxOWPuCZyCN0C6ZdWB1YP2NhxYFQwQfGV8yfnTImgL-DuV4WPSRVj7W_GJr213-oXBrBR0CnQEPbi_3w"; - static final String RSA_1_E = "AQAB"; - - static final String RSA_2_D = "QQ18k_buZHOSVYzkXL1FaqdodZVNZ_hrBtDcmCVUYjm3dfDVQYt70h8LUdLUCSUA2-_VEwqVdQ-L2FTg7NZVvZJXIyQXp3yrdY1vGKebs3oaIB_VQT8jt-64s12r_8V2ksK2myRrvfm2Fgqi32H5QkspuaQYb9s4NJwKSk7mVAz5dRWQdCx9JNVWknWDJxgHzh3Uku1tNwUOyvSYcRnSZ9X7oWNHaHkSGLEYE_mxD7YXs6HEdCDwc3WuvR5AiVKg2OGec0lL1hY_AWX5UxnR00mhAa0qPytFfaPe-Sc5tQ5regQRqRNDyDESVGIvqXsY8ePjZPOFyoxrcJ2wN3bt4Q"; - static final String RSA_2_N = "lt4EID7tbrE9E8l7VfVGhiwSx4O8nLO5AZo5pJNE1fUy4bM56wH_DeU3YspXh0UvH-vcn4uKjhwJdOCjzalBc2wXD0aRd3JXzWwbjveo6oBFz6kU7VnY8nFMYLMlb6FDcl066OZOtW4PIFtAStXj5rX_J94He3sfTClodpNljTi4qeQwoNsrnZ5Eq82pCp20zCgvbdes8HQBq_QgApvzhL3c-PXd2I_4pBnaPoZwAnufthk7-v8V0Zf5CrDuqEczKKr38pvwggnxZqsfUy2X0bXPBvDXh5B2ljWxWl8tHJbKXzOhfV5Nx5rllJnNabFoVxh3hnlxdOZ88zcaslWBLQ"; - static final String RSA_2_E = "AQAB"; - - static final String RSA_X_D = "iXym57VmwbWvcHtf--xSDPTagEJdnceuErjH6lbuabFXeBx42ZpuAICvo6_YpMcqLybD37ArIu2SD5J_ZBALp4v4KecMPFI5lZr7GKlGgqnForvcC7EWA_ZtZ9uY746cKun8NtemcOlAenn2dvc9NP2S4JtE3FHxmqs2MMmz-ki-ar8-zu0j0HLPLl_Wj2SZ9yCeFmmH3eocX5IRRiWwPnudQJM2t0kt9V-M88YzobqzoMEoFjTfi-owa-w6xGAgJxAUKk02vTiTivH3Qmkk-uAXyj-VtcyzYXD74ICN8EplcAEUKegDR59T4-u18GdpDbPU20XzxDaO4lZiQ7TIEQ"; - static final String RSA_X_N = "jDDVUMXOXDVcaRVAT5TtuiAsLxk7XAAwyyECfmySZul7D5XVLMtGe6rP2900q3nM4BaCEiuwXjmTCZDAGlFGs2a3eQ1vbBSv9_0KGHL-gZGFPNiv0v8aR7QzZ-abhGnRy5F52PlTWsypGgG_kQpF2t2TBotvYhvVPagAt4ljllDKvY1siOvS3nh4TqcUtWcbgQZEWPmaXuhx0eLmhQJca7UEw99YlGNew48AEzt7ZnfU0Qkz3JwSz7IcPx-NfIh6BN6LwAg_ASdoM3MR8rDOtLYavmJVhutrfOpE-4-fw1mf3eLYu7xrxIplSiOIsHunTUssnTiBkXAaGqGJs604Pw"; - static final String RSA_X_E = "AQAB"; - - static final JsonWebKey RSA_1 = createRsa("kid/1", "RS256", RSA_1_E, RSA_1_N, RSA_1_D); - static final JsonWebKey RSA_1_PUBLIC = createRsaPublic("kid/1", "RS256", RSA_1_E, RSA_1_N); - static final JsonWebKey RSA_1_PUBLIC_NO_ALG = createRsaPublic("kid/1", null, RSA_1_E, RSA_1_N); + // Keys generated with https://mkjwk.org/ + + static final String OCT_1_K = + "eTDZjSqRD9Abhod9iqeGX_7o93a-eElTeXWAF6FmzQshmRIrPD-C9ET3pFjJ_IBrzmWIZDk8ig-X_PIyGmKsxNMsrU-0BNWF5gJq5xOp4rYTl8z66Tw9wr8tHLxLxgJqkLSuUCRBZvlZlQ7jNdhBBxgM-hdSSzsN1T33qdIwhrUeJ-KXI5yKUXHjoWFYb9tETbYQ4NvONowkCsXK_flp-E3F_OcKe_z5iVUszAV8QfCod1zhbya540kDejXCL6N_XMmhWJqum7UJ3hgf6DEtroPSnVpHt4iR5w9ArKK-IBgluPght03gNcoNqwz7p77TFbdOmUKF_PWy1bcdbaUoSg"; + static final String OCT_2_K = + "YP6Q3IF2qJEagV948dsicXKpG43Ci2W7ZxUpiVTBLZr1vFN9ZGUKxeXGgVWuMFYTmoHvv5AOC8BvoNOpcE3rcJNuNOqTMdujxD92CxjOykiLEKQ0Te_7xQ4LnSQjlqdIJ4U3S7qCnJLd1LxhKOGZcUhE_pjhwf7q2RUUpvC3UOyZZLog9yeflnp9nqqDy5yVqRYWZRcPI06kJTh3Z8IFi2JRJV14iUFQtOHQKuyJRMcsldKnfWl7YW3JdQ9IRN-c1lEYSEBmsavEejcqHZkbli2svqLfmCBJVWffXDRxhq0_VafiL83HC0bP9qeNKivhemw6foVmg8UMs7yJ6ao02A"; + static final String OCT_3_K = + "r3aeW3OK7-B4Hs3hq9BmlT1D3jRiolH9PL82XUz9xAS7dniAdmvMnN5GkOc1vqibOe2T-CC_103UglDm9D0iU9S9zn6wTuQt1L5wfZIoHd9f5IjJ_YFEzZMvsoUY_-ji_0K_ugVvBPwi9JnBQHHS4zrgmP06dGjmcnZDcIf4W_iFas3lDYSXilL1V2QhNaynpSqTarpfBGSphKv4Zg2JhsX8xB0VSaTlEq4lF8pzvpWSxXCW9CtomhB80daSuTizrmSTEPpdN3XzQ2-Tovo1ieMOfDU4csvjEk7Bwc2ThjpnA8ucKQUYpUv9joBxKuCdUltssthWnetrogjYOn_xGA"; + + static final JsonWebKey OCT_1 = createOct("kid/a", "HS256", OCT_1_K); + static final JsonWebKey OCT_2 = createOct("kid/b", "HS256", OCT_2_K); + static final JsonWebKey OCT_3 = createOct("kid/c", "HS256", OCT_3_K); + static final JsonWebKey ESCAPED_SLASH_KID_OCT_1 = createOct("kid\\/_a", "HS256", OCT_1_K); + static final JsonWebKey FORWARD_SLASH_KID_OCT_1 = createOct("kid/_a", "HS256", OCT_1_K); + + static final JsonWebKeys OCT_1_2_3 = createJwks(OCT_1, OCT_2, OCT_3, FORWARD_SLASH_KID_OCT_1, ESCAPED_SLASH_KID_OCT_1); + + static final String RSA_1_D = + "On8XGMmdM5Fm5hvuhQk-qAkIP2CoK5QMx0OH5m_WDzKXZv8lZ2eg89I4ehBiOKGdw1h_mjmWwTah-evpXV-BF5QpejPQqxkXS-8s5r2AvietQq32jl-gwIwZWTvfzjpT9On0YJZ4q01tMDj3r-YOLUW2xrz3za9tl6pPU_5kP63C-hoj1ybTwcC7ujbCPwhY6yAopMA1v10uVmCxsjsNikEjB6YePgHixez51wO3Z8mXNwefWukFWYJ5T7t4kHMSf5P_8FJZ14u5yvYZnngE_tJCyHFdIDb6UWsrgxomtlQU-SdZYK_NY6gw6mCkjjlqOoYqlsrRJ16kJ81Ds269oQ"; + static final String RSA_1_N = + "hMSoV74FRtoaU7xpp0llsXbHE4oUseKoSNga-C_YIXuoGc3pajHh1WtJppZQNYM1Xy07nHchLJAdgqL2_q_Lk8cFHmmL1KTjwPflK9zZ9C0-8QTOrrqU9vkp3gT00jWWJ0HJbUvXIGxPGPnxoJoI--ToE0EWsYEWqWyx1TqYol--oUUPlY5r7vXRKIn5UZNz6VGkW8nI4fXaqDUpXH9uVM9A-nJX2B0Xjwu3VOn2zrgkCZeGTHjNgfLISOTFe9m8lHWLKcuxOWPuCZyCN0C6ZdWB1YP2NhxYFQwQfGV8yfnTImgL-DuV4WPSRVj7W_GJr213-oXBrBR0CnQEPbi_3w"; + static final String RSA_1_E = "AQAB"; + + static final String RSA_2_D = + "QQ18k_buZHOSVYzkXL1FaqdodZVNZ_hrBtDcmCVUYjm3dfDVQYt70h8LUdLUCSUA2-_VEwqVdQ-L2FTg7NZVvZJXIyQXp3yrdY1vGKebs3oaIB_VQT8jt-64s12r_8V2ksK2myRrvfm2Fgqi32H5QkspuaQYb9s4NJwKSk7mVAz5dRWQdCx9JNVWknWDJxgHzh3Uku1tNwUOyvSYcRnSZ9X7oWNHaHkSGLEYE_mxD7YXs6HEdCDwc3WuvR5AiVKg2OGec0lL1hY_AWX5UxnR00mhAa0qPytFfaPe-Sc5tQ5regQRqRNDyDESVGIvqXsY8ePjZPOFyoxrcJ2wN3bt4Q"; + static final String RSA_2_N = + "lt4EID7tbrE9E8l7VfVGhiwSx4O8nLO5AZo5pJNE1fUy4bM56wH_DeU3YspXh0UvH-vcn4uKjhwJdOCjzalBc2wXD0aRd3JXzWwbjveo6oBFz6kU7VnY8nFMYLMlb6FDcl066OZOtW4PIFtAStXj5rX_J94He3sfTClodpNljTi4qeQwoNsrnZ5Eq82pCp20zCgvbdes8HQBq_QgApvzhL3c-PXd2I_4pBnaPoZwAnufthk7-v8V0Zf5CrDuqEczKKr38pvwggnxZqsfUy2X0bXPBvDXh5B2ljWxWl8tHJbKXzOhfV5Nx5rllJnNabFoVxh3hnlxdOZ88zcaslWBLQ"; + static final String RSA_2_E = "AQAB"; + + static final String RSA_X_D = + "iXym57VmwbWvcHtf--xSDPTagEJdnceuErjH6lbuabFXeBx42ZpuAICvo6_YpMcqLybD37ArIu2SD5J_ZBALp4v4KecMPFI5lZr7GKlGgqnForvcC7EWA_ZtZ9uY746cKun8NtemcOlAenn2dvc9NP2S4JtE3FHxmqs2MMmz-ki-ar8-zu0j0HLPLl_Wj2SZ9yCeFmmH3eocX5IRRiWwPnudQJM2t0kt9V-M88YzobqzoMEoFjTfi-owa-w6xGAgJxAUKk02vTiTivH3Qmkk-uAXyj-VtcyzYXD74ICN8EplcAEUKegDR59T4-u18GdpDbPU20XzxDaO4lZiQ7TIEQ"; + static final String RSA_X_N = + "jDDVUMXOXDVcaRVAT5TtuiAsLxk7XAAwyyECfmySZul7D5XVLMtGe6rP2900q3nM4BaCEiuwXjmTCZDAGlFGs2a3eQ1vbBSv9_0KGHL-gZGFPNiv0v8aR7QzZ-abhGnRy5F52PlTWsypGgG_kQpF2t2TBotvYhvVPagAt4ljllDKvY1siOvS3nh4TqcUtWcbgQZEWPmaXuhx0eLmhQJca7UEw99YlGNew48AEzt7ZnfU0Qkz3JwSz7IcPx-NfIh6BN6LwAg_ASdoM3MR8rDOtLYavmJVhutrfOpE-4-fw1mf3eLYu7xrxIplSiOIsHunTUssnTiBkXAaGqGJs604Pw"; + static final String RSA_X_E = "AQAB"; + + static final JsonWebKey RSA_1 = createRsa("kid/1", "RS256", RSA_1_E, RSA_1_N, RSA_1_D); + static final JsonWebKey RSA_1_PUBLIC = createRsaPublic("kid/1", "RS256", RSA_1_E, RSA_1_N); + static final JsonWebKey RSA_1_PUBLIC_NO_ALG = createRsaPublic("kid/1", null, RSA_1_E, RSA_1_N); static final JsonWebKey RSA_1_PUBLIC_WRONG_ALG = createRsaPublic("kid/1", "HS256", RSA_1_E, RSA_1_N); - static final JsonWebKey RSA_2 = createRsa("kid/2", "RS256", RSA_2_E, RSA_2_N, RSA_2_D); - static final JsonWebKey RSA_2_PUBLIC = createRsaPublic("kid/2", "RS256", RSA_2_E, RSA_2_N); - - static final JsonWebKey RSA_X = createRsa("kid/2", "RS256", RSA_X_E, RSA_X_N, RSA_X_D); - static final JsonWebKey RSA_X_PUBLIC = createRsaPublic("kid/2", "RS256", RSA_X_E, RSA_X_N); + static final JsonWebKey RSA_2 = createRsa("kid/2", "RS256", RSA_2_E, RSA_2_N, RSA_2_D); + static final JsonWebKey RSA_2_PUBLIC = createRsaPublic("kid/2", "RS256", RSA_2_E, RSA_2_N); - static final JsonWebKeys RSA_1_2_PUBLIC = createJwks(RSA_1_PUBLIC, RSA_2_PUBLIC); + static final JsonWebKey RSA_X = createRsa("kid/2", "RS256", RSA_X_E, RSA_X_N, RSA_X_D); + static final JsonWebKey RSA_X_PUBLIC = createRsaPublic("kid/2", "RS256", RSA_X_E, RSA_X_N); - static class Jwks { - static final JsonWebKeys ALL = createJwks(OCT_1, OCT_2, OCT_3, FORWARD_SLASH_KID_OCT_1, RSA_1_PUBLIC, RSA_2_PUBLIC); - static final JsonWebKeys RSA_1 = createJwks(RSA_1_PUBLIC); - static final JsonWebKeys RSA_2 = createJwks(RSA_2_PUBLIC); - static final JsonWebKeys RSA_1_NO_ALG = createJwks(RSA_1_PUBLIC_NO_ALG); - static final JsonWebKeys RSA_1_WRONG_ALG = createJwks(RSA_1_PUBLIC_WRONG_ALG); - } + static final JsonWebKeys RSA_1_2_PUBLIC = createJwks(RSA_1_PUBLIC, RSA_2_PUBLIC); + static class Jwks { + static final JsonWebKeys ALL = createJwks(OCT_1, OCT_2, OCT_3, FORWARD_SLASH_KID_OCT_1, RSA_1_PUBLIC, RSA_2_PUBLIC); + static final JsonWebKeys RSA_1 = createJwks(RSA_1_PUBLIC); + static final JsonWebKeys RSA_2 = createJwks(RSA_2_PUBLIC); + static final JsonWebKeys RSA_1_NO_ALG = createJwks(RSA_1_PUBLIC_NO_ALG); + static final JsonWebKeys RSA_1_WRONG_ALG = createJwks(RSA_1_PUBLIC_WRONG_ALG); + } - private static JsonWebKey createOct(String keyId, String algorithm, String k) { - JsonWebKey result = new JsonWebKey(); + private static JsonWebKey createOct(String keyId, String algorithm, String k) { + JsonWebKey result = new JsonWebKey(); - result.setKeyId(keyId); - result.setKeyType(KeyType.OCTET); - result.setAlgorithm(algorithm); - result.setPublicKeyUse(PublicKeyUse.SIGN); - result.setProperty("k", k); + result.setKeyId(keyId); + result.setKeyType(KeyType.OCTET); + result.setAlgorithm(algorithm); + result.setPublicKeyUse(PublicKeyUse.SIGN); + result.setProperty("k", k); - return result; - } + return result; + } - private static JsonWebKey createRsa(String keyId, String algorithm, String e, String n, String d) { - JsonWebKey result = new JsonWebKey(); + private static JsonWebKey createRsa(String keyId, String algorithm, String e, String n, String d) { + JsonWebKey result = new JsonWebKey(); - result.setKeyId(keyId); - result.setKeyType(KeyType.RSA); - result.setAlgorithm(algorithm); - result.setPublicKeyUse(PublicKeyUse.SIGN); + result.setKeyId(keyId); + result.setKeyType(KeyType.RSA); + result.setAlgorithm(algorithm); + result.setPublicKeyUse(PublicKeyUse.SIGN); - if (d != null) { - result.setProperty("d", d); - } + if (d != null) { + result.setProperty("d", d); + } - result.setProperty("e", e); - result.setProperty("n", n); + result.setProperty("e", e); + result.setProperty("n", n); - return result; - } + return result; + } - private static JsonWebKey createRsaPublic(String keyId, String algorithm, String e, String n) { - return createRsa(keyId, algorithm, e, n, null); - } + private static JsonWebKey createRsaPublic(String keyId, String algorithm, String e, String n) { + return createRsa(keyId, algorithm, e, n, null); + } - private static JsonWebKeys createJwks(JsonWebKey... array) { - JsonWebKeys result = new JsonWebKeys(); + private static JsonWebKeys createJwks(JsonWebKey... array) { + JsonWebKeys result = new JsonWebKeys(); - result.setKeys(Arrays.asList(array)); + result.setKeys(Arrays.asList(array)); - return result; - } + return result; + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java index 7d0e91561d..292af6c014 100644 --- a/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java +++ b/src/test/java/com/amazon/dlic/auth/http/jwt/keybyoidc/TestJwts.java @@ -25,113 +25,126 @@ import org.apache.logging.log4j.util.Strings; class TestJwts { - static final String ROLES_CLAIM = "roles"; - static final Set TEST_ROLES = ImmutableSet.of("role1", "role2"); - static final String TEST_ROLES_STRING = Strings.join(TEST_ROLES, ','); + static final String ROLES_CLAIM = "roles"; + static final Set TEST_ROLES = ImmutableSet.of("role1", "role2"); + static final String TEST_ROLES_STRING = Strings.join(TEST_ROLES, ','); - static final String TEST_AUDIENCE = "TestAudience"; + static final String TEST_AUDIENCE = "TestAudience"; - static final String MCCOY_SUBJECT = "Leonard McCoy"; + static final String MCCOY_SUBJECT = "Leonard McCoy"; - static final String TEST_ISSUER = "TestIssuer"; + static final String TEST_ISSUER = "TestIssuer"; - static final JwtToken MC_COY = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + static final JwtToken MC_COY = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); - static final JwtToken MC_COY_2 = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + static final JwtToken MC_COY_2 = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); - static final JwtToken MC_COY_NO_AUDIENCE = create(MCCOY_SUBJECT, null, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); + static final JwtToken MC_COY_NO_AUDIENCE = create(MCCOY_SUBJECT, null, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING); - static final JwtToken MC_COY_NO_ISSUER = create(MCCOY_SUBJECT, TEST_AUDIENCE, null, ROLES_CLAIM, TEST_ROLES_STRING); + static final JwtToken MC_COY_NO_ISSUER = create(MCCOY_SUBJECT, TEST_AUDIENCE, null, ROLES_CLAIM, TEST_ROLES_STRING); - static final JwtToken MC_COY_EXPIRED = create(MCCOY_SUBJECT, TEST_AUDIENCE, TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING, JwtConstants.CLAIM_EXPIRY, 10); + static final JwtToken MC_COY_EXPIRED = create( + MCCOY_SUBJECT, + TEST_AUDIENCE, + TEST_ISSUER, + ROLES_CLAIM, + TEST_ROLES_STRING, + JwtConstants.CLAIM_EXPIRY, + 10 + ); - static final String MC_COY_SIGNED_OCT_1 = createSigned(MC_COY, TestJwk.OCT_1); + static final String MC_COY_SIGNED_OCT_1 = createSigned(MC_COY, TestJwk.OCT_1); - static final String MC_COY_SIGNED_OCT_2 = createSigned(MC_COY_2, TestJwk.OCT_2); + static final String MC_COY_SIGNED_OCT_2 = createSigned(MC_COY_2, TestJwk.OCT_2); - static final String MC_COY_SIGNED_NO_AUDIENCE_OCT_1 = createSigned(MC_COY_NO_AUDIENCE, TestJwk.OCT_1); - static final String MC_COY_SIGNED_NO_ISSUER_OCT_1 = createSigned(MC_COY_NO_ISSUER, TestJwk.OCT_1); + static final String MC_COY_SIGNED_NO_AUDIENCE_OCT_1 = createSigned(MC_COY_NO_AUDIENCE, TestJwk.OCT_1); + static final String MC_COY_SIGNED_NO_ISSUER_OCT_1 = createSigned(MC_COY_NO_ISSUER, TestJwk.OCT_1); - static final String MC_COY_SIGNED_OCT_1_INVALID_KID = createSigned(MC_COY, TestJwk.FORWARD_SLASH_KID_OCT_1); + static final String MC_COY_SIGNED_OCT_1_INVALID_KID = createSigned(MC_COY, TestJwk.FORWARD_SLASH_KID_OCT_1); - static final String MC_COY_SIGNED_RSA_1 = createSigned(MC_COY, TestJwk.RSA_1); + static final String MC_COY_SIGNED_RSA_1 = createSigned(MC_COY, TestJwk.RSA_1); - static final String MC_COY_SIGNED_RSA_X = createSigned(MC_COY, TestJwk.RSA_X); + static final String MC_COY_SIGNED_RSA_X = createSigned(MC_COY, TestJwk.RSA_X); - static final String MC_COY_EXPIRED_SIGNED_OCT_1 = createSigned(MC_COY_EXPIRED, TestJwk.OCT_1); + static final String MC_COY_EXPIRED_SIGNED_OCT_1 = createSigned(MC_COY_EXPIRED, TestJwk.OCT_1); - static class NoKid { - static final String MC_COY_SIGNED_RSA_1 = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_1); - static final String MC_COY_SIGNED_RSA_2 = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_2); - static final String MC_COY_SIGNED_RSA_X = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_X); - } + static class NoKid { + static final String MC_COY_SIGNED_RSA_1 = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_1); + static final String MC_COY_SIGNED_RSA_2 = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_2); + static final String MC_COY_SIGNED_RSA_X = createSignedWithoutKeyId(MC_COY, TestJwk.RSA_X); + } - static class PeculiarEscaping { - static final String MC_COY_SIGNED_RSA_1 = createSignedWithPeculiarEscaping(MC_COY, TestJwk.RSA_1); - } + static class PeculiarEscaping { + static final String MC_COY_SIGNED_RSA_1 = createSignedWithPeculiarEscaping(MC_COY, TestJwk.RSA_1); + } - static JwtToken create(String subject, String audience, String issuer, Object... moreClaims) { - JwtClaims claims = new JwtClaims(); + static JwtToken create(String subject, String audience, String issuer, Object... moreClaims) { + JwtClaims claims = new JwtClaims(); - claims.setSubject(subject); - if (audience != null) { - claims.setAudience(audience); - } - if (issuer != null) { - claims.setIssuer(issuer); - } + claims.setSubject(subject); + if (audience != null) { + claims.setAudience(audience); + } + if (issuer != null) { + claims.setIssuer(issuer); + } - if (moreClaims != null) { - for (int i = 0; i < moreClaims.length; i += 2) { - claims.setClaim(String.valueOf(moreClaims[i]), moreClaims[i + 1]); - } - } + if (moreClaims != null) { + for (int i = 0; i < moreClaims.length; i += 2) { + claims.setClaim(String.valueOf(moreClaims[i]), moreClaims[i + 1]); + } + } - JwtToken result = new JwtToken(claims); + JwtToken result = new JwtToken(claims); - return result; - } + return result; + } - static String createSigned(JwtToken baseJwt, JsonWebKey jwk) { + static String createSigned(JwtToken baseJwt, JsonWebKey jwk) { return createSigned(baseJwt, jwk, JwsUtils.getSignatureProvider(jwk)); } static String createSigned(JwtToken baseJwt, JsonWebKey jwk, JwsSignatureProvider signatureProvider) { - JwsHeaders jwsHeaders = new JwsHeaders(); - JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); + JwsHeaders jwsHeaders = new JwsHeaders(); + JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); - jwsHeaders.setKeyId(jwk.getKeyId()); + jwsHeaders.setKeyId(jwk.getKeyId()); return new JoseJwtProducer().processJwt(signedToken, null, signatureProvider); - } - - static String createSignedWithoutKeyId(JwtToken baseJwt, JsonWebKey jwk) { - JwsHeaders jwsHeaders = new JwsHeaders(); - JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); + } - return new JoseJwtProducer().processJwt(signedToken, null, JwsUtils.getSignatureProvider(jwk)); - } + static String createSignedWithoutKeyId(JwtToken baseJwt, JsonWebKey jwk) { + JwsHeaders jwsHeaders = new JwsHeaders(); + JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); - static String createSignedWithPeculiarEscaping(JwtToken baseJwt, JsonWebKey jwk) { - JwsSignatureProvider signatureProvider = JwsUtils.getSignatureProvider(jwk); - JwsHeaders jwsHeaders = new JwsHeaders(); - JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); + return new JoseJwtProducer().processJwt(signedToken, null, JwsUtils.getSignatureProvider(jwk)); + } - // Depends on CXF not escaping the input string. This may fail for other frameworks or versions. - jwsHeaders.setKeyId(jwk.getKeyId().replace("/", "\\/")); + static String createSignedWithPeculiarEscaping(JwtToken baseJwt, JsonWebKey jwk) { + JwsSignatureProvider signatureProvider = JwsUtils.getSignatureProvider(jwk); + JwsHeaders jwsHeaders = new JwsHeaders(); + JwtToken signedToken = new JwtToken(jwsHeaders, baseJwt.getClaims()); - return new JoseJwtProducer().processJwt(signedToken, null, signatureProvider); - } + // Depends on CXF not escaping the input string. This may fail for other frameworks or versions. + jwsHeaders.setKeyId(jwk.getKeyId().replace("/", "\\/")); - static String createMcCoySignedOct1(long nbf, long exp) - { - JwtToken jwt_token = create( - MCCOY_SUBJECT, TEST_AUDIENCE, - TEST_ISSUER, ROLES_CLAIM, TEST_ROLES_STRING, - JwtConstants.CLAIM_NOT_BEFORE, nbf, - JwtConstants.CLAIM_EXPIRY, exp); + return new JoseJwtProducer().processJwt(signedToken, null, signatureProvider); + } - return createSigned(jwt_token, TestJwk.OCT_1); - } + static String createMcCoySignedOct1(long nbf, long exp) { + JwtToken jwt_token = create( + MCCOY_SUBJECT, + TEST_AUDIENCE, + TEST_ISSUER, + ROLES_CLAIM, + TEST_ROLES_STRING, + JwtConstants.CLAIM_NOT_BEFORE, + nbf, + JwtConstants.CLAIM_EXPIRY, + exp + ); + + return createSigned(jwt_token, TestJwk.OCT_1); + } } diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java index bfaf33049d..5a70a963c6 100644 --- a/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java +++ b/src/test/java/com/amazon/dlic/auth/http/saml/HTTPSamlAuthenticatorTest.java @@ -62,37 +62,39 @@ public class HTTPSamlAuthenticatorTest { protected MockSamlIdpServer mockSamlIdpServer; - private static final Pattern WWW_AUTHENTICATE_PATTERN = Pattern - .compile("([^\\s]+)\\s*([^\\s=]+)=\"([^\"]+)\"\\s*([^\\s=]+)=\"([^\"]+)\"\\s*([^\\s=]+)=\"([^\"]+)\"\\s*"); + private static final Pattern WWW_AUTHENTICATE_PATTERN = Pattern.compile( + "([^\\s]+)\\s*([^\\s=]+)=\"([^\"]+)\"\\s*([^\\s=]+)=\"([^\"]+)\"\\s*([^\\s=]+)=\"([^\"]+)\"\\s*" + ); private static final String SPOCK_KEY = "-----BEGIN ENCRYPTED PRIVATE KEY-----\n" - + "MIIE6TAbBgkqhkiG9w0BBQMwDgQI0JMa7PyPedwCAggABIIEyLdPL2RXj8jjKqFT\n" - + "p+7vywwyxyUQOQvvIIU6H+lKZPd/y6pxzYtGd1suT2aermrrlh4b/ZXXfj/EcKcw\n" - + "GgcXB60Kr7UHIv7Xr498S4EKa9R7UG0NtWtsA3FVR5ndwXI+CiRSShhkskmpseVH\n" - + "dNWAoUsKQFbZRLnoINMKIw1/lpQBUwAUcYVB7LxLeKSTVHn/h9kvq0tad1kbE5OY\n" - + "GnOLEVW311++XQ3Ep/13tGEZCrxef+QsnmXuYxXBq4RvbyGZOvyM2FC7va8KzJxl\n" - + "P38SPEL1TzqokQB/eLDBMBOCqkhTbP/8lNuoEVm44T6//ijBp6VdBB+YRIFh3NrS\n" - + "1fPuDVgHr1jrRGICe8lzWy/bSa+4FlxYjn5qpEzZQtbC6C+iRzlwtlCiDdKl8zJ1\n" - + "YF80OW9Gr3Kvph2LJukBiODcyWUAsAf5vJH3vfPV4T9kWTNMu2NCy3Ch8u9d906k\n" - + "zojB/tRRdZ/XCftkU05gYU/5ruU1YA49U60s0KWXvSLmecFo2SjkcEoPDI+Y80Uw\n" - + "OB/5kdh1M1uu/qjoJTPWBbZ28L6e0fiMsr7eWSG7PQFwnN6VzY6Oesm8AS8LMe3V\n" - + "Dr4Syec8vVfGg/EDsjNC1yeZTzlO66NQYGkpnHwK1kgX/XXe7fjDfztPyM9crBXj\n" - + "YcYpNULAkMj9QUVDQqQ7L8TjoAFQiSdvNa+kkDhaxnAXoxfqeacTtkpKcHADsAQL\n" - + "azfoyflnpuZ1dIn0noRFsVuguKDp4k990bhXu9RkQ1H5IzIoYqJwypacVdt3m74o\n" - + "jpZvBY6z0EtBNkze6WA0Vj0BSWpy/IzndDwroG4Xf+54hn0R/Tp5K5UNttOaJN8c\n" - + "9U/NTiGJTJg1O4x6xbPD7C5bBdoJ/MH5yJuk/dUc7pVkisLpuH9sAPETjYCdFIjX\n" - + "MSRJCtq2ouT0ZRW1yBIrKIadgHLExhjZjTSQCBXJMbO7r2DjPHMZU23GTiPtC8ua\n" - + "L2BmC+AW7RQ2Fyo3hJDT2TM4XlMMlTtGuFxkWwmjV+FiwfjbiR3cp0+99/X6OFu5\n" - + "ysgZLuTMQsmWNJ8ZARZqBnkGnN92Aw4D5GLCFv3QXO+fqJnOP1PbkPwpjq59Yytf\n" - + "U4XqyTwRYSXRzwPFFb7RcgL9HbmjpRBEnvqEjKYeXxkBnhs+WOWN/PuJzGgP5uAk\n" - + "jAjQbtgLEPd4WpGcwEhkX6S1DBi8NrGapuehCjXsN1axify8Kx4eRuTiPdINlgsq\n" - + "d2MsPIuDgU2+0QXrXjRLwABcMGuKcmmfZjC+zZomj+yr4+Togs3vhSj9yGK3HHMh\n" - + "NgOlPBTibruXXa4AI07c28j3sEry+CMZrUGyYg6o1HLBpBfOmp7V5HJcvkMFWCVy\n" - + "DPFm5LZu0jZMDj9a+oGkv4hfp1xSXSUjhjiGz47xFJb6PH9pOUIkhTEdFCgEXbaR\n" - + "fXcR+kakLOotL4X1cT9cpxdimN3CCTBpr03gCv2NCVYMYhHKHK+CQVngJrY+PzMH\n" - + "q6fw81bUNcixZyeXFfLFN6GK75k51UV7YS/X2H8YkqGeIVNaFjrcqUoVAN8jQOeb\n" - + "XXIa8gT/MdNT0+W3NHKcbE31pDhOI92COZWlhOyp1cLhyo1ytayjxPTl/2RM/Vtj\n" + "T9IKkp7810LOKhrCDQ==\n" - + "-----END ENCRYPTED PRIVATE KEY-----"; + + "MIIE6TAbBgkqhkiG9w0BBQMwDgQI0JMa7PyPedwCAggABIIEyLdPL2RXj8jjKqFT\n" + + "p+7vywwyxyUQOQvvIIU6H+lKZPd/y6pxzYtGd1suT2aermrrlh4b/ZXXfj/EcKcw\n" + + "GgcXB60Kr7UHIv7Xr498S4EKa9R7UG0NtWtsA3FVR5ndwXI+CiRSShhkskmpseVH\n" + + "dNWAoUsKQFbZRLnoINMKIw1/lpQBUwAUcYVB7LxLeKSTVHn/h9kvq0tad1kbE5OY\n" + + "GnOLEVW311++XQ3Ep/13tGEZCrxef+QsnmXuYxXBq4RvbyGZOvyM2FC7va8KzJxl\n" + + "P38SPEL1TzqokQB/eLDBMBOCqkhTbP/8lNuoEVm44T6//ijBp6VdBB+YRIFh3NrS\n" + + "1fPuDVgHr1jrRGICe8lzWy/bSa+4FlxYjn5qpEzZQtbC6C+iRzlwtlCiDdKl8zJ1\n" + + "YF80OW9Gr3Kvph2LJukBiODcyWUAsAf5vJH3vfPV4T9kWTNMu2NCy3Ch8u9d906k\n" + + "zojB/tRRdZ/XCftkU05gYU/5ruU1YA49U60s0KWXvSLmecFo2SjkcEoPDI+Y80Uw\n" + + "OB/5kdh1M1uu/qjoJTPWBbZ28L6e0fiMsr7eWSG7PQFwnN6VzY6Oesm8AS8LMe3V\n" + + "Dr4Syec8vVfGg/EDsjNC1yeZTzlO66NQYGkpnHwK1kgX/XXe7fjDfztPyM9crBXj\n" + + "YcYpNULAkMj9QUVDQqQ7L8TjoAFQiSdvNa+kkDhaxnAXoxfqeacTtkpKcHADsAQL\n" + + "azfoyflnpuZ1dIn0noRFsVuguKDp4k990bhXu9RkQ1H5IzIoYqJwypacVdt3m74o\n" + + "jpZvBY6z0EtBNkze6WA0Vj0BSWpy/IzndDwroG4Xf+54hn0R/Tp5K5UNttOaJN8c\n" + + "9U/NTiGJTJg1O4x6xbPD7C5bBdoJ/MH5yJuk/dUc7pVkisLpuH9sAPETjYCdFIjX\n" + + "MSRJCtq2ouT0ZRW1yBIrKIadgHLExhjZjTSQCBXJMbO7r2DjPHMZU23GTiPtC8ua\n" + + "L2BmC+AW7RQ2Fyo3hJDT2TM4XlMMlTtGuFxkWwmjV+FiwfjbiR3cp0+99/X6OFu5\n" + + "ysgZLuTMQsmWNJ8ZARZqBnkGnN92Aw4D5GLCFv3QXO+fqJnOP1PbkPwpjq59Yytf\n" + + "U4XqyTwRYSXRzwPFFb7RcgL9HbmjpRBEnvqEjKYeXxkBnhs+WOWN/PuJzGgP5uAk\n" + + "jAjQbtgLEPd4WpGcwEhkX6S1DBi8NrGapuehCjXsN1axify8Kx4eRuTiPdINlgsq\n" + + "d2MsPIuDgU2+0QXrXjRLwABcMGuKcmmfZjC+zZomj+yr4+Togs3vhSj9yGK3HHMh\n" + + "NgOlPBTibruXXa4AI07c28j3sEry+CMZrUGyYg6o1HLBpBfOmp7V5HJcvkMFWCVy\n" + + "DPFm5LZu0jZMDj9a+oGkv4hfp1xSXSUjhjiGz47xFJb6PH9pOUIkhTEdFCgEXbaR\n" + + "fXcR+kakLOotL4X1cT9cpxdimN3CCTBpr03gCv2NCVYMYhHKHK+CQVngJrY+PzMH\n" + + "q6fw81bUNcixZyeXFfLFN6GK75k51UV7YS/X2H8YkqGeIVNaFjrcqUoVAN8jQOeb\n" + + "XXIa8gT/MdNT0+W3NHKcbE31pDhOI92COZWlhOyp1cLhyo1ytayjxPTl/2RM/Vtj\n" + + "T9IKkp7810LOKhrCDQ==\n" + + "-----END ENCRYPTED PRIVATE KEY-----"; private static X509Certificate spSigningCertificate; private static PrivateKey spSigningPrivateKey; @@ -121,9 +123,14 @@ public void basicTest() throws Exception { mockSamlIdpServer.setAuthenticateUser("horst"); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -137,9 +144,11 @@ public void basicTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -157,11 +166,18 @@ public void decryptAssertionsTest() throws Exception { mockSamlIdpServer.setSpSignatureCertificate(spSigningCertificate); mockSamlIdpServer.setEncryptAssertion(true); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -175,9 +191,11 @@ public void decryptAssertionsTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -196,11 +214,18 @@ public void shouldUnescapeSamlEntitiesTest() throws Exception { mockSamlIdpServer.setEncryptAssertion(true); mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("ABC\\Admin")); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -214,9 +239,11 @@ public void shouldUnescapeSamlEntitiesTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -225,7 +252,7 @@ public void shouldUnescapeSamlEntitiesTest() throws Exception { JwtToken jwt = jwtConsumer.getJwtToken(); Assert.assertEquals("ABC\\User1", jwt.getClaim("sub")); - Assert.assertEquals("ABC\\User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); + Assert.assertEquals("ABC\\User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); Assert.assertEquals("[ABC\\Admin]", String.valueOf(jwt.getClaim("roles"))); Assert.assertEquals("ABC\\Admin", samlAuthenticator.httpJwtAuthenticator.extractRoles(jwt.getClaims())[0]); } @@ -238,11 +265,18 @@ public void shouldUnescapeSamlEntitiesTest2() throws Exception { mockSamlIdpServer.setEncryptAssertion(true); mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("ABC\"Admin")); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -256,9 +290,11 @@ public void shouldUnescapeSamlEntitiesTest2() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -267,7 +303,7 @@ public void shouldUnescapeSamlEntitiesTest2() throws Exception { JwtToken jwt = jwtConsumer.getJwtToken(); Assert.assertEquals("ABC\"User1", jwt.getClaim("sub")); - Assert.assertEquals("ABC\"User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); + Assert.assertEquals("ABC\"User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); Assert.assertEquals("[ABC\"Admin]", String.valueOf(jwt.getClaim("roles"))); Assert.assertEquals("ABC\"Admin", samlAuthenticator.httpJwtAuthenticator.extractRoles(jwt.getClaims())[0]); } @@ -280,11 +316,18 @@ public void shouldNotEscapeSamlEntities() throws Exception { mockSamlIdpServer.setEncryptAssertion(true); mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("ABC/Admin")); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -298,9 +341,11 @@ public void shouldNotEscapeSamlEntities() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -309,7 +354,7 @@ public void shouldNotEscapeSamlEntities() throws Exception { JwtToken jwt = jwtConsumer.getJwtToken(); Assert.assertEquals("ABC/User1", jwt.getClaim("sub")); - Assert.assertEquals("ABC/User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); + Assert.assertEquals("ABC/User1", samlAuthenticator.httpJwtAuthenticator.extractSubject(jwt.getClaims())); Assert.assertEquals("[ABC/Admin]", String.valueOf(jwt.getClaim("roles"))); Assert.assertEquals("ABC/Admin", samlAuthenticator.httpJwtAuthenticator.extractRoles(jwt.getClaims())[0]); } @@ -322,11 +367,18 @@ public void shouldNotTrimWhitespaceInJwtRoles() throws Exception { mockSamlIdpServer.setEncryptAssertion(true); mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList(" ABC/Admin ")); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -340,9 +392,11 @@ public void shouldNotTrimWhitespaceInJwtRoles() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -362,12 +416,16 @@ public void testMetadataBody() throws Exception { // Note: We need to replace endpoint with mockSamlIdpServer endpoint final String metadataBody = FileHelper.loadFile("saml/metadata.xml") - .replaceAll("http://localhost:33667/", mockSamlIdpServer.getMetadataUri()); + .replaceAll("http://localhost:33667/", mockSamlIdpServer.getMetadataUri()); - Settings settings = Settings.builder().put(IDP_METADATA_CONTENT, metadataBody) + Settings settings = Settings.builder() + .put(IDP_METADATA_CONTENT, metadataBody) .put("kibana_url", "http://wherever") .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -381,9 +439,11 @@ public void testMetadataBody() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, new TypeReference>() { - }); + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -394,18 +454,21 @@ public void testMetadataBody() throws Exception { Assert.assertEquals("horst", jwt.getClaim("sub")); } - - @Test(expected= RuntimeException.class) + @Test(expected = RuntimeException.class) public void testEmptyMetadataBody() throws Exception { mockSamlIdpServer.setSignResponses(true); mockSamlIdpServer.loadSigningKeys("saml/kirk-keystore.jks", "kirk"); mockSamlIdpServer.setAuthenticateUser("horst"); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_CONTENT, "") + Settings settings = Settings.builder() + .put(IDP_METADATA_CONTENT, "") .put("kibana_url", "http://wherever") .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); new HTTPSamlAuthenticator(settings, null); } @@ -418,24 +481,34 @@ public void unsolicitedSsoTest() throws Exception { mockSamlIdpServer.setEndpointQueryString(null); mockSamlIdpServer.setDefaultAssertionConsumerService("http://wherever/opendistrosecurity/saml/acs/idpinitiated"); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); String encodedSamlResponse = mockSamlIdpServer.createUnsolicitedSamlResponse(); - RestRequest tokenRestRequest = buildTokenExchangeRestRequest(encodedSamlResponse, null, - "/opendistrosecurity/saml/acs/idpinitiated"); + RestRequest tokenRestRequest = buildTokenExchangeRestRequest( + encodedSamlResponse, + null, + "/opendistrosecurity/saml/acs/idpinitiated" + ); TestRestChannel tokenRestChannel = new TestRestChannel(tokenRestRequest); samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -454,19 +527,29 @@ public void badUnsolicitedSsoTest() throws Exception { mockSamlIdpServer.setEndpointQueryString(null); mockSamlIdpServer.setDefaultAssertionConsumerService("http://wherever/opendistrosecurity/saml/acs/idpinitiated"); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); String encodedSamlResponse = mockSamlIdpServer.createUnsolicitedSamlResponse(); - AuthenticateHeaders authenticateHeaders = new AuthenticateHeaders("http://wherever/opendistrosecurity/saml/acs/", - "wrong_request_id"); + AuthenticateHeaders authenticateHeaders = new AuthenticateHeaders( + "http://wherever/opendistrosecurity/saml/acs/", + "wrong_request_id" + ); - RestRequest tokenRestRequest = buildTokenExchangeRestRequest(encodedSamlResponse, authenticateHeaders, - "/opendistrosecurity/saml/acs/idpinitiated"); + RestRequest tokenRestRequest = buildTokenExchangeRestRequest( + encodedSamlResponse, + authenticateHeaders, + "/opendistrosecurity/saml/acs/idpinitiated" + ); TestRestChannel tokenRestChannel = new TestRestChannel(tokenRestRequest); samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); @@ -481,9 +564,14 @@ public void wrongCertTest() throws Exception { mockSamlIdpServer.setAuthenticateUser("horst"); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -507,9 +595,14 @@ public void noSignatureTest() throws Exception { mockSamlIdpServer.setAuthenticateUser("horst"); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -534,9 +627,15 @@ public void rolesTest() throws Exception { mockSamlIdpServer.setAuthenticateUserRoles(Arrays.asList("a ,c", "b ,d, e", "f", "g,,h, ,i")); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").put("roles_seperator", ",").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .put("roles_seperator", ",") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -550,9 +649,11 @@ public void rolesTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -561,8 +662,10 @@ public void rolesTest() throws Exception { JwtToken jwt = jwtConsumer.getJwtToken(); Assert.assertEquals("horst", jwt.getClaim("sub")); - Assert.assertArrayEquals(new String[] { "a ", "c", "b ", "d", " e", "f", "g", "h", " ", "i" }, - ((List) jwt.getClaim("roles")).toArray(new String[0])); + Assert.assertArrayEquals( + new String[] { "a ", "c", "b ", "d", " e", "f", "g", "h", " ", "i" }, + ((List) jwt.getClaim("roles")).toArray(new String[0]) + ); } @Test @@ -572,9 +675,14 @@ public void idpEndpointWithQueryStringTest() throws Exception { mockSamlIdpServer.setAuthenticateUser("horst"); mockSamlIdpServer.setEndpointQueryString("extra=query"); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -588,9 +696,11 @@ public void idpEndpointWithQueryStringTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -622,9 +732,12 @@ private void commaSeparatedRoles(final String rolesAsString, final Settings.Buil mockSamlIdpServer.setEndpointQueryString(null); Settings settings = settingsBuilder.put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".") - .build(); + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); AuthenticateHeaders authenticateHeaders = getAutenticateHeaders(samlAuthenticator); @@ -637,9 +750,11 @@ private void commaSeparatedRoles(final String rolesAsString, final Settings.Buil samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -648,8 +763,7 @@ private void commaSeparatedRoles(final String rolesAsString, final Settings.Buil JwtToken jwt = jwtConsumer.getJwtToken(); Assert.assertEquals("horst", jwt.getClaim("sub")); - Assert.assertArrayEquals(new String[] { "a", "b" }, - ((List) jwt.getClaim("roles")).toArray(new String[0])); + Assert.assertArrayEquals(new String[] { "a", "b" }, ((List) jwt.getClaim("roles")).toArray(new String[0])); } @Test @@ -660,12 +774,18 @@ public void basicLogoutTest() throws Exception { mockSamlIdpServer.setSpSignatureCertificate(spSigningCertificate); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles") - .put("sp.signature_private_key", "-BEGIN PRIVATE KEY-\n" - + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-") - .put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put( + "sp.signature_private_key", + "-BEGIN PRIVATE KEY-\n" + Base64.getEncoder().encodeToString(spSigningPrivateKey.getEncoded()) + "-END PRIVATE KEY-" + ) + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -688,10 +808,16 @@ public void basicLogoutTestEncryptedKey() throws Exception { mockSamlIdpServer.setSpSignatureCertificate(spSigningCertificate); mockSamlIdpServer.setEndpointQueryString(null); - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("sp.signature_private_key", SPOCK_KEY) - .put("sp.signature_private_key_password", "changeit").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("sp.signature_private_key", SPOCK_KEY) + .put("sp.signature_private_key_password", "changeit") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -710,10 +836,15 @@ public void basicLogoutTestEncryptedKey() throws Exception { public void initialConnectionFailureTest() throws Exception { try (MockSamlIdpServer mockSamlIdpServer = new MockSamlIdpServer()) { - Settings settings = Settings.builder().put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) - .put("idp.min_refresh_delay", 100) - .put("kibana_url", "http://wherever").put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) - .put("exchange_key", "abc").put("roles_key", "roles").put("path.home", ".").build(); + Settings settings = Settings.builder() + .put(IDP_METADATA_URL, mockSamlIdpServer.getMetadataUri()) + .put("idp.min_refresh_delay", 100) + .put("kibana_url", "http://wherever") + .put("idp.entity_id", mockSamlIdpServer.getIdpEntityId()) + .put("exchange_key", "abc") + .put("roles_key", "roles") + .put("path.home", ".") + .build(); HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null); @@ -742,9 +873,11 @@ public void initialConnectionFailureTest() throws Exception { samlAuthenticator.reRequestAuthentication(tokenRestChannel, null); String responseJson = new String(BytesReference.toBytes(tokenRestChannel.response.content())); - HashMap response = DefaultObjectMapper.objectMapper.readValue(responseJson, - new TypeReference>() { - }); + HashMap response = DefaultObjectMapper.objectMapper.readValue( + responseJson, + new TypeReference>() { + } + ); String authorization = (String) response.get("authorization"); Assert.assertNotNull("Expected authorization attribute in JSON: " + responseJson, authorization); @@ -765,8 +898,7 @@ private AuthenticateHeaders getAutenticateHeaders(HTTPSamlAuthenticator samlAuth List wwwAuthenticateHeaders = restChannel.response.getHeaders().get("WWW-Authenticate"); Assert.assertNotNull(wwwAuthenticateHeaders); - Assert.assertEquals("More than one WWW-Authenticate header: " + wwwAuthenticateHeaders, 1, - wwwAuthenticateHeaders.size()); + Assert.assertEquals("More than one WWW-Authenticate header: " + wwwAuthenticateHeaders, 1, wwwAuthenticateHeaders.size()); String wwwAuthenticateHeader = wwwAuthenticateHeaders.get(0); @@ -786,26 +918,36 @@ private AuthenticateHeaders getAutenticateHeaders(HTTPSamlAuthenticator samlAuth return new AuthenticateHeaders(location, requestId); } - private RestRequest buildTokenExchangeRestRequest(String encodedSamlResponse, - AuthenticateHeaders authenticateHeaders) { + private RestRequest buildTokenExchangeRestRequest(String encodedSamlResponse, AuthenticateHeaders authenticateHeaders) { return buildTokenExchangeRestRequest(encodedSamlResponse, authenticateHeaders, "/opendistrosecurity/saml/acs"); } - private RestRequest buildTokenExchangeRestRequest(String encodedSamlResponse, - AuthenticateHeaders authenticateHeaders, String acsEndpoint) { + private RestRequest buildTokenExchangeRestRequest( + String encodedSamlResponse, + AuthenticateHeaders authenticateHeaders, + String acsEndpoint + ) { String authtokenPostJson; if (authenticateHeaders != null) { - authtokenPostJson = "{\"SAMLResponse\": \"" + encodedSamlResponse + "\", \"RequestId\": \"" - + authenticateHeaders.requestId + "\"}"; + authtokenPostJson = "{\"SAMLResponse\": \"" + + encodedSamlResponse + + "\", \"RequestId\": \"" + + authenticateHeaders.requestId + + "\"}"; } else { - authtokenPostJson = "{\"SAMLResponse\": \"" + encodedSamlResponse - + "\", \"RequestId\": null, \"acsEndpoint\": \"" + acsEndpoint + "\" }"; + authtokenPostJson = "{\"SAMLResponse\": \"" + + encodedSamlResponse + + "\", \"RequestId\": null, \"acsEndpoint\": \"" + + acsEndpoint + + "\" }"; } - return new FakeRestRequest.Builder().withPath("/_opendistro/_security/api/authtoken").withMethod(Method.POST) - .withContent(new BytesArray(authtokenPostJson)) - .withHeaders(ImmutableMap.of("Content-Type", "application/json")).build(); + return new FakeRestRequest.Builder().withPath("/_opendistro/_security/api/authtoken") + .withMethod(Method.POST) + .withContent(new BytesArray(authtokenPostJson)) + .withHeaders(ImmutableMap.of("Content-Type", "application/json")) + .build(); } @BeforeClass @@ -814,8 +956,7 @@ public static void initSpSigningKeys() { KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("saml/spock-keystore.jks").toFile()); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("saml/spock-keystore.jks").toFile()); keyStore.load(keyStream, "changeit".toCharArray()); kmf.init(keyStore, "changeit".toCharArray()); @@ -824,8 +965,7 @@ public static void initSpSigningKeys() { spSigningPrivateKey = (PrivateKey) keyStore.getKey("spock", "changeit".toCharArray()); - } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException - | UnrecoverableKeyException e) { + } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException | UnrecoverableKeyException e) { throw new RuntimeException(e); } } @@ -876,7 +1016,8 @@ public void sendResponse(RestResponse response) { } @Override - public XContentBuilder newBuilder(XContentType xContentType, XContentType responseContentType, boolean useFiltering) throws IOException { + public XContentBuilder newBuilder(XContentType xContentType, XContentType responseContentType, boolean useFiltering) + throws IOException { return null; } diff --git a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java index 4f4a8c9640..ef54e3e833 100644 --- a/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java +++ b/src/test/java/com/amazon/dlic/auth/http/saml/MockSamlIdpServer.java @@ -193,46 +193,50 @@ class MockSamlIdpServer implements Closeable { this.loadSigningKeys("saml/kirk-keystore.jks", "kirk"); - ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap().setListenerPort(port) - .register(CTX_METADATA, new HttpRequestHandler() { + ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap() + .setListenerPort(port) + .register(CTX_METADATA, new HttpRequestHandler() { - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { - handleMetadataRequest(request, response, context); + handleMetadataRequest(request, response, context); - } - }).register(CTX_SAML_SSO, new HttpRequestHandler() { + } + }) + .register(CTX_SAML_SSO, new HttpRequestHandler() { - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { - handleSsoRequest(request, response, context); - } - }).register(CTX_SAML_SLO, new HttpRequestHandler() { + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + handleSsoRequest(request, response, context); + } + }) + .register(CTX_SAML_SLO, new HttpRequestHandler() { - @Override - public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, IOException { - handleSloRequest(request, response, context); - } - }); + @Override + public void handle(ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { + handleSloRequest(request, response, context); + } + }); if (ssl) { - serverBootstrap = serverBootstrap.setSslContext(createSSLContext()) - .setSslSetupHandler(new Callback() { - @Override - public void execute(SSLParameters object) { - object.setNeedClientAuth(true); - } - }) - .setConnectionFactory(new HttpConnectionFactory() { - @Override - public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { - final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(ssl ? "https" : "http", Http1Config.DEFAULT); - conn.bind(socket); - return conn; - } - }); + serverBootstrap = serverBootstrap.setSslContext(createSSLContext()).setSslSetupHandler(new Callback() { + @Override + public void execute(SSLParameters object) { + object.setNeedClientAuth(true); + } + }).setConnectionFactory(new HttpConnectionFactory() { + @Override + public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException { + final DefaultBHttpServerConnection conn = new DefaultBHttpServerConnection(ssl ? "https" : "http", Http1Config.DEFAULT); + conn.bind(socket); + return conn; + } + }); } this.httpServer = serverBootstrap.create(); @@ -289,16 +293,15 @@ public int getPort() { return port; } - protected void handleMetadataRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) - throws HttpException, IOException { + protected void handleMetadataRequest(HttpRequest request, ClassicHttpResponse response, HttpContext context) throws HttpException, + IOException { response.setCode(200); response.setHeader("Cache-Control", "public, max-age=31536000"); response.setHeader("Content-Type", "application/xml"); response.setEntity(new StringEntity(createMetadata())); } - protected void handleSsoRequest(HttpRequest request, HttpResponse response, HttpContext context) - throws HttpException, IOException { + protected void handleSsoRequest(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { if ("GET".equalsIgnoreCase(request.getMethod())) { handleSsoGetRequestBase(request); @@ -308,8 +311,7 @@ protected void handleSsoRequest(HttpRequest request, HttpResponse response, Http } - protected void handleSloRequest(HttpRequest request, HttpResponse response, HttpContext context) - throws HttpException, IOException { + protected void handleSloRequest(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { if ("GET".equalsIgnoreCase(request.getMethod())) { handleSloGetRequestBase(request); @@ -375,10 +377,10 @@ public void handleSloGetRequestBase(HttpRequest request) { LogoutRequest logoutRequest = (LogoutRequest) messageContext.getMessage(); - SAML2HTTPRedirectDeflateSignatureSecurityHandler signatureSecurityHandler = new SAML2HTTPRedirectDeflateSignatureSecurityHandler(); + SAML2HTTPRedirectDeflateSignatureSecurityHandler signatureSecurityHandler = + new SAML2HTTPRedirectDeflateSignatureSecurityHandler(); SignatureValidationParameters validationParams = new SignatureValidationParameters(); - SecurityParametersContext securityParametersContext = messageContext - .getSubcontext(SecurityParametersContext.class, true); + SecurityParametersContext securityParametersContext = messageContext.getSubcontext(SecurityParametersContext.class, true); SAMLPeerEntityContext peerEntityContext = messageContext.getSubcontext(SAMLPeerEntityContext.class, true); peerEntityContext.setEntityId(idpEntityId); @@ -397,8 +399,7 @@ public void handleSloGetRequestBase(HttpRequest request) { throw new RuntimeException("Unexpected NameID in LogoutRequest: " + logoutRequest); } - } catch (URISyntaxException | ComponentInitializationException | MessageDecodingException - | MessageHandlerException e) { + } catch (URISyntaxException | ComponentInitializationException | MessageDecodingException | MessageHandlerException e) { throw new RuntimeException(e); } } @@ -436,12 +437,24 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { if (authnRequest != null) { subject.getSubjectConfirmations() - .add(createSubjectConfirmation("urn:oasis:names:tc:SAML:2.0:cm:bearer", - new DateTime().plusMinutes(1), authnRequest.getID(), - authnRequest.getAssertionConsumerServiceURL())); + .add( + createSubjectConfirmation( + "urn:oasis:names:tc:SAML:2.0:cm:bearer", + new DateTime().plusMinutes(1), + authnRequest.getID(), + authnRequest.getAssertionConsumerServiceURL() + ) + ); } else { - subject.getSubjectConfirmations().add(createSubjectConfirmation("urn:oasis:names:tc:SAML:2.0:cm:bearer", - new DateTime().plusMinutes(1), null, defaultAssertionConsumerService)); + subject.getSubjectConfirmations() + .add( + createSubjectConfirmation( + "urn:oasis:names:tc:SAML:2.0:cm:bearer", + new DateTime().plusMinutes(1), + null, + defaultAssertionConsumerService + ) + ); } Conditions conditions = createSamlElement(Conditions.class); @@ -464,7 +477,7 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { attribute.getAttributeValues().add(createXSAny(AttributeValue.DEFAULT_ELEMENT_NAME, role)); } } - + if (signResponses) { Signature signature = createSamlElement(Signature.class); assertion.setSignature(signature); @@ -478,7 +491,7 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { Signer.signObject(signature); } - if (this.encryptAssertion){ + if (this.encryptAssertion) { Encrypter encrypter = getEncrypter(); EncryptedAssertion encryptedAssertion = encrypter.encrypt(assertion); response.getEncryptedAssertions().add(encryptedAssertion); @@ -486,7 +499,6 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { response.getAssertions().add(assertion); } - String marshalledXml = marshallSamlXml(response); return Base64Support.encode(marshalledXml.getBytes("UTF-8"), Base64Support.UNCHUNKED); @@ -498,10 +510,11 @@ private String createSamlAuthResponse(AuthnRequest authnRequest) { private Encrypter getEncrypter() { KeyEncryptionParameters kek = new KeyEncryptionParameters(); - // Algorithm from https://santuario.apache.org/Java/api/constant-values.html#org.apache.xml.security.utils.EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15 + // Algorithm from + // https://santuario.apache.org/Java/api/constant-values.html#org.apache.xml.security.utils.EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15 kek.setAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-1_5"); kek.setEncryptionCredential(new BasicX509Credential(spSignatureCertificate)); - Encrypter encrypter = new Encrypter( new DataEncryptionParameters(),kek); + Encrypter encrypter = new Encrypter(new DataEncryptionParameters(), kek); encrypter.setKeyPlacement(Encrypter.KeyPlacement.INLINE); return encrypter; } @@ -554,8 +567,7 @@ private NameID createNameID(String format, String value) { return nameID; } - private SubjectConfirmation createSubjectConfirmation(String method, DateTime notOnOrAfter, String inResponseTo, - String recipient) { + private SubjectConfirmation createSubjectConfirmation(String method, DateTime notOnOrAfter, String inResponseTo, String recipient) { SubjectConfirmation result = createSamlElement(SubjectConfirmation.class); result.setMethod(method); @@ -601,8 +613,7 @@ private String createMetadata() { redirectSingleLogoutService.setBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"); redirectSingleLogoutService.setLocation(getSamlSloUri()); - idpSsoDescriptor.getNameIDFormats() - .add(createNameIDFormat("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")); + idpSsoDescriptor.getNameIDFormats().add(createNameIDFormat("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")); SingleSignOnService redirectSingleSignOnService = createSamlElement(SingleSignOnService.class); idpSsoDescriptor.getSingleSignOnServices().add(redirectSingleSignOnService); @@ -619,8 +630,7 @@ private String createMetadata() { signingKeyDescriptor.setUse(UsageType.SIGNING); - signingKeyDescriptor - .setKeyInfo(keyInfoGenerator.generate(new BasicX509Credential(this.signingCertificate))); + signingKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(new BasicX509Credential(this.signingCertificate))); return marshallSamlXml(idpEntityDescriptor); } catch (org.opensaml.security.SecurityException e) { @@ -640,16 +650,14 @@ private String marshallSamlXml(XMLObject xmlObject) { transformer.transform(source, new StreamResult(stringWriter)); return stringWriter.toString(); - } catch (ParserConfigurationException | MarshallingException | TransformerFactoryConfigurationError - | TransformerException e) { + } catch (ParserConfigurationException | MarshallingException | TransformerFactoryConfigurationError | TransformerException e) { throw new RuntimeException(e); } } private SignatureTrustEngine buildSignatureTrustEngine(X509Certificate certificate) { CredentialResolver credentialResolver = new StaticCredentialResolver(new BasicX509Credential(certificate)); - KeyInfoCredentialResolver keyInfoCredentialResolver = new StaticKeyInfoCredentialResolver( - new BasicX509Credential(certificate)); + KeyInfoCredentialResolver keyInfoCredentialResolver = new StaticKeyInfoCredentialResolver(new BasicX509Credential(certificate)); return new ExplicitKeySignatureTrustEngine(credentialResolver, keyInfoCredentialResolver); } @@ -666,11 +674,12 @@ void loadSigningKeys(String path, String alias) { this.signingCertificate = (X509Certificate) keyStore.getCertificate(alias); - this.signingCredential = new BasicX509Credential(this.signingCertificate, - (PrivateKey) keyStore.getKey(alias, "changeit".toCharArray())); + this.signingCredential = new BasicX509Credential( + this.signingCertificate, + (PrivateKey) keyStore.getKey(alias, "changeit".toCharArray()) + ); - } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException - | UnrecoverableKeyException e) { + } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException | UnrecoverableKeyException e) { throw new RuntimeException(e); } } @@ -683,15 +692,13 @@ private SSLContext createSSLContext() { try { final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); final KeyStore trustStore = KeyStore.getInstance("JKS"); - InputStream trustStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); + InputStream trustStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/truststore.jks").toFile()); trustStore.load(trustStream, "changeit".toCharArray()); tmf.init(trustStore); final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); final KeyStore keyStore = KeyStore.getInstance("JKS"); - InputStream keyStream = new FileInputStream( - FileHelper.getAbsoluteFilePathFromClassPath("jwt/node-0-keystore.jks").toFile()); + InputStream keyStream = new FileInputStream(FileHelper.getAbsoluteFilePathFromClassPath("jwt/node-0-keystore.jks").toFile()); keyStore.load(keyStream, "changeit".toCharArray()); kmf.init(keyStore, "changeit".toCharArray()); @@ -709,14 +716,26 @@ private String nextId() { } static class SSLTestHttpServerConnection extends DefaultBHttpServerConnection { - public SSLTestHttpServerConnection(final String scheme, Http1Config http1Config, - final CharsetDecoder charDecoder, final CharsetEncoder charEncoder, - final ContentLengthStrategy incomingContentStrategy, - final ContentLengthStrategy outgoingContentStrategy, - final HttpMessageParserFactory requestParserFactory, - final HttpMessageWriterFactory responseWriterFactory) { - super(scheme, http1Config, charDecoder, charEncoder, incomingContentStrategy, - outgoingContentStrategy, requestParserFactory, responseWriterFactory); + public SSLTestHttpServerConnection( + final String scheme, + Http1Config http1Config, + final CharsetDecoder charDecoder, + final CharsetEncoder charEncoder, + final ContentLengthStrategy incomingContentStrategy, + final ContentLengthStrategy outgoingContentStrategy, + final HttpMessageParserFactory requestParserFactory, + final HttpMessageWriterFactory responseWriterFactory + ) { + super( + scheme, + http1Config, + charDecoder, + charEncoder, + incomingContentStrategy, + outgoingContentStrategy, + requestParserFactory, + responseWriterFactory + ); } } @@ -729,8 +748,9 @@ static class FakeHttpServletRequest implements HttpServletRequest { this.delegate = delegate; String uri = delegate.getRequestUri(); this.uriBuilder = new URIBuilder(uri); - this.queryParams = uriBuilder.getQueryParams().stream() - .collect(Collectors.toMap(NameValuePair::getName, NameValuePair::getValue)); + this.queryParams = uriBuilder.getQueryParams() + .stream() + .collect(Collectors.toMap(NameValuePair::getName, NameValuePair::getValue)); } @Override @@ -959,8 +979,7 @@ public String getHeader(String name) { @SuppressWarnings("rawtypes") @Override public Enumeration getHeaderNames() { - return Collections.enumeration( - Arrays.asList(delegate.getHeaders()).stream().map(Header::getName).collect(Collectors.toSet())); + return Collections.enumeration(Arrays.asList(delegate.getHeaders()).stream().map(Header::getName).collect(Collectors.toSet())); } @SuppressWarnings("rawtypes") @@ -969,8 +988,7 @@ public Enumeration getHeaders(String name) { Header[] headers = delegate.getHeaders(name); if (headers != null) { - return Collections - .enumeration(Arrays.asList(headers).stream().map(Header::getName).collect(Collectors.toSet())); + return Collections.enumeration(Arrays.asList(headers).stream().map(Header::getName).collect(Collectors.toSet())); } else { return null; } diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java index 81654d4c19..b2ba079dff 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendIntegTest.java @@ -74,13 +74,19 @@ public void testAttributesWithImpersonation() throws Exception { String securityConfigAsYamlString = FileHelper.loadFile("ldap/config.yml"); securityConfigAsYamlString = securityConfigAsYamlString.replace("${ldapsPort}", String.valueOf(ldapsPort)); final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".cn=Captain Spock,ou=people,o=TEST", "*") - .build(); + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".cn=Captain Spock,ou=people,o=TEST", "*") + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfigAsYamlString(securityConfigAsYamlString), settings); final RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "jacksonm") - ,encodeBasicHeader("spock", "spocksecret"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "jacksonm"), + encodeBasicHeader("spock", "spocksecret") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("ldap.dn")); Assert.assertTrue(res.getBody().contains("attr.ldap.entryDN")); @@ -88,7 +94,6 @@ public void testAttributesWithImpersonation() throws Exception { } - @AfterClass public static void tearDownLdap() throws Exception { diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java index db961eb9a4..3cc5006198 100755 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTest.java @@ -61,128 +61,138 @@ public static void startLdapServer() throws Exception { @Test public void testLdapAuthentication() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } - @Test(expected=OpenSearchSecurityException.class) + @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFakeLogin() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true) - .build(); - - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("unknown", "unknown" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true) + .build(); + + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8)) + ); } - @Test(expected=OpenSearchSecurityException.class) + @Test(expected = OpenSearchSecurityException.class) public void testLdapInjection() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); String injectString = "*jack*"; - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials(injectString, "secret" - .getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationBindDn() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "spocksecret") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "spocksecret") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } - @Test(expected=OpenSearchSecurityException.class) + @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationWrongBindDn() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "wrong") - .build(); - - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "wrong") + .build(); + + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } - @Test(expected=OpenSearchSecurityException.class) + @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationBindFail() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8)) + ); } - @Test(expected=OpenSearchSecurityException.class) + @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationNoUser() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFail() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationSSL() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false) - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -190,36 +200,34 @@ public void testLdapAuthenticationSSL() throws Exception { @Test public void testLdapAuthenticationSSLPEMFile() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName()) - .put("verify_hostnames", false) - .put("path.home",".") - .put("path.conf",FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()) - .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, Paths.get("src/test/resources/ldap")).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName() + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()) + .build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, Paths.get("src/test/resources/ldap")).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @Test public void testLdapAuthenticationSSLPEMText() throws Exception { - final Settings settingsFromFile = Settings - .builder() - .loadFromPath( - Paths - .get(FileHelper - .getAbsoluteFilePathFromClassPath("ldap/test1.yml") - .toFile() - .getAbsolutePath())) - .build(); - Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:"+ldapsPort).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final Settings settingsFromFile = Settings.builder() + .loadFromPath(Paths.get(FileHelper.getAbsoluteFilePathFromClassPath("ldap/test1.yml").toFile().getAbsolutePath())) + .build(); + Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:" + ldapsPort).build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -227,20 +235,23 @@ public void testLdapAuthenticationSSLPEMText() throws Exception { @Test public void testLdapAuthenticationSSLSSLv3() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false) - .putList("enabled_ssl_protocols", "SSLv3") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "SSLv3") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (Exception e) { Assert.assertEquals(e.getCause().getClass(), org.ldaptive.LdapException.class); Assert.assertTrue(e.getCause().getMessage().contains("Unable to connec")); @@ -251,20 +262,23 @@ public void testLdapAuthenticationSSLSSLv3() throws Exception { @Test public void testLdapAuthenticationSSLUnknowCipher() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false) - .putList("enabled_ssl_ciphers", "AAA") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_ciphers", "AAA") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (Exception e) { Assert.assertEquals(e.getCause().getClass(), org.ldaptive.LdapException.class); Assert.assertTrue(e.getCause().getMessage().contains("Unable to connec")); @@ -275,20 +289,23 @@ public void testLdapAuthenticationSSLUnknowCipher() throws Exception { @Test public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false) - .putList("enabled_ssl_protocols", "TLSv1.2") - .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "TLSv1.2") + .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); @@ -297,18 +314,21 @@ public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { @Test public void testLdapAuthenticationSSLNoKeystore() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false) - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -316,15 +336,16 @@ public void testLdapAuthenticationSSLNoKeystore() throws Exception { @Test public void testLdapAuthenticationSSLFailPlain() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .build(); try { - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (final Exception e) { Assert.assertEquals(org.ldaptive.LdapException.class, e.getCause().getClass()); } @@ -333,10 +354,10 @@ public void testLdapAuthenticationSSLFailPlain() throws Exception { @Test public void testLdapExists() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); final LDAPAuthenticationBackend lbe = new LDAPAuthenticationBackend(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -346,20 +367,20 @@ public void testLdapExists() throws Exception { @Test public void testLdapAuthorization() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - // .put("plugins.security.authentication.authorization.ldap.userrolename", - // "(uniqueMember={0})") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + // .put("plugins.security.authentication.authorization.ldap.userrolename", + // "(uniqueMember={0})") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -373,19 +394,19 @@ public void testLdapAuthorization() throws Exception { @Test public void testLdapAuthenticationReturnAttributes() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, "mail", "cn", "uid") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, "mail", "cn", "uid") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -401,10 +422,10 @@ public void testLdapAuthenticationReturnAttributes() throws Exception { @Test public void testLdapAuthenticationReferral() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { @@ -418,17 +439,21 @@ public void testLdapAuthenticationReferral() throws Exception { @Test public void testLdapDontFollowReferrals() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.FOLLOW_REFERRALS, false).build(); - + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.FOLLOW_REFERRALS, false) + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { - //If following is off then should fail to return the result provided by following - final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT)); + // If following is off then should fail to return the result provided by following + final LdapEntry ref1 = LdapHelper.lookup( + con, + "cn=Ref1,ou=people,o=TEST", + ReturnAttributes.ALL.value(), + settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT) + ); Assert.assertNull(ref1); } finally { con.close(); @@ -438,20 +463,20 @@ public void testLdapDontFollowReferrals() throws Exception { @Test public void testLdapEscape() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ssign", "ssignsecret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Special\\, Sign,ou=people,o=TEST", user.getName()); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -463,18 +488,18 @@ public void testLdapEscape() throws Exception { @Test public void testLdapAuthorizationRoleSearchUsername() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(cn={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember=cn={1},ou=people,o=TEST)") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("Michael Jackson", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(cn={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember=cn={1},ou=people,o=TEST)") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -489,15 +514,14 @@ public void testLdapAuthorizationRoleSearchUsername() throws Exception { @Test public void testLdapAuthorizationOnly() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -509,19 +533,17 @@ public void testLdapAuthorizationOnly() throws Exception { Assert.assertEquals("ceo", new ArrayList(new TreeSet(user.getRoles())).get(0)); } - - @Test public void testLdapAuthorizationNonDNEntry() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -533,20 +555,18 @@ public void testLdapAuthorizationNonDNEntry() throws Exception { Assert.assertEquals("ceo-ceo", new ArrayList(new TreeSet(user.getRoles())).get(0)); } - @Test public void testLdapAuthorizationNested() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -561,17 +581,16 @@ public void testLdapAuthorizationNested() throws Exception { @Test public void testLdapAuthorizationNestedFilter() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST") + .build(); final User user = new User("spock"); @@ -587,16 +606,15 @@ public void testLdapAuthorizationNestedFilter() throws Exception { @Test public void testLdapAuthorizationDnNested() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -611,17 +629,16 @@ public void testLdapAuthorizationDnNested() throws Exception { @Test public void testLdapAuthorizationDn() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); @@ -636,13 +653,16 @@ public void testLdapAuthorizationDn() throws Exception { @Test public void testLdapAuthenticationUserNameAttribute() throws Exception { - - final Settings settings = Settings.builder().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST").put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final Settings settings = Settings.builder() + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("jacksonm", user.getName()); } @@ -650,17 +670,21 @@ public void testLdapAuthenticationUserNameAttribute() throws Exception { @Test public void testLdapAuthenticationStartTLS() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -668,19 +692,19 @@ public void testLdapAuthenticationStartTLS() throws Exception { @Test public void testLdapAuthorizationSkipUsers() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -694,17 +718,18 @@ public void testLdapAuthorizationSkipUsers() throws Exception { public void testLdapAuthorizationSkipUsersNoDn() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "jacksonm") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "jacksonm") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -717,18 +742,17 @@ public void testLdapAuthorizationSkipUsersNoDn() throws Exception { @Test public void testLdapAuthorizationNestedAttr() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -744,19 +768,18 @@ public void testLdapAuthorizationNestedAttr() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilter() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*") + .build(); final User user = new User("spock"); @@ -773,19 +796,18 @@ public void testLdapAuthorizationNestedAttrFilter() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") + .build(); final User user = new User("spock"); @@ -800,18 +822,18 @@ public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) //-> same like putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like + // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -826,18 +848,17 @@ public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws E @Test public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "unused") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(((unused") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false) - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "unused") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(((unused") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false) + .build(); final User user = new User("spock"); @@ -854,35 +875,42 @@ public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { public void testCustomAttributes() throws Exception { Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); Assert.assertEquals(user.getCustomAttributesMap().toString(), 16, user.getCustomAttributesMap().size()); - Assert.assertFalse(user.getCustomAttributesMap().toString(), user.getCustomAttributesMap().keySet().contains("attr.ldap.userpassword")); + Assert.assertFalse( + user.getCustomAttributesMap().toString(), + user.getCustomAttributesMap().keySet().contains("attr.ldap.userpassword") + ); settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0) - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0) + .build(); - user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*","entryParentId") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId") + .build(); - user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); @@ -892,16 +920,16 @@ public void testCustomAttributes() throws Exception { public void testLdapAuthorizationNonDNRoles() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("nondnroles"); @@ -914,25 +942,28 @@ public void testLdapAuthorizationNonDNRoles() throws Exception { Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", user.getRoles().contains("humanresources")); Assert.assertTrue("Roles do not contain LDAP role 'dummyempty'", user.getRoles().contains("dummyempty")); Assert.assertTrue("Roles do not contain non-LDAP role 'role2'", user.getRoles().contains("role2")); - Assert.assertTrue("Roles do not contain non-LDAP role 'anotherrole' from second role name", user.getRoles().contains("anotherrole")); + Assert.assertTrue( + "Roles do not contain non-LDAP role 'anotherrole' from second role name", + user.getRoles().contains("anotherrole") + ); } - @Test public void testLdapSpecial186() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -948,12 +979,18 @@ public void testLdapSpecial186() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); @@ -963,17 +1000,18 @@ public void testLdapSpecial186() throws Exception { public void testLdapSpecial186_2() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -989,13 +1027,18 @@ public void testLdapSpecial186_2() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); @@ -1004,13 +1047,14 @@ public void testLdapSpecial186_2() throws Exception { @Test public void testOperationalAttributes() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); LdapAttribute operationAttribute = user.getUserEntry().getAttribute("entryUUID"); Assert.assertNotNull(operationAttribute); @@ -1023,23 +1067,23 @@ public void testOperationalAttributes() throws Exception { public void testMultiCn() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("multi", "multi" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("multi", "multi".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=cabc,ou=people,o=TEST", user.getName()); System.out.println(user.getUserEntry().getAttribute("cn")); } - @AfterClass public static void tearDown() throws Exception { diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java index 6f62cd48dd..1765b5fd26 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestClientCert.java @@ -39,106 +39,124 @@ public class LdapBackendTestClientCert { @Test public void testNoAuth() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("authentication required")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("authentication required") + ); } } @Test public void testNoAuthX() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("authentication required")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("authentication required") + ); } } @Test public void testNoAuthY() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/wrong/truststore.jks") - .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/wrong/truststore.jks" + ) + .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("Unable to connect to any")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("Unable to connect to any") + ); } } - - - @Test public void testBindDnAuthLocalhost() throws Exception { - //bin dn auth + // bin dn auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -147,21 +165,27 @@ public void testBindDnAuthLocalhost() throws Exception { public void testLdapSslAuth() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "spock") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + "plugins.security.ssl.transport.keystore_filepath", + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock-keystore.jks" + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "spock") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -170,24 +194,30 @@ public void testLdapSslAuth() throws Exception { public void testLdapSslAuthPem() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/ca/root-ca.pem") - .put(ConfigConstants.LDAPS_PEMCERT_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.crtfull.pem") - .put(ConfigConstants.LDAPS_PEMKEY_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.key.pem") - //.put(ConfigConstants.LDAPS_PEMKEY_PASSWORD, "changeit") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - //.put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/ca/root-ca.pem" + ) + .put( + ConfigConstants.LDAPS_PEMCERT_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.crtfull.pem" + ) + .put(ConfigConstants.LDAPS_PEMKEY_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.key.pem") + // .put(ConfigConstants.LDAPS_PEMKEY_PASSWORD, "changeit") + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + // .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -196,59 +226,66 @@ public void testLdapSslAuthPem() throws Exception { public void testLdapSslAuthNo() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/kirk-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "kirk") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + "plugins.security.ssl.transport.keystore_filepath", + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/kirk-keystore.jks" + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "kirk") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } - public void testLdapAuthenticationSSL() throws Exception { - //startLDAPServer(); + // startLDAPServer(); final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - //.put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/cn=ldapbinder,ou=people,dc=example,dc=com-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - //.put("verify_hostnames", false) - //.put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - //.put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "cn=ldapbinder,ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - //.put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - //.put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - - //.putList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, "TLS_RSA_WITH_AES_128_CBC_SHA") - //.putList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, "TLSv1") - //TLS_RSA_AES_128_CBC_SHA1 - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + // .put("plugins.security.ssl.transport.keystore_filepath", + // "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/cn=ldapbinder,ou=people,dc=example,dc=com-keystore.jks") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + // .put("verify_hostnames", false) + // .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + // .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "cn=ldapbinder,ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + // .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + + // .putList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, "TLS_RSA_WITH_AES_128_CBC_SHA") + // .putList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, "TLSv1") + // TLS_RSA_AES_128_CBC_SHA1 + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } - - public static File getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) { File file = null; final URL fileUrl = LdapBackendTestClientCert.class.getClassLoader().getResource(fileNameFromClasspath); diff --git a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java index 3e21a223e2..8bc13eec48 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/LdapBackendTestNewStyleConfig.java @@ -52,7 +52,7 @@ public class LdapBackendTestNewStyleConfig { public static void startLdapServer() throws Exception { ldapServer = new EmbeddedLDAPServer(); ldapServer.start(); - ldapServer.applyLdif("base.ldif","base2.ldif"); + ldapServer.applyLdif("base.ldif", "base2.ldif"); ldapPort = ldapServer.getLdapPort(); ldapsPort = ldapServer.getLdapsPort(); } @@ -61,11 +61,13 @@ public static void startLdapServer() throws Exception { public void testLdapAuthentication() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -74,38 +76,46 @@ public void testLdapAuthentication() throws Exception { public void testLdapAuthenticationFakeLogin() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true) + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapInjection() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); String injectString = "*jack*"; @SuppressWarnings("unused") - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationBindDn() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "spocksecret").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "spocksecret") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -114,60 +124,75 @@ public void testLdapAuthenticationBindDn() throws Exception { public void testLdapAuthenticationWrongBindDn() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "wrong").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "wrong") + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationBindFail() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationNoUser() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFail() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationSSL() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -176,14 +201,20 @@ public void testLdapAuthenticationSSL() throws Exception { public void testLdapAuthenticationSSLPEMFile() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName()) - .put("verify_hostnames", false).put("path.home", ".") - .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, Paths.get("src/test/resources/ldap")) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName() + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()) + .build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, Paths.get("src/test/resources/ldap")).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -191,18 +222,13 @@ public void testLdapAuthenticationSSLPEMFile() throws Exception { @Test public void testLdapAuthenticationSSLPEMText() throws Exception { - final Settings settingsFromFile = Settings - .builder() - .loadFromPath( - Paths - .get(FileHelper - .getAbsoluteFilePathFromClassPath("ldap/test1.yml") - .toFile() - .getAbsolutePath())) - .build(); - Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:"+ldapsPort).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settingsFromFile = Settings.builder() + .loadFromPath(Paths.get(FileHelper.getAbsoluteFilePathFromClassPath("ldap/test1.yml").toFile().getAbsolutePath())) + .build(); + Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:" + ldapsPort).build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -211,15 +237,22 @@ public void testLdapAuthenticationSSLPEMText() throws Exception { public void testLdapAuthenticationSSLSSLv3() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "SSLv3").put("path.home", ".").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "SSLv3") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (Exception e) { Assert.assertEquals(e.getCause().getClass(), org.ldaptive.LdapException.class); Assert.assertTrue(e.getCause().getMessage().contains("Unable to connec")); @@ -231,15 +264,22 @@ public void testLdapAuthenticationSSLSSLv3() throws Exception { public void testLdapAuthenticationSSLUnknownCipher() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_ciphers", "AAA").put("path.home", ".").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_ciphers", "AAA") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (Exception e) { Assert.assertEquals(e.getCause().getClass(), org.ldaptive.LdapException.class); Assert.assertTrue(e.getCause().getMessage().contains("Unable to connec")); @@ -251,15 +291,22 @@ public void testLdapAuthenticationSSLUnknownCipher() throws Exception { public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "TLSv1.2") - .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA").put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "TLSv1.2") + .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); @@ -269,14 +316,20 @@ public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { public void testLdapAuthenticationSSLNoKeystore() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -285,12 +338,15 @@ public void testLdapAuthenticationSSLNoKeystore() throws Exception { public void testLdapAuthenticationSSLFailPlain() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .build(); try { - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); } catch (final Exception e) { Assert.assertEquals(org.ldaptive.LdapException.class, e.getCause().getClass()); } @@ -300,8 +356,9 @@ public void testLdapAuthenticationSSLFailPlain() throws Exception { public void testLdapExists() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); final LDAPAuthenticationBackend lbe = new LDAPAuthenticationBackend(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -312,16 +369,19 @@ public void testLdapExists() throws Exception { public void testLdapAuthorization() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - // .put("plugins.security.authentication.authorization.ldap.userrolename", - // "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + // .put("plugins.security.authentication.authorization.ldap.userrolename", + // "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -336,8 +396,9 @@ public void testLdapAuthorization() throws Exception { public void testLdapAuthenticationReferral() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { @@ -352,17 +413,21 @@ public void testLdapAuthenticationReferral() throws Exception { @Test public void testLdapDontFollowReferrals() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.FOLLOW_REFERRALS, false).build(); - + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.FOLLOW_REFERRALS, false) + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { - //If following is off then should fail to return the result provided by following - final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT)); + // If following is off then should fail to return the result provided by following + final LdapEntry ref1 = LdapHelper.lookup( + con, + "cn=Ref1,ou=people,o=TEST", + ReturnAttributes.ALL.value(), + settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT) + ); Assert.assertNull(ref1); } finally { con.close(); @@ -373,15 +438,19 @@ public void testLdapDontFollowReferrals() throws Exception { public void testLdapEscape() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Special\\, Sign,ou=people,o=TEST", user.getName()); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -394,13 +463,17 @@ public void testLdapEscape() throws Exception { public void testLdapAuthorizationRoleSearchUsername() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(cn={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember=cn={1},ou=people,o=TEST)").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(cn={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember=cn={1},ou=people,o=TEST)") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -416,10 +489,13 @@ public void testLdapAuthorizationRoleSearchUsername() throws Exception { public void testLdapAuthorizationOnly() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -435,11 +511,14 @@ public void testLdapAuthorizationOnly() throws Exception { public void testLdapAuthorizationNested() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -455,12 +534,15 @@ public void testLdapAuthorizationNested() throws Exception { public void testLdapAuthorizationNestedFilter() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST") + .build(); final User user = new User("spock"); @@ -477,11 +559,14 @@ public void testLdapAuthorizationNestedFilter() throws Exception { public void testLdapAuthorizationDnNested() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -497,15 +582,17 @@ public void testLdapAuthorizationDnNested() throws Exception { public void testLdapAuthorizationDn() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) - .put("roles.g1.search", "(uniqueMember={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); - final User user = new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); + final User user = new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -519,12 +606,15 @@ public void testLdapAuthorizationDn() throws Exception { public void testLdapAuthenticationUserNameAttribute() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.base", "ou=people,o=TEST").put("users.u1.search", "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("jacksonm", user.getName()); } @@ -533,14 +623,20 @@ public void testLdapAuthenticationUserNameAttribute() throws Exception { public void testLdapAuthenticationStartTLS() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -549,14 +645,18 @@ public void testLdapAuthenticationStartTLS() throws Exception { public void testLdapAuthorizationSkipUsers() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -570,13 +670,16 @@ public void testLdapAuthorizationSkipUsers() throws Exception { public void testLdapAuthorizationNestedAttr() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -593,14 +696,17 @@ public void testLdapAuthorizationNestedAttr() throws Exception { public void testLdapAuthorizationNestedAttrFilter() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*") + .build(); final User user = new User("spock"); @@ -618,14 +724,17 @@ public void testLdapAuthorizationNestedAttrFilter() throws Exception { public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") + .build(); final User user = new User("spock"); @@ -641,15 +750,18 @@ public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like - // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, - // "*") - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like + // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, + // "*") + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -665,12 +777,16 @@ public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws E public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "unused").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(((unused") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "unused") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(((unused") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false) + .build(); final User user = new User("spock"); @@ -687,33 +803,39 @@ public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { public void testCustomAttributes() throws Exception { Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); Assert.assertEquals(user.getCustomAttributesMap().toString(), 16, user.getCustomAttributesMap().size()); - Assert.assertFalse(user.getCustomAttributesMap().toString(), - user.getCustomAttributesMap().containsKey("attr.ldap.userpassword")); + Assert.assertFalse(user.getCustomAttributesMap().toString(), user.getCustomAttributesMap().containsKey("attr.ldap.userpassword")); settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0).build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0) + .build(); - user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})") - .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId") + .build(); - user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); @@ -723,13 +845,16 @@ public void testCustomAttributes() throws Exception { public void testLdapAuthorizationNonDNRoles() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("nondnroles"); @@ -739,24 +864,29 @@ public void testLdapAuthorizationNonDNRoles() throws Exception { Assert.assertEquals("nondnroles", user.getName()); Assert.assertEquals(5, user.getRoles().size()); Assert.assertTrue("Roles do not contain non-LDAP role 'kibanauser'", user.getRoles().contains("kibanauser")); - Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", - user.getRoles().contains("humanresources")); + Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", user.getRoles().contains("humanresources")); Assert.assertTrue("Roles do not contain LDAP role 'dummyempty'", user.getRoles().contains("dummyempty")); Assert.assertTrue("Roles do not contain non-LDAP role 'role2'", user.getRoles().contains("role2")); - Assert.assertTrue("Roles do not contain non-LDAP role 'anotherrole' from second role name", - user.getRoles().contains("anotherrole")); + Assert.assertTrue( + "Roles do not contain non-LDAP role 'anotherrole' from second role name", + user.getRoles().contains("anotherrole") + ); } @Test public void testChainedLdapAuthentication1() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("users.u2.search", "(uid={0})").put("users.u2.base", "ou=people2,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -765,12 +895,16 @@ public void testChainedLdapAuthentication1() throws Exception { public void testChainedLdapAuthentication2() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("users.u2.search", "(uid={0})").put("users.u2.base", "ou=people2,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("presleye", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("presleye", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Elvis Presley,ou=people2,o=TEST", user.getName()); } @@ -779,13 +913,17 @@ public void testChainedLdapAuthentication2() throws Exception { public void testChainedLdapAuthenticationDuplicate() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_SEARCH_ALL_BASES, true).put("users.u1.search", "(uid={0})") - .put("users.u1.base", "ou=people,o=TEST").put("users.u2.search", "(uid={0})") - .put("users.u2.base", "ou=people2,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_SEARCH_ALL_BASES, true) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); // Fails with OpenSearchSecurityException because two possible instances are // found @@ -795,9 +933,11 @@ public void testChainedLdapAuthenticationDuplicate() throws Exception { public void testChainedLdapExists() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u2.search", "(uid={0})") - .put("users.u2.base", "ou=people2,o=TEST").build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); final LDAPAuthenticationBackend lbe = new LDAPAuthenticationBackend(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -809,17 +949,19 @@ public void testChainedLdapExists() throws Exception { public void testChainedLdapAuthorization() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.base", "ou=groups,o=TEST") - .put("roles.g1.search", "(uniqueMember={0})") - .put("roles.g2.base", "ou=groups2,o=TEST") - .put("roles.g2.search", "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.base", "ou=groups,o=TEST") + .put("roles.g1.search", "(uniqueMember={0})") + .put("roles.g2.base", "ou=groups2,o=TEST") + .put("roles.g2.search", "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -838,17 +980,19 @@ public void testChainedLdapAuthorization() throws Exception { public void testCrossChainedLdapAuthorization() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people2,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.base", "ou=groups,o=TEST") - .put("roles.g1.search", "(uniqueMember={0})") - .put("roles.g2.base", "ou=groups2,o=TEST") - .put("roles.g2.search", "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people2,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.base", "ou=groups,o=TEST") + .put("roles.g1.search", "(uniqueMember={0})") + .put("roles.g2.base", "ou=groups2,o=TEST") + .put("roles.g2.search", "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null) - .authenticate(new AuthCredentials("mercuryf", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("mercuryf", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); diff --git a/src/test/java/com/amazon/dlic/auth/ldap/UtilsTest.java b/src/test/java/com/amazon/dlic/auth/ldap/UtilsTest.java index cbfa40f850..ce22bf6036 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/UtilsTest.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/UtilsTest.java @@ -19,39 +19,38 @@ public class UtilsTest { - @Test public void testLDAPName() throws Exception { - //same ldapname - Assert.assertEquals(new LdapName("CN=1,OU=2,O=3,C=4"),new LdapName("CN=1,OU=2,O=3,C=4")); + // same ldapname + Assert.assertEquals(new LdapName("CN=1,OU=2,O=3,C=4"), new LdapName("CN=1,OU=2,O=3,C=4")); - //case differ - Assert.assertEquals(new LdapName("CN=1,OU=2,O=3,C=4".toLowerCase()),new LdapName("CN=1,OU=2,O=3,C=4".toUpperCase())); + // case differ + Assert.assertEquals(new LdapName("CN=1,OU=2,O=3,C=4".toLowerCase()), new LdapName("CN=1,OU=2,O=3,C=4".toUpperCase())); - //case differ - Assert.assertEquals(new LdapName("CN=abc,OU=xyz,O=3,C=4".toLowerCase()),new LdapName("CN=abc,OU=xyz,O=3,C=4".toUpperCase())); + // case differ + Assert.assertEquals(new LdapName("CN=abc,OU=xyz,O=3,C=4".toLowerCase()), new LdapName("CN=abc,OU=xyz,O=3,C=4".toUpperCase())); - //same ldapname - Assert.assertEquals(new LdapName("CN=a,OU=2,O=3,C=xxx"),new LdapName("CN=A,OU=2,O=3,C=XxX")); + // same ldapname + Assert.assertEquals(new LdapName("CN=a,OU=2,O=3,C=xxx"), new LdapName("CN=A,OU=2,O=3,C=XxX")); - //case differ and spaces - Assert.assertEquals(new LdapName("Cn =1 ,OU=2, O = 3,C=4"),new LdapName("CN= 1,Ou=2,O=3,c=4")); + // case differ and spaces + Assert.assertEquals(new LdapName("Cn =1 ,OU=2, O = 3,C=4"), new LdapName("CN= 1,Ou=2,O=3,c=4")); - //same components, different order - Assert.assertNotEquals(new LdapName("CN=1,OU=2,C=4,O=3"),new LdapName("CN=1,OU=2,O=3,C=4")); + // same components, different order + Assert.assertNotEquals(new LdapName("CN=1,OU=2,C=4,O=3"), new LdapName("CN=1,OU=2,O=3,C=4")); - //last component missing - Assert.assertNotEquals(new LdapName("CN=1,OU=2,O=3"),new LdapName("CN=1,OU=2,O=3,C=4")); + // last component missing + Assert.assertNotEquals(new LdapName("CN=1,OU=2,O=3"), new LdapName("CN=1,OU=2,O=3,C=4")); - //first component missing - Assert.assertNotEquals(new LdapName("OU=2,O=3,C=4"),new LdapName("CN=1,OU=2,O=3,C=4")); + // first component missing + Assert.assertNotEquals(new LdapName("OU=2,O=3,C=4"), new LdapName("CN=1,OU=2,O=3,C=4")); - //parse exception + // parse exception try { new LdapName("OU2,O=3,C=4"); Assert.fail(); } catch (InvalidNameException e) { - //expected + // expected } } } diff --git a/src/test/java/com/amazon/dlic/auth/ldap/srv/EmbeddedLDAPServer.java b/src/test/java/com/amazon/dlic/auth/ldap/srv/EmbeddedLDAPServer.java index 2dd3fc8284..b56f432e6e 100755 --- a/src/test/java/com/amazon/dlic/auth/ldap/srv/EmbeddedLDAPServer.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/srv/EmbeddedLDAPServer.java @@ -11,7 +11,6 @@ package com.amazon.dlic.auth.ldap.srv; - public class EmbeddedLDAPServer { LdapServer s = new LdapServer(); diff --git a/src/test/java/com/amazon/dlic/auth/ldap/srv/LdapServer.java b/src/test/java/com/amazon/dlic/auth/ldap/srv/LdapServer.java index 3ce93e8761..bb7738d3fd 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap/srv/LdapServer.java +++ b/src/test/java/com/amazon/dlic/auth/ldap/srv/LdapServer.java @@ -49,11 +49,13 @@ final class LdapServer { private static final int LOCK_TIMEOUT = 60; private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS; - private static final String LOCK_TIMEOUT_MSG = "Unable to obtain lock due to timeout after " + LOCK_TIMEOUT + " " + TIME_UNIT.toString(); + private static final String LOCK_TIMEOUT_MSG = "Unable to obtain lock due to timeout after " + + LOCK_TIMEOUT + + " " + + TIME_UNIT.toString(); private static final String SERVER_NOT_STARTED = "The LDAP server is not started."; private static final String SERVER_ALREADY_STARTED = "The LDAP server is already started."; - private InMemoryDirectoryServer server; private final AtomicBoolean isStarted = new AtomicBoolean(Boolean.FALSE); private final ReentrantLock serverStateLock = new ReentrantLock(); @@ -61,9 +63,7 @@ final class LdapServer { private int ldapPort = -1; private int ldapsPort = -1; - - public LdapServer() { - } + public LdapServer() {} public boolean isStarted() { return this.isStarted.get(); @@ -77,7 +77,7 @@ public int getLdapsPort() { return ldapsPort; } - public int start(String... ldifFiles) throws Exception { + public int start(String... ldifFiles) throws Exception { boolean hasLock = false; try { hasLock = serverStateLock.tryLock(LdapServer.LOCK_TIMEOUT, LdapServer.TIME_UNIT); @@ -89,7 +89,7 @@ public int start(String... ldifFiles) throws Exception { throw new IllegalStateException(LdapServer.LOCK_TIMEOUT_MSG); } } catch (InterruptedException ioe) { - //lock interrupted + // lock interrupted LOG.error(ioe.getMessage(), ioe); } finally { if (hasLock) { @@ -112,8 +112,10 @@ private Collection getInMemoryListenerConfigs() throws E String serverKeyStorePath = FileHelper.getAbsoluteFilePathFromClassPath("ldap/node-0-keystore.jks").toFile().getAbsolutePath(); final SSLUtil serverSSLUtil = new SSLUtil( - new KeyStoreKeyManager(serverKeyStorePath, "changeit".toCharArray()), new TrustStoreTrustManager(serverKeyStorePath)); - //final SSLUtil clientSSLUtil = new SSLUtil(new TrustStoreTrustManager(serverKeyStorePath)); + new KeyStoreKeyManager(serverKeyStorePath, "changeit".toCharArray()), + new TrustStoreTrustManager(serverKeyStorePath) + ); + // final SSLUtil clientSSLUtil = new SSLUtil(new TrustStoreTrustManager(serverKeyStorePath)); ldapPort = SocketUtils.findAvailableTcpPort(); ldapsPort = SocketUtils.findAvailableTcpPort(); @@ -127,11 +129,10 @@ private Collection getInMemoryListenerConfigs() throws E private final String loadFile(final String file) throws IOException { String ldif; - try (final Reader reader = new InputStreamReader(this.getClass().getResourceAsStream("/ldap/" + file),StandardCharsets.UTF_8)) { + try (final Reader reader = new InputStreamReader(this.getClass().getResourceAsStream("/ldap/" + file), StandardCharsets.UTF_8)) { ldif = CharStreams.toString(reader); } - ldif = ldif.replace("${hostname}", "localhost"); ldif = ldif.replace("${port}", String.valueOf(ldapPort)); return ldif; @@ -146,14 +147,14 @@ private synchronized int configureAndStartServer(String... ldifFiles) throws Exc final String rootObjectDN = "o=TEST"; InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(new DN(rootObjectDN)); - config.setSchema(schema); //schema can be set on the rootDN too, per javadoc. + config.setSchema(schema); // schema can be set on the rootDN too, per javadoc. config.setListenerConfigs(listenerConfigs); config.setEnforceAttributeSyntaxCompliance(false); config.setEnforceSingleStructuralObjectClass(false); - //config.setLDAPDebugLogHandler(DEBUG_HANDLER); - //config.setAccessLogHandler(DEBUG_HANDLER); - //config.addAdditionalBindCredentials(configuration.getBindDn(), configuration.getPassword()); + // config.setLDAPDebugLogHandler(DEBUG_HANDLER); + // config.setAccessLogHandler(DEBUG_HANDLER); + // config.addAdditionalBindCredentials(configuration.getBindDn(), configuration.getPassword()); server = new InMemoryDirectoryServer(config); @@ -185,7 +186,7 @@ public void stop() { throw new IllegalStateException(LdapServer.LOCK_TIMEOUT_MSG); } } catch (InterruptedException ioe) { - //lock interrupted + // lock interrupted LOG.debug(ExceptionUtils.getStackTrace(ioe)); } finally { if (hasLock) { @@ -198,13 +199,13 @@ private int loadLdifFiles(String... ldifFiles) throws Exception { int ldifLoadCount = 0; for (String ldif : ldifFiles) { ldifLoadCount++; - try (LDIFReader r = new LDIFReader(new BufferedReader(new StringReader(loadFile(ldif))))){ + try (LDIFReader r = new LDIFReader(new BufferedReader(new StringReader(loadFile(ldif))))) { Entry entry = null; while ((entry = r.readEntry()) != null) { server.add(entry); ldifLoadCount++; } - } catch(Exception e) { + } catch (Exception e) { LOG.error(e.toString(), e); throw e; } diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java index 0ce9d0c857..e88491e994 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendIntegTest2.java @@ -74,13 +74,19 @@ public void testAttributesWithImpersonation() throws Exception { String securityConfigAsYamlString = FileHelper.loadFile("ldap/config_ldap2.yml"); securityConfigAsYamlString = securityConfigAsYamlString.replace("${ldapsPort}", String.valueOf(ldapsPort)); final Settings settings = Settings.builder() - .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".cn=Captain Spock,ou=people,o=TEST", "*") - .build(); + .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS + ".cn=Captain Spock,ou=people,o=TEST", "*") + .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfigAsYamlString(securityConfigAsYamlString), settings); final RestHelper rh = nonSslRestHelper(); HttpResponse res; - Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "jacksonm") - ,encodeBasicHeader("spock", "spocksecret"))).getStatusCode()); + Assert.assertEquals( + HttpStatus.SC_OK, + (res = rh.executeGetRequest( + "_opendistro/_security/authinfo", + new BasicHeader("opendistro_security_impersonate_as", "jacksonm"), + encodeBasicHeader("spock", "spocksecret") + )).getStatusCode() + ); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("ldap.dn")); Assert.assertTrue(res.getBody().contains("attr.ldap.entryDN")); @@ -88,7 +94,6 @@ public void testAttributesWithImpersonation() throws Exception { } - @AfterClass public static void tearDownLdap() throws Exception { diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java index ac8aca7d15..6ba7a84b4a 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestClientCert2.java @@ -39,109 +39,127 @@ public class LdapBackendTestClientCert2 { @Test public void testNoAuth() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); @SuppressWarnings("unused") LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("authentication required")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("authentication required") + ); } } @Test public void testNoAuthX() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); @SuppressWarnings("unused") LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("authentication required")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("authentication required") + ); } } @Test public void testNoAuthY() throws Exception { - //no auth + // no auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/wrong/truststore.jks") - .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/wrong/truststore.jks" + ) + .put(ConfigConstants.LDAPS_VERIFY_HOSTNAMES, false) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); @SuppressWarnings("unused") LdapUser user; try { - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail(); } catch (Exception e) { - Assert.assertTrue(ExceptionUtils.getRootCause(e).getMessage(), ExceptionUtils.getRootCause(e).getMessage().contains("Unable to connect to any")); + Assert.assertTrue( + ExceptionUtils.getRootCause(e).getMessage(), + ExceptionUtils.getRootCause(e).getMessage().contains("Unable to connect to any") + ); } } - - - @Test public void testBindDnAuthLocalhost() throws Exception { - //bin dn auth + // bin dn auth final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -150,21 +168,27 @@ public void testBindDnAuthLocalhost() throws Exception { public void testLdapSslAuth() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "spock") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + "plugins.security.ssl.transport.keystore_filepath", + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock-keystore.jks" + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "spock") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -173,24 +197,30 @@ public void testLdapSslAuth() throws Exception { public void testLdapSslAuthPem() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/ca/root-ca.pem") - .put(ConfigConstants.LDAPS_PEMCERT_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.crtfull.pem") - .put(ConfigConstants.LDAPS_PEMKEY_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.key.pem") - //.put(ConfigConstants.LDAPS_PEMKEY_PASSWORD, "changeit") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - //.put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/ca/root-ca.pem" + ) + .put( + ConfigConstants.LDAPS_PEMCERT_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.crtfull.pem" + ) + .put(ConfigConstants.LDAPS_PEMKEY_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/spock.key.pem") + // .put(ConfigConstants.LDAPS_PEMKEY_PASSWORD, "changeit") + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + // .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } @@ -199,59 +229,66 @@ public void testLdapSslAuthPem() throws Exception { public void testLdapSslAuthNo() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/kirk-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "kirk") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + "plugins.security.ssl.transport.keystore_filepath", + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/kirk-keystore.jks" + ) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "kirk") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } - public void testLdapAuthenticationSSL() throws Exception { - //startLDAPServer(); + // startLDAPServer(); final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_SSL, true) - //.put("plugins.security.ssl.transport.keystore_filepath", "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/cn=ldapbinder,ou=people,dc=example,dc=com-keystore.jks") - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks") - //.put("verify_hostnames", false) - //.put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) - //.put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "cn=ldapbinder,ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") - //.put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") - //.put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") - - //.putList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, "TLS_RSA_WITH_AES_128_CBC_SHA") - //.putList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, "TLSv1") - //TLS_RSA_AES_128_CBC_SHA1 - .put("path.home",".") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("ldap_hr_employee" - , "ldap_hr_employee" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "kdc.dummy.com:636") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + // .put("plugins.security.ssl.transport.keystore_filepath", + // "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/cn=ldapbinder,ou=people,dc=example,dc=com-keystore.jks") + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + "/Users/temp/opendistro_security_integration_tests/ldap/ssl-root-ca/truststore.jks" + ) + // .put("verify_hostnames", false) + // .put(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH, true) + // .put(ConfigConstants.LDAPS_JKS_CERT_ALIAS, "cn=ldapbinder,ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,dc=example,dc=com") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + // .put(ConfigConstants.LDAP_BIND_DN, "cn=ldapbinder,ou=people,dc=example,dc=com") + // .put(ConfigConstants.LDAP_PASSWORD, "ldapbinder") + + // .putList(ConfigConstants.LDAPS_ENABLED_SSL_CIPHERS, "TLS_RSA_WITH_AES_128_CBC_SHA") + // .putList(ConfigConstants.LDAPS_ENABLED_SSL_PROTOCOLS, "TLSv1") + // TLS_RSA_AES_128_CBC_SHA1 + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ldap_hr_employee", "ldap_hr_employee".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("ldap_hr_employee", user.getName()); } - - public static File getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) { File file = null; final URL fileUrl = LdapBackendTestClientCert2.class.getClassLoader().getResource(fileNameFromClasspath); diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java index dfa3296a25..a53e73772d 100644 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestNewStyleConfig2.java @@ -62,7 +62,7 @@ public class LdapBackendTestNewStyleConfig2 { public static void startLdapServer() throws Exception { ldapServer = new EmbeddedLDAPServer(); ldapServer.start(); - ldapServer.applyLdif("base.ldif","base2.ldif"); + ldapServer.applyLdif("base.ldif", "base2.ldif"); ldapPort = ldapServer.getLdapPort(); ldapsPort = ldapServer.getLdapsPort(); } @@ -86,12 +86,13 @@ protected Settings.Builder createBaseSettings() { @Test public void testLdapAuthentication() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -99,39 +100,44 @@ public void testLdapAuthentication() throws Exception { @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFakeLogin() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true) + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapInjection() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); String injectString = "*jack*"; @SuppressWarnings("unused") - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationBindDn() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "spocksecret").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "spocksecret") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -140,14 +146,16 @@ public void testLdapAuthenticationBindDn() throws Exception { public void testLdapAuthenticationWrongBindDn() throws Exception { try { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "wrong").build(); - - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "wrong") + .build(); + + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected exception"); } catch (Exception e) { Assert.assertTrue(ExceptionUtils.getStackTrace(e), ExceptionUtils.getStackTrace(e).contains("password was incorrect")); @@ -157,48 +165,56 @@ public void testLdapAuthenticationWrongBindDn() throws Exception { @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationBindFail() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationNoUser() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFail() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationSSL() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -206,15 +222,20 @@ public void testLdapAuthenticationSSL() throws Exception { @Test public void testLdapAuthenticationSSLPEMFile() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName()) - .put("verify_hostnames", false).put("path.home", ".") - .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, Paths.get("src/test/resources/ldap")) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName() + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()) + .build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, Paths.get("src/test/resources/ldap")).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -222,18 +243,13 @@ public void testLdapAuthenticationSSLPEMFile() throws Exception { @Test public void testLdapAuthenticationSSLPEMText() throws Exception { - final Settings settingsFromFile = Settings - .builder() - .loadFromPath( - Paths - .get(FileHelper - .getAbsoluteFilePathFromClassPath("ldap/test1.yml") - .toFile() - .getAbsolutePath())) - .build(); - Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:"+ldapsPort).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settingsFromFile = Settings.builder() + .loadFromPath(Paths.get(FileHelper.getAbsoluteFilePathFromClassPath("ldap/test1.yml").toFile().getAbsolutePath())) + .build(); + Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:" + ldapsPort).build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -241,16 +257,22 @@ public void testLdapAuthenticationSSLPEMText() throws Exception { @Test public void testLdapAuthenticationSSLSSLv3() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "SSLv3").put("path.home", ".").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "SSLv3") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected Exception"); } catch (Exception e) { Assert.assertEquals(org.ldaptive.provider.ConnectionException.class, e.getCause().getClass()); @@ -262,20 +284,29 @@ public void testLdapAuthenticationSSLSSLv3() throws Exception { @Test public void testLdapAuthenticationSSLUnknownCipher() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_ciphers", "AAA").put("path.home", ".").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_ciphers", "AAA") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected Exception"); } catch (Exception e) { Assert.assertEquals(org.ldaptive.provider.ConnectionException.class, e.getCause().getClass()); - Assert.assertTrue(ExceptionUtils.getStackTrace(e), WildcardMatcher.from("*unsupported*ciphersuite*aaa*").test(ExceptionUtils.getStackTrace(e).toLowerCase())); + Assert.assertTrue( + ExceptionUtils.getStackTrace(e), + WildcardMatcher.from("*unsupported*ciphersuite*aaa*").test(ExceptionUtils.getStackTrace(e).toLowerCase()) + ); } } @@ -283,16 +314,22 @@ public void testLdapAuthenticationSSLUnknownCipher() throws Exception { @Test public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "TLSv1.2") - .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA").put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "TLSv1.2") + .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); @@ -301,15 +338,20 @@ public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { @Test public void testLdapAuthenticationSSLNoKeystore() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -317,13 +359,15 @@ public void testLdapAuthenticationSSLNoKeystore() throws Exception { @Test public void testLdapAuthenticationSSLFailPlain() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .build(); try { - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected exception"); } catch (final Exception e) { Assert.assertEquals(IllegalStateException.class, e.getCause().getClass()); @@ -333,9 +377,9 @@ public void testLdapAuthenticationSSLFailPlain() throws Exception { @Test public void testLdapExists() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); final LDAPAuthenticationBackend2 lbe = new LDAPAuthenticationBackend2(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -345,17 +389,19 @@ public void testLdapExists() throws Exception { @Test public void testLdapAuthorization() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - // .put("plugins.security.authentication.authorization.ldap.userrolename", - // "(uniqueMember={0})") - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + // .put("plugins.security.authentication.authorization.ldap.userrolename", + // "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -369,16 +415,18 @@ public void testLdapAuthorization() throws Exception { @Test public void testLdapAuthorizationReturnAttributes() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, "mail", "cn", "uid") - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_RETURN_ATTRIBUTES, "mail", "cn", "uid") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend2(settings, null).fillRoles(user, null); @@ -394,12 +442,11 @@ public void testLdapAuthorizationReturnAttributes() throws Exception { @Test public void testLdapAuthenticationReferral() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - final Connection con = new LDAPConnectionFactoryFactory(settings, null).createBasicConnectionFactory() - .getConnection(); + final Connection con = new LDAPConnectionFactoryFactory(settings, null).createBasicConnectionFactory().getConnection(); try { con.open(); final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), true); @@ -413,17 +460,21 @@ public void testLdapAuthenticationReferral() throws Exception { @Test public void testLdapDontFollowReferrals() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.FOLLOW_REFERRALS, false).build(); - + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.FOLLOW_REFERRALS, false) + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { - //If following is off then should fail to return the result provided by following - final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT)); + // If following is off then should fail to return the result provided by following + final LdapEntry ref1 = LdapHelper.lookup( + con, + "cn=Ref1,ou=people,o=TEST", + ReturnAttributes.ALL.value(), + settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT) + ); Assert.assertNull(ref1); } finally { con.close(); @@ -433,16 +484,19 @@ public void testLdapDontFollowReferrals() throws Exception { @Test public void testLdapEscape() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Special\\, Sign,ou=people,o=TEST", user.getName()); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -454,14 +508,17 @@ public void testLdapEscape() throws Exception { @Test public void testLdapAuthorizationRoleSearchUsername() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(cn={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember=cn={1},ou=people,o=TEST)").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(cn={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember=cn={1},ou=people,o=TEST)") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -476,11 +533,13 @@ public void testLdapAuthorizationRoleSearchUsername() throws Exception { @Test public void testLdapAuthorizationOnly() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -495,12 +554,14 @@ public void testLdapAuthorizationOnly() throws Exception { @Test public void testLdapAuthorizationNested() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -515,12 +576,15 @@ public void testLdapAuthorizationNested() throws Exception { @Test public void testLdapAuthorizationNestedFilter() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST") + .build(); final User user = new User("spock"); @@ -536,12 +600,14 @@ public void testLdapAuthorizationNestedFilter() throws Exception { @Test public void testLdapAuthorizationDnNested() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -556,16 +622,17 @@ public void testLdapAuthorizationDnNested() throws Exception { @Test public void testLdapAuthorizationDn() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) - .put("roles.g1.search", "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + .put("roles.g1.search", "(uniqueMember={0})") + .build(); - final User user = new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); + final User user = new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -578,13 +645,15 @@ public void testLdapAuthorizationDn() throws Exception { @Test public void testLdapAuthenticationUserNameAttribute() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.base", "ou=people,o=TEST").put("users.u1.search", "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("jacksonm", user.getName()); } @@ -592,15 +661,20 @@ public void testLdapAuthenticationUserNameAttribute() throws Exception { @Test public void testLdapAuthenticationStartTLS() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -608,15 +682,18 @@ public void testLdapAuthenticationStartTLS() throws Exception { @Test public void testLdapAuthorizationSkipUsers() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put("roles.g1.search", "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.search", "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -629,13 +706,16 @@ public void testLdapAuthorizationSkipUsers() throws Exception { @Test public void testLdapAuthorizationNestedAttr() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -651,14 +731,17 @@ public void testLdapAuthorizationNestedAttr() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilter() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*") + .build(); final User user = new User("spock"); @@ -675,14 +758,17 @@ public void testLdapAuthorizationNestedAttrFilter() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") + .build(); final User user = new User("spock"); @@ -697,16 +783,18 @@ public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like - // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, - // "*") - .put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like + // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, + // "*") + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -721,13 +809,16 @@ public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws E @Test public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "unused").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(((unused") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "unused") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(((unused") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false) + .build(); final User user = new User("spock"); @@ -743,34 +834,40 @@ public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { @Test public void testCustomAttributes() throws Exception { - Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").build(); + Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .build(); - LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); Assert.assertEquals(user.getCustomAttributesMap().toString(), 16, user.getCustomAttributesMap().size()); - Assert.assertFalse(user.getCustomAttributesMap().toString(), - user.getCustomAttributesMap().keySet().contains("attr.ldap.userpassword")); + Assert.assertFalse( + user.getCustomAttributesMap().toString(), + user.getCustomAttributesMap().keySet().contains("attr.ldap.userpassword") + ); - settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0).build(); + settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0) + .build(); - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); - settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})") - .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId").build(); + settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId") + .build(); - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); @@ -779,13 +876,16 @@ public void testCustomAttributes() throws Exception { @Test public void testLdapAuthorizationNonDNRoles() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("roles.g1.base", "ou=groups,o=TEST").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).put("roles.g1.search", "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("roles.g1.base", "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put("roles.g1.search", "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("nondnroles"); @@ -795,24 +895,28 @@ public void testLdapAuthorizationNonDNRoles() throws Exception { Assert.assertEquals("nondnroles", user.getName()); Assert.assertEquals(5, user.getRoles().size()); Assert.assertTrue("Roles do not contain non-LDAP role 'kibanauser'", user.getRoles().contains("kibanauser")); - Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", - user.getRoles().contains("humanresources")); + Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", user.getRoles().contains("humanresources")); Assert.assertTrue("Roles do not contain LDAP role 'dummyempty'", user.getRoles().contains("dummyempty")); Assert.assertTrue("Roles do not contain non-LDAP role 'role2'", user.getRoles().contains("role2")); - Assert.assertTrue("Roles do not contain non-LDAP role 'anotherrole' from second role name", - user.getRoles().contains("anotherrole")); + Assert.assertTrue( + "Roles do not contain non-LDAP role 'anotherrole' from second role name", + user.getRoles().contains("anotherrole") + ); } @Test public void testChainedLdapAuthentication1() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("users.u2.search", "(uid={0})").put("users.u2.base", "ou=people2,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -820,13 +924,16 @@ public void testChainedLdapAuthentication1() throws Exception { @Test public void testChainedLdapAuthentication2() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put("users.u2.search", "(uid={0})").put("users.u2.base", "ou=people2,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("presleye", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("presleye", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Elvis Presley,ou=people2,o=TEST", user.getName()); } @@ -834,14 +941,17 @@ public void testChainedLdapAuthentication2() throws Exception { @Test(expected = OpenSearchSecurityException.class) public void testChainedLdapAuthenticationDuplicate() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_SEARCH_ALL_BASES, true).put("users.u1.search", "(uid={0})") - .put("users.u1.base", "ou=people,o=TEST").put("users.u2.search", "(uid={0})") - .put("users.u2.base", "ou=people2,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_SEARCH_ALL_BASES, true) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); // Fails with OpenSearchSecurityException because two possible instances are // found @@ -850,10 +960,11 @@ public void testChainedLdapAuthenticationDuplicate() throws Exception { @Test public void testChainedLdapExists() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u2.search", "(uid={0})") - .put("users.u2.base", "ou=people2,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u2.search", "(uid={0})") + .put("users.u2.base", "ou=people2,o=TEST") + .build(); final LDAPAuthenticationBackend2 lbe = new LDAPAuthenticationBackend2(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -864,15 +975,19 @@ public void testChainedLdapExists() throws Exception { @Test public void testChainedLdapAuthorization() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn").put("roles.g1.base", "ou=groups,o=TEST") - .put("roles.g1.search", "(uniqueMember={0})").put("roles.g2.base", "ou=groups2,o=TEST") - .put("roles.g2.search", "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.base", "ou=groups,o=TEST") + .put("roles.g1.search", "(uniqueMember={0})") + .put("roles.g2.base", "ou=groups2,o=TEST") + .put("roles.g2.search", "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -890,15 +1005,19 @@ public void testChainedLdapAuthorization() throws Exception { @Test public void testCrossChainedLdapAuthorization() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put("users.u1.search", "(uid={0})").put("users.u1.base", "ou=people2,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn").put("roles.g1.base", "ou=groups,o=TEST") - .put("roles.g1.search", "(uniqueMember={0})").put("roles.g2.base", "ou=groups2,o=TEST") - .put("roles.g2.search", "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put("users.u1.search", "(uid={0})") + .put("users.u1.base", "ou=people2,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put("roles.g1.base", "ou=groups,o=TEST") + .put("roles.g1.search", "(uniqueMember={0})") + .put("roles.g2.base", "ou=groups2,o=TEST") + .put("roles.g2.search", "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("mercuryf", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("mercuryf", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -914,13 +1033,13 @@ public void testCrossChainedLdapAuthorization() throws Exception { public void testLdapAuthorizationNonDNEntry() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -936,17 +1055,18 @@ public void testLdapAuthorizationNonDNEntry() throws Exception { public void testLdapSpecial186() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -962,12 +1082,18 @@ public void testLdapSpecial186() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); @@ -977,17 +1103,18 @@ public void testLdapSpecial186() throws Exception { public void testLdapSpecial186_2() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -1003,13 +1130,18 @@ public void testLdapSpecial186_2() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); @@ -1018,13 +1150,14 @@ public void testLdapSpecial186_2() throws Exception { @Test public void testOperationalAttributes() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); LdapAttribute operationAttribute = user.getUserEntry().getAttribute("entryUUID"); Assert.assertNotNull(operationAttribute); diff --git a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java index 8a4afee5da..8c6f4dc85d 100755 --- a/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java +++ b/src/test/java/com/amazon/dlic/auth/ldap2/LdapBackendTestOldStyleConfig2.java @@ -88,12 +88,13 @@ protected Settings.Builder createBaseSettings() { @Test public void testLdapAuthentication() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -101,13 +102,14 @@ public void testLdapAuthentication() throws Exception { @Test public void testLdapAuthenticationPooled() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAP_POOL_ENABLED, true) - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_POOL_ENABLED, true) + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -115,41 +117,44 @@ public void testLdapAuthenticationPooled() throws Exception { @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFakeLogin() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_FAKE_LOGIN_ENABLED, true) + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("unknown", "unknown".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapInjection() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); String injectString = "*jack*"; @SuppressWarnings("unused") - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials(injectString, "secret".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationBindDn() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "spocksecret").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "spocksecret") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -157,15 +162,16 @@ public void testLdapAuthenticationBindDn() throws Exception { @Test public void testLdapAuthenticationWrongBindDn() throws Exception { try { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") - .put(ConfigConstants.LDAP_PASSWORD, "wrong").build(); - - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_BIND_DN, "cn=Captain Spock,ou=people,o=TEST") + .put(ConfigConstants.LDAP_PASSWORD, "wrong") + .build(); + + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected exception"); } catch (Exception e) { Assert.assertTrue(ExceptionUtils.getStackTrace(e), ExceptionUtils.getStackTrace(e).contains("password was incorrect")); @@ -175,60 +181,69 @@ public void testLdapAuthenticationWrongBindDn() throws Exception { @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationBindFail() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "wrong".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationNoUser() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("UNKNOWN", "UNKNOWN".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFail() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8)) + ); } @Test(expected = OpenSearchSecurityException.class) public void testLdapAuthenticationFailPooled() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAP_POOL_ENABLED, true) - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_POOL_ENABLED, true) + .build(); - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "xxxxx".getBytes(StandardCharsets.UTF_8)) + ); } @Test public void testLdapAuthenticationSSL() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -236,16 +251,21 @@ public void testLdapAuthenticationSSL() throws Exception { @Test public void testLdapAuthenticationSSLPooled() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAP_POOL_ENABLED, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put(ConfigConstants.LDAP_POOL_ENABLED, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -253,15 +273,20 @@ public void testLdapAuthenticationSSLPooled() throws Exception { @Test public void testLdapAuthenticationSSLPEMFile() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName()) - .put("verify_hostnames", false).put("path.home", ".") - .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, Paths.get("src/test/resources/ldap")) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + ConfigConstants.LDAPS_PEMTRUSTEDCAS_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").toFile().getName() + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .put("path.conf", FileHelper.getAbsoluteFilePathFromClassPath("ldap/root-ca.pem").getParent()) + .build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, Paths.get("src/test/resources/ldap")).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -269,18 +294,13 @@ public void testLdapAuthenticationSSLPEMFile() throws Exception { @Test public void testLdapAuthenticationSSLPEMText() throws Exception { - final Settings settingsFromFile = Settings - .builder() - .loadFromPath( - Paths - .get(FileHelper - .getAbsoluteFilePathFromClassPath("ldap/test1.yml") - .toFile() - .getAbsolutePath())) - .build(); - Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:"+ldapsPort).build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settingsFromFile = Settings.builder() + .loadFromPath(Paths.get(FileHelper.getAbsoluteFilePathFromClassPath("ldap/test1.yml").toFile().getAbsolutePath())) + .build(); + Settings settings = Settings.builder().put(settingsFromFile).putList("hosts", "localhost:" + ldapsPort).build(); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -288,16 +308,22 @@ public void testLdapAuthenticationSSLPEMText() throws Exception { @Test public void testLdapAuthenticationSSLSSLv3() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "SSLv3").put("path.home", ".").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "SSLv3") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected Exception"); } catch (Exception e) { Assert.assertEquals(org.ldaptive.provider.ConnectionException.class, e.getCause().getClass()); @@ -309,20 +335,30 @@ public void testLdapAuthenticationSSLSSLv3() throws Exception { @Test public void testLdapAuthenticationSSLUnknowCipher() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_ciphers", "AAA").put("path.home", ".").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_ciphers", "AAA") + .put("path.home", ".") + .build(); try { - new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected Exception"); } catch (Exception e) { - Assert.assertEquals(e.getCause().getClass().toString(), org.ldaptive.provider.ConnectionException.class, e.getCause().getClass()); - Assert.assertTrue(ExceptionUtils.getStackTrace(e), EXCEPTION_MATCHER.test( ExceptionUtils.getStackTrace(e).toLowerCase())); + Assert.assertEquals( + e.getCause().getClass().toString(), + org.ldaptive.provider.ConnectionException.class, + e.getCause().getClass() + ); + Assert.assertTrue(ExceptionUtils.getStackTrace(e), EXCEPTION_MATCHER.test(ExceptionUtils.getStackTrace(e).toLowerCase())); } } @@ -330,16 +366,22 @@ public void testLdapAuthenticationSSLUnknowCipher() throws Exception { @Test public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).putList("enabled_ssl_protocols", "TLSv1.2") - .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA").put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .putList("enabled_ssl_protocols", "TLSv1.2") + .putList("enabled_ssl_ciphers", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA") + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); @@ -348,15 +390,20 @@ public void testLdapAuthenticationSpecialCipherProtocol() throws Exception { @Test public void testLdapAuthenticationSSLNoKeystore() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapsPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -364,14 +411,15 @@ public void testLdapAuthenticationSSLNoKeystore() throws Exception { @Test public void testLdapAuthenticationSSLFailPlain() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").put(ConfigConstants.LDAPS_ENABLE_SSL, true) - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_SSL, true) + .build(); try { - new LDAPAuthenticationBackend2(settings, new File("").toPath()) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + new LDAPAuthenticationBackend2(settings, new File("").toPath()).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.fail("Expected exception"); } catch (final Exception e) { Assert.assertEquals(IllegalStateException.class, e.getCause().getClass()); @@ -381,9 +429,9 @@ public void testLdapAuthenticationSSLFailPlain() throws Exception { @Test public void testLdapExists() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); final LDAPAuthenticationBackend2 lbe = new LDAPAuthenticationBackend2(settings, null); Assert.assertTrue(lbe.exists(new User("jacksonm"))); @@ -393,19 +441,19 @@ public void testLdapExists() throws Exception { @Test public void testLdapAuthorization() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - // .put("plugins.security.authentication.authorization.ldap.userrolename", - // "(uniqueMember={0})") - .build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + // .put("plugins.security.authentication.authorization.ldap.userrolename", + // "(uniqueMember={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -419,20 +467,20 @@ public void testLdapAuthorization() throws Exception { @Test public void testLdapAuthorizationPooled() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_POOL_ENABLED, true) - // .put("plugins.security.authentication.authorization.ldap.userrolename", - // "(uniqueMember={0})") - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_POOL_ENABLED, true) + // .put("plugins.security.authentication.authorization.ldap.userrolename", + // "(uniqueMember={0})") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -446,12 +494,11 @@ public void testLdapAuthorizationPooled() throws Exception { @Test public void testLdapAuthenticationReferral() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final Connection con = new LDAPConnectionFactoryFactory(settings, null).createBasicConnectionFactory() - .getConnection(); + final Connection con = new LDAPConnectionFactoryFactory(settings, null).createBasicConnectionFactory().getConnection(); try { con.open(); final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), true); @@ -465,17 +512,21 @@ public void testLdapAuthenticationReferral() throws Exception { @Test public void testLdapDontFollowReferrals() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.FOLLOW_REFERRALS, false).build(); - + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.FOLLOW_REFERRALS, false) + .build(); final Connection con = LDAPAuthorizationBackend.getConnection(settings, null); try { - //If following is off then should fail to return the result provided by following - final LdapEntry ref1 = LdapHelper.lookup(con, "cn=Ref1,ou=people,o=TEST", ReturnAttributes.ALL.value(), settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT)); + // If following is off then should fail to return the result provided by following + final LdapEntry ref1 = LdapHelper.lookup( + con, + "cn=Ref1,ou=people,o=TEST", + ReturnAttributes.ALL.value(), + settings.getAsBoolean(ConfigConstants.FOLLOW_REFERRALS, ConfigConstants.FOLLOW_REFERRALS_DEFAULT) + ); Assert.assertNull(ref1); } finally { con.close(); @@ -485,18 +536,19 @@ public void testLdapDontFollowReferrals() throws Exception { @Test public void testLdapEscape() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true).build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("ssign", "ssignsecret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Special\\, Sign,ou=people,o=TEST", user.getName()); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -508,16 +560,17 @@ public void testLdapEscape() throws Exception { @Test public void testLdapAuthorizationRoleSearchUsername() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(cn={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember=cn={1},ou=people,o=TEST)").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(cn={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember=cn={1},ou=people,o=TEST)") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("Michael Jackson", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -532,13 +585,13 @@ public void testLdapAuthorizationRoleSearchUsername() throws Exception { @Test public void testLdapAuthorizationOnly() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -553,14 +606,14 @@ public void testLdapAuthorizationOnly() throws Exception { @Test public void testLdapAuthorizationNested() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -575,15 +628,15 @@ public void testLdapAuthorizationNested() throws Exception { @Test public void testLdapAuthorizationNestedFilter() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=nested2,ou=groups,o=TEST") + .build(); final User user = new User("spock"); @@ -599,14 +652,14 @@ public void testLdapAuthorizationNestedFilter() throws Exception { @Test public void testLdapAuthorizationDnNested() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("spock"); @@ -621,18 +674,17 @@ public void testLdapAuthorizationDnNested() throws Exception { @Test public void testLdapAuthorizationDn() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "UID") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); - final User user = new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); + final User user = new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("jacksonm", "secret".getBytes())); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -645,14 +697,15 @@ public void testLdapAuthorizationDn() throws Exception { @Test public void testLdapAuthenticationUserNameAttribute() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERNAME_ATTRIBUTE, "uid") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("jacksonm", user.getName()); } @@ -660,16 +713,20 @@ public void testLdapAuthenticationUserNameAttribute() throws Exception { @Test public void testLdapAuthenticationStartTLS() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) - .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, - FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks")) - .put("verify_hostnames", false).put("path.home", ".").build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAPS_ENABLE_START_TLS, true) + .put( + SSLConfigConstants.SECURITY_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, + FileHelper.getAbsoluteFilePathFromClassPath("ldap/truststore.jks") + ) + .put("verify_hostnames", false) + .put("path.home", ".") + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); } @@ -677,17 +734,18 @@ public void testLdapAuthenticationStartTLS() throws Exception { @Test public void testLdapAuthorizationSkipUsers() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .putList(ConfigConstants.LDAP_AUTHZ_SKIP_USERS, "cn=Michael Jackson,ou*people,o=TEST") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); new LDAPAuthorizationBackend(settings, null).fillRoles(user, null); @@ -700,16 +758,16 @@ public void testLdapAuthorizationSkipUsers() throws Exception { @Test public void testLdapAuthorizationNestedAttr() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -725,17 +783,17 @@ public void testLdapAuthorizationNestedAttr() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilter() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "cn=rolemo4*") + .build(); final User user = new User("spock"); @@ -752,17 +810,17 @@ public void testLdapAuthorizationNestedAttrFilter() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) - .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*").build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, "*") + .build(); final User user = new User("spock"); @@ -777,18 +835,18 @@ public void testLdapAuthorizationNestedAttrFilterAll() throws Exception { @Test public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like - // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, - // "*") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, false) // -> same like + // putList(ConfigConstants.LDAP_AUTHZ_NESTEDROLEFILTER, + // "*") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("spock"); @@ -803,15 +861,16 @@ public void testLdapAuthorizationNestedAttrFilterAllEqualsNestedFalse() throws E @Test public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "unused").put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(((unused") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "unused") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(((unused") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, false) + .build(); final User user = new User("spock"); @@ -827,35 +886,37 @@ public void testLdapAuthorizationNestedAttrNoRoleSearch() throws Exception { @Test public void testCustomAttributes() throws Exception { - Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("cn=Michael Jackson,ou=people,o=TEST", user.getName()); Assert.assertEquals(user.getCustomAttributesMap().toString(), 16, user.getCustomAttributesMap().size()); - Assert.assertFalse(user.getCustomAttributesMap().toString(), - user.getCustomAttributesMap().containsKey("attr.ldap.userpassword")); + Assert.assertFalse(user.getCustomAttributesMap().toString(), user.getCustomAttributesMap().containsKey("attr.ldap.userpassword")); - settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0).build(); + settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_CUSTOM_ATTR_MAXVAL_LEN, 0) + .build(); - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); - settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId").build(); + settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "127.0.0.1:4", "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .putList(ConfigConstants.LDAP_CUSTOM_ATTR_WHITELIST, "*objectclass*", "entryParentId") + .build(); - user = (LdapUser) new LDAPAuthenticationBackend2(settings, null) - .authenticate(new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8))); + user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertEquals(user.getCustomAttributesMap().toString(), 2, user.getCustomAttributesMap().size()); @@ -864,16 +925,16 @@ public void testCustomAttributes() throws Exception { @Test public void testLdapAuthorizationNonDNRoles() throws Exception { - final Settings settings = createBaseSettings() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true).build(); + final Settings settings = createBaseSettings().putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "cn") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_USERROLENAME, "description, ou") // no memberOf OID + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH_ENABLED, true) + .build(); final User user = new User("nondnroles"); @@ -883,26 +944,26 @@ public void testLdapAuthorizationNonDNRoles() throws Exception { Assert.assertEquals("nondnroles", user.getName()); Assert.assertEquals(5, user.getRoles().size()); Assert.assertTrue("Roles do not contain non-LDAP role 'kibanauser'", user.getRoles().contains("kibanauser")); - Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", - user.getRoles().contains("humanresources")); + Assert.assertTrue("Roles do not contain non-LDAP role 'humanresources'", user.getRoles().contains("humanresources")); Assert.assertTrue("Roles do not contain LDAP role 'dummyempty'", user.getRoles().contains("dummyempty")); Assert.assertTrue("Roles do not contain non-LDAP role 'role2'", user.getRoles().contains("role2")); - Assert.assertTrue("Roles do not contain non-LDAP role 'anotherrole' from second role name", - user.getRoles().contains("anotherrole")); + Assert.assertTrue( + "Roles do not contain non-LDAP role 'anotherrole' from second role name", + user.getRoles().contains("anotherrole") + ); } - @Test public void testLdapAuthorizationNonDNEntry() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .build(); final User user = new User("jacksonm"); @@ -918,17 +979,18 @@ public void testLdapAuthorizationNonDNEntry() throws Exception { public void testLdapSpecial186() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "description") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -944,12 +1006,18 @@ public void testLdapSpecial186() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLEx(186n) consists of\\, special=")); Assert.assertTrue(user.getRoles().toString().contains("ROLE/(186nn) consists of\\, special=")); @@ -959,17 +1027,18 @@ public void testLdapSpecial186() throws Exception { public void testLdapSpecial186_2() throws Exception { final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") - .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") - .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") - .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") - .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) - .build(); - - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate(new AuthCredentials("spec186", "spec186" - .getBytes(StandardCharsets.UTF_8))); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .put(ConfigConstants.LDAP_AUTHC_USERBASE, "ou=people,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLEBASE, "ou=groups,o=TEST") + .put(ConfigConstants.LDAP_AUTHZ_ROLENAME, "dn") + .put(ConfigConstants.LDAP_AUTHZ_ROLESEARCH, "(uniqueMember={0})") + .put(ConfigConstants.LDAP_AUTHZ_RESOLVE_NESTED_ROLES, true) + .build(); + + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend(settings, null).authenticate( + new AuthCredentials("spec186", "spec186".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); Assert.assertEquals("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST", user.getName()); Assert.assertEquals("AA BB/CC (DD) my, company end=with=whitespace ", user.getUserEntry().getAttribute("cn").getStringValue()); @@ -985,13 +1054,18 @@ public void testLdapSpecial186_2() throws Exception { Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); - new LDAPAuthorizationBackend(settings, null).fillRoles(new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), null); + new LDAPAuthorizationBackend(settings, null).fillRoles( + new User("CN=AA BB\\/CC (DD) my\\, company end\\=with\\=whitespace\\ ,ou=people,o=TEST"), + null + ); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186n) consists of\\, special\\=chars\\ ")); Assert.assertTrue(user.getRoles().toString().contains("cn=ROLE/(186nn) consists of\\, special\\=chars\\ ")); @@ -1000,13 +1074,14 @@ public void testLdapSpecial186_2() throws Exception { @Test public void testOperationalAttributes() throws Exception { - final Settings settings = Settings.builder() - .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) - .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})").build(); + .putList(ConfigConstants.LDAP_HOSTS, "localhost:" + ldapPort) + .put(ConfigConstants.LDAP_AUTHC_USERSEARCH, "(uid={0})") + .build(); - final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate(new AuthCredentials("jacksonm", "secret" - .getBytes(StandardCharsets.UTF_8))); + final LdapUser user = (LdapUser) new LDAPAuthenticationBackend2(settings, null).authenticate( + new AuthCredentials("jacksonm", "secret".getBytes(StandardCharsets.UTF_8)) + ); Assert.assertNotNull(user); LdapAttribute operationAttribute = user.getUserEntry().getAttribute("entryUUID"); Assert.assertNotNull(operationAttribute); @@ -1015,7 +1090,6 @@ public void testOperationalAttributes() throws Exception { Assert.assertTrue(operationAttribute.getStringValue().split("-").length == 5); } - @AfterClass public static void tearDown() throws Exception { diff --git a/src/test/java/org/opensearch/node/PluginAwareNode.java b/src/test/java/org/opensearch/node/PluginAwareNode.java index 39c93e6b8e..35dcd8b699 100644 --- a/src/test/java/org/opensearch/node/PluginAwareNode.java +++ b/src/test/java/org/opensearch/node/PluginAwareNode.java @@ -33,7 +33,7 @@ import org.opensearch.plugins.Plugin; public class PluginAwareNode extends Node { - + private final boolean clusterManagerEligible; @SafeVarargs @@ -41,7 +41,7 @@ public PluginAwareNode(boolean clusterManagerEligible, final Settings preparedSe super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, Collections.emptyMap(), null, () -> System.getenv("HOSTNAME")), Arrays.asList(plugins), true); this.clusterManagerEligible = clusterManagerEligible; } - + public boolean isClusterManagerEligible() { return clusterManagerEligible; diff --git a/src/test/java/org/opensearch/security/AggregationTests.java b/src/test/java/org/opensearch/security/AggregationTests.java index c2feddd6b6..a8a0f94078 100644 --- a/src/test/java/org/opensearch/security/AggregationTests.java +++ b/src/test/java/org/opensearch/security/AggregationTests.java @@ -48,33 +48,33 @@ public class AggregationTests extends SingleClusterTest { public void testBasicAggregations() throws Exception { final Settings settings = Settings.builder() .build(); - + setup(settings); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("xyz").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("xyz").alias("alias1"))).actionGet(); } - + HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); System.out.println(res.getBody()); @@ -88,7 +88,7 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); assertContains(res, "*\"failed\" : 0*"); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("*/_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); System.out.println(res.getBody()); assertNotContains(res, "*xception*"); @@ -101,7 +101,7 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*xyz*"); assertContains(res, "*role01_role02*"); assertContains(res, "*\"failed\" : 0*"); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("worf", "worf"))).getStatusCode()); System.out.println(res.getBody()); assertNotContains(res, "*xception*"); @@ -114,9 +114,9 @@ public void testBasicAggregations() throws Exception { assertContains(res, "*public*"); assertContains(res, "*xyz*"); assertContains(res, "*\"failed\" : 0*"); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("_search?pretty", "{\"size\":0,\"aggs\":{\"myindices\":{\"terms\":{\"field\":\"_index\",\"size\":40}}}}",encodeBasicHeader("worf", "worf"))).getStatusCode()); - + } - + } diff --git a/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java b/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java index 7fdf2d8bfc..a0a1b8bb7b 100644 --- a/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java +++ b/src/test/java/org/opensearch/security/AlwaysFalseInterClusterRequestEvaluator.java @@ -42,12 +42,12 @@ public AlwaysFalseInterClusterRequestEvaluator(Settings settings) { @Override public boolean isInterClusterRequest(TransportRequest request, X509Certificate[] localCerts, X509Certificate[] peerCerts, String principal) { - + if(localCerts == null || peerCerts == null || principal == null || localCerts.length == 0 || peerCerts.length == 0 || principal.length() == 0) { return true; } - + return false; } diff --git a/src/test/java/org/opensearch/security/ConfigTests.java b/src/test/java/org/opensearch/security/ConfigTests.java index c5b8c089e4..3c083ac153 100644 --- a/src/test/java/org/opensearch/security/ConfigTests.java +++ b/src/test/java/org/opensearch/security/ConfigTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security; @@ -46,24 +46,24 @@ import org.opensearch.security.test.SingleClusterTest; public class ConfigTests { - + private static final ObjectMapper YAML = new ObjectMapper(new YAMLFactory()); - + @Test public void testEmptyConfig() throws Exception { Assert.assertTrue(SecurityDynamicConfiguration.empty().deepClone() != SecurityDynamicConfiguration.empty()); } - + @Test public void testMigrate() throws Exception { Tuple, SecurityDynamicConfiguration> rolesResult = Migration.migrateRoles((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles.yml", CType.ROLES), (SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING)); - + System.out.println(Strings.toString(XContentType.JSON, rolesResult.v2(), true, false)); System.out.println(Strings.toString(XContentType.JSON, rolesResult.v1(), true, false)); - - + + SecurityDynamicConfiguration actionGroupsResult = Migration.migrateActionGroups((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/action_groups.yml", CType.ACTIONGROUPS)); System.out.println(Strings.toString(XContentType.JSON, actionGroupsResult, true, false)); SecurityDynamicConfiguration configResult =Migration.migrateConfig((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/config.yml", CType.CONFIG)); @@ -73,29 +73,29 @@ public void testMigrate() throws Exception { SecurityDynamicConfiguration rolemappingsResult = Migration.migrateRoleMappings((SecurityDynamicConfiguration)load("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING)); System.out.println(Strings.toString(XContentType.JSON, rolemappingsResult, true, false)); } - + @Test public void testParseSg67Config() throws Exception { check("./legacy/securityconfig_v6/action_groups.yml", CType.ACTIONGROUPS); check("./action_groups.yml", CType.ACTIONGROUPS); - + check("./legacy/securityconfig_v6/config.yml", CType.CONFIG); check("./config.yml", CType.CONFIG); - + check("./legacy/securityconfig_v6/roles.yml", CType.ROLES); check("./roles.yml", CType.ROLES); - + check("./legacy/securityconfig_v6/internal_users.yml", CType.INTERNALUSERS); check("./internal_users.yml", CType.INTERNALUSERS); - + check("./legacy/securityconfig_v6/roles_mapping.yml", CType.ROLESMAPPING); check("./roles_mapping.yml", CType.ROLESMAPPING); - + check("./tenants.yml", CType.TENANTS); - + } - + private void check(String file, CType cType) throws Exception { final String adjustedFilePath = SingleClusterTest.TEST_RESOURCE_RELATIVE_PATH + file; JsonNode jsonNode = YAML.readTree(FileUtils.readFileToString(new File(adjustedFilePath), "UTF-8")); @@ -108,16 +108,16 @@ private void check(String file, CType cType) throws Exception { System.out.println("%%%%%%%% THIS IS A LINE OF INTEREST: CONFIG VERSION: "+ configVersion + "%%%%%%%"); - + SecurityDynamicConfiguration dc = load(file, cType); Assert.assertNotNull(dc); //Assert.assertTrue(dc.getCEntries().size() > 0); String jsonSerialize = DefaultObjectMapper.objectMapper.writeValueAsString(dc); SecurityDynamicConfiguration conf = SecurityDynamicConfiguration.fromJson(jsonSerialize, cType, configVersion, 0, 0); SecurityDynamicConfiguration.fromJson(Strings.toString(XContentType.JSON, conf), cType, configVersion, 0, 0); - + } - + private SecurityDynamicConfiguration load(String file, CType cType) throws Exception { final String adjustedFilePath = SingleClusterTest.TEST_RESOURCE_RELATIVE_PATH + file; JsonNode jsonNode = YAML.readTree(FileUtils.readFileToString(new File(adjustedFilePath), "UTF-8")); diff --git a/src/test/java/org/opensearch/security/HealthTests.java b/src/test/java/org/opensearch/security/HealthTests.java index 4cba4030e6..0785fd620f 100644 --- a/src/test/java/org/opensearch/security/HealthTests.java +++ b/src/test/java/org/opensearch/security/HealthTests.java @@ -37,11 +37,11 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class HealthTests extends SingleClusterTest { - + @Test public void testHealth() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode()); @@ -49,18 +49,18 @@ public void testHealth() throws Exception { assertContains(res, "*UP*"); assertNotContains(res, "*DOWN*"); assertNotContains(res, "*strict*"); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testHealthUnitialized() throws Exception { setup(Settings.EMPTY, null, Settings.EMPTY, false); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty&mode=lenient")).getStatusCode()); @@ -68,7 +68,7 @@ public void testHealthUnitialized() throws Exception { assertContains(res, "*UP*"); assertNotContains(res, "*DOWN*"); assertNotContains(res, "*strict*"); - + Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*DOWN*"); diff --git a/src/test/java/org/opensearch/security/HttpIntegrationTests.java b/src/test/java/org/opensearch/security/HttpIntegrationTests.java index d9ed9c34df..bf185e0972 100644 --- a/src/test/java/org/opensearch/security/HttpIntegrationTests.java +++ b/src/test/java/org/opensearch/security/HttpIntegrationTests.java @@ -68,9 +68,9 @@ public void testHTTPBasic() throws Exception { .build(); setup(settings); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { - tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); @@ -79,17 +79,17 @@ public void testHTTPBasic() throws Exception { tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("v2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("v3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); } - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_search").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); @@ -108,11 +108,11 @@ public void testHTTPBasic() throws Exception { Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); - + for(int i=0; i< 10; i++) { Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); } - + Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("/theindex","{}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest("/theindex/_doc/1?refresh=true","{\"a\":0}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); //Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); @@ -126,80 +126,80 @@ public void testHTTPBasic() throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_close", null,encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_upgrade", null,encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("/.opendistro_security/_mapping","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/0","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - + HttpResponse resc = rh.executeGetRequest("_cat/indices/public?v",encodeBasicHeader("bug108", "nagilum")); Assert.assertTrue(resc.getBody().contains("green")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01", "user_role01")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("spock", "spock")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("kirk/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - //all + //all Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest(".opendistro_security/_mget","{\"ids\" : [\"0\"]}",encodeBasicHeader("worf", "worf")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - + try (Client tc = getClient()) { tc.index(new IndexRequest(".opendistro_security").id("roles").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("roles", FileHelper.readYamlContent("roles_deny.yml"))).actionGet(); ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"roles"})).actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); - + try (Client tc = getClient()) { tc.index(new IndexRequest(".opendistro_security").id("roles").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("roles", FileHelper.readYamlContent("roles.yml"))).actionGet(); ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"roles"})).actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("starfleet/_search?pretty", encodeBasicHeader("worf", "worf")).getStatusCode()); HttpResponse res = rh.executeGetRequest("_search?pretty", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"value\" : 11")); Assert.assertTrue(!res.getBody().contains(".opendistro_security")); - + res = rh.executeGetRequest("_nodes/stats?pretty", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("total_in_bytes")); Assert.assertTrue(res.getBody().contains("max_file_descriptors")); Assert.assertTrue(res.getBody().contains("buffer_pools")); Assert.assertFalse(res.getBody().contains("\"nodes\" : { }")); - + res = rh.executePostRequest("*/_upgrade", "", encodeBasicHeader("nagilum", "nagilum")); System.out.println(res.getBody()); System.out.println(res.getStatusReason()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - - String bulkBody = + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ "{ \"field2\" : \"value2\" }"+System.lineSeparator(); - + res = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("writer", "writer")); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"errors\":false")); - Assert.assertTrue(res.getBody().contains("\"status\":201")); - + Assert.assertTrue(res.getBody().contains("\"status\":201")); + res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("security_tenant", "unittesttenant"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("tenant")); Assert.assertTrue(res.getBody().contains("unittesttenant")); Assert.assertTrue(res.getBody().contains("\"kltentrw\":true")); Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); - + res = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("tenant")); @@ -208,7 +208,7 @@ public void testHTTPBasic() throws Exception { Assert.assertTrue(res.getBody().contains("\"user_name\":\"worf\"")); Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\":[]")); Assert.assertFalse(res.getBody().contains("attributes=")); - + res = rh.executeGetRequest("_opendistro/_security/authinfo?pretty", encodeBasicHeader("custattr", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("tenants")); @@ -217,38 +217,38 @@ public void testHTTPBasic() throws Exception { Assert.assertTrue(res.getBody().contains("\"custom_attribute_names\" : [")); Assert.assertTrue(res.getBody().contains("attr.internal.c3")); Assert.assertTrue(res.getBody().contains("attr.internal.c1")); - + res = rh.executeGetRequest("v2/_search", encodeBasicHeader("custattr", "nagilum")); Assert.assertEquals(res.getBody(), HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("v3/_search", encodeBasicHeader("custattr", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - + final String reindex = "{"+ - "\"source\": {"+ + "\"source\": {"+ "\"index\": \"starfleet\""+ "},"+ "\"dest\": {"+ "\"index\": \"copysf\""+ "}"+ "}"; - + res = rh.executePostRequest("_reindex?pretty", reindex, encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"total\" : 1")); Assert.assertTrue(res.getBody().contains("\"batches\" : 1")); Assert.assertTrue(res.getBody().contains("\"failures\" : [ ]")); - + //rest impersonation res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","knuddel"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("name=knuddel")); Assert.assertTrue(res.getBody().contains("attr.internal.test1")); Assert.assertFalse(res.getBody().contains("worf")); - + res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","nonexists"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - + res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","notallowed"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); } @@ -274,7 +274,7 @@ public void testHTTPSCompressionEnabled() throws Exception { assertNotContains(res, "*\"compression\":\"false\"*"); assertContains(res, "*\"compression\":\"true\"*"); } - + @Test public void testHTTPSCompression() throws Exception { final Settings settings = Settings.builder() @@ -298,30 +298,30 @@ public void testHTTPSCompression() throws Exception { @Test public void testHTTPAnon() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_anon.yml"), Settings.EMPTY, true); - + RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - + HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo"); Assert.assertTrue(resc.getBody().contains("opendistro_security_anonymous")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("_opendistro/_security/authinfo?pretty=true"); System.out.println(resc.getBody()); Assert.assertTrue(resc.getBody().contains("\"remote_address\" : \"")); //check pretty print Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", encodeBasicHeader("nagilum", "nagilum")); System.out.println(resc.getBody()); Assert.assertTrue(resc.getBody().contains("nagilum")); Assert.assertFalse(resc.getBody().contains("opendistro_security_anonymous")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + try (Client tc = getClient()) { tc.index(new IndexRequest(".opendistro_security").id("config").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("config", FileHelper.readYamlContent("config.yml"))).actionGet(); tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("internalusers").source("internalusers", FileHelper.readYamlContent("internal_users.yml"))).actionGet(); @@ -329,8 +329,8 @@ public void testHTTPAnon() throws Exception { Assert.assertFalse(cur.hasFailures()); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - - + + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("_opendistro/_security/authinfo").getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrong")).getStatusCode()); @@ -349,27 +349,27 @@ public void testHTTPClientCert() throws Exception { .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_PROTOCOLS, "TLSv1.1","TLSv1.2") .putList(SSLConfigConstants.SECURITY_SSL_TRANSPORT_ENABLED_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256") .build(); - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_clientcert.yml"), settings, true); - + try (Client tc = getClient()) { tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); Assert.assertFalse(cur.hasFailures()); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + RestHelper rh = restHelper(); - + rh.enableHTTPClientSSL = true; rh.trustHTTPServerCertificate = true; rh.sendAdminCertificate = true; rh.keystore = "spock-keystore.jks"; Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("_search").getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/x", "{}").getStatusCode()); - + rh.keystore = "kirk-keystore.jks"; Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest(".opendistro_security/_doc/y", "{}").getStatusCode()); HttpResponse res; @@ -380,7 +380,7 @@ public void testHTTPClientCert() throws Exception { @Test @Ignore public void testHTTPPlaintextErrMsg() throws Exception { - + try { final Settings settings = Settings.builder() .put("plugins.security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-0-keystore.jks")) @@ -405,7 +405,7 @@ public void testHTTPPlaintextErrMsg() throws Exception { public void testHTTPProxyDefault() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_proxy.yml"), Settings.EMPTY, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty"), encodeBasicHeader("nagilum-wrong", "nagilum-wrong")).getStatusCode()); @@ -415,7 +415,7 @@ public void testHTTPProxyDefault() throws Exception { Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("X-Proxy-User", "scotty")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("x-proxy-user", "scotty"),new BasicHeader("x-proxy-roles", "starfleet,engineer")).getStatusCode()); - + } @Test @@ -424,45 +424,45 @@ public void testHTTPProxyRolesSeparator() throws Exception { RestHelper rh = nonSslRestHelper(); // separator is configured as ";" so separating roles with "," leads to one (wrong) backend role HttpResponse res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("user", "scotty"),new BasicHeader("roles", "starfleet,engineer")); - Assert.assertTrue("Expected one backend role since separator is incorrect", res.getBody().contains("\"backend_roles\":[\"starfleet,engineer\"]")); + Assert.assertTrue("Expected one backend role since separator is incorrect", res.getBody().contains("\"backend_roles\":[\"starfleet,engineer\"]")); // correct separator, now we should see two backend roles res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "localhost,192.168.0.1,10.0.0.2"),new BasicHeader("user", "scotty"),new BasicHeader("roles", "starfleet;engineer")); - Assert.assertTrue("Expected two backend roles string since separator is correct: " + res.getBody(), res.getBody().contains("\"backend_roles\":[\"starfleet\",\"engineer\"]")); - + Assert.assertTrue("Expected two backend roles string since separator is correct: " + res.getBody(), res.getBody().contains("\"backend_roles\":[\"starfleet\",\"engineer\"]")); + } @Test public void testHTTPBasic2() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - + try (Client tc = getClient()) { - + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("starfleet_library").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("spock").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("kirk").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("role01_role02").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("starfleet","starfleet_academy","starfleet_library").alias("sf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("klingonempire","vulcangov").alias("nonsf"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("public").alias("unrestricted"))).actionGet(); } - + RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); @@ -480,11 +480,11 @@ public void testHTTPBasic2() throws Exception { Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "Basic")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", new BasicHeader("Authorization", "")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("picard", "picard")).getStatusCode()); - + for(int i=0; i< 10; i++) { Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("worf", "wrongpasswd")).getStatusCode()); } - + Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest("/theindex","{}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest("/theindex/_doc/1?refresh=true","{\"a\":0}",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); //Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("/theindex/_analyze?text=this+is+a+test",encodeBasicHeader("theindexadmin", "theindexadmin")).getStatusCode()); @@ -498,31 +498,31 @@ public void testHTTPBasic2() throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_close", null,encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePostRequest("/.opendistro_security/_upgrade", null,encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("/.opendistro_security/_mapping","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/", encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/2", "{}",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeDeleteRequest(".opendistro_security/_doc/0",encodeBasicHeader("worf", "worf")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest(".opendistro_security/_doc/0","{}",encodeBasicHeader("worf", "worf")).getStatusCode()); - + HttpResponse resc = rh.executeGetRequest("_cat/indices/public",encodeBasicHeader("bug108", "nagilum")); System.out.println(resc.getBody()); //Assert.assertTrue(resc.getBody().contains("green")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01_role02_role03", "user_role01_role02_role03")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("role01_role02/_search?pretty",encodeBasicHeader("user_role01", "user_role01")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("spock", "spock")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("spock/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("kirk/_search?pretty",encodeBasicHeader("kirk", "kirk")).getStatusCode()); - + System.out.println("ok"); //all - - + + } - + @Test public void testBulk() throws Exception { final Settings settings = Settings.builder() @@ -530,16 +530,16 @@ public void testBulk() throws Exception { .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_bulk.yml"), settings); final RestHelper rh = nonSslRestHelper(); - - String bulkBody = + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ "{ \"field1\" : \"value1\" }" +System.lineSeparator()+ "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ "{ \"field2\" : \"value2\" }"+System.lineSeparator(); - + HttpResponse res = rh.executePostRequest("_bulk", bulkBody, encodeBasicHeader("bulk", "nagilum")); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"errors\":false")); Assert.assertTrue(res.getBody().contains("\"status\":201")); } @@ -573,40 +573,40 @@ public void test557() throws Exception { .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); - + try (Client tc = getClient()) { - + tc.admin().indices().create(new CreateIndexRequest("copysf")).actionGet(); - + tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("starfleet_academy").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + } - + final RestHelper rh = nonSslRestHelper(); HttpResponse res = rh.executePostRequest("/*/_search", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", encodeBasicHeader("nagilum", "nagilum")); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("starfleet_academy")); res = rh.executePostRequest("/*/_search", "{\"size\":0,\"aggs\":{\"indices\":{\"terms\":{\"field\":\"_index\",\"size\":10}}}}", encodeBasicHeader("557", "nagilum")); System.out.println(res.getBody()); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - Assert.assertTrue(res.getBody().contains("starfleet_academy")); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertTrue(res.getBody().contains("starfleet_academy")); } - + @Test public void testITT1635() throws Exception { final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_ROLES_MAPPING_RESOLUTION, "BOTH") .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_dnfof.yml").setSecurityRoles("roles_itt1635.yml"), settings); - + try (Client tc = getClient()) { - + tc.index(new IndexRequest("esb-prod-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("esb-prod-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("esb-prod-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); @@ -621,12 +621,12 @@ public void testITT1635() throws Exception { tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))).actionGet(); } - + final RestHelper rh = nonSslRestHelper(); System.out.println("###1"); HttpResponse res = rh.executeGetRequest("/esb-prod-*/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); System.out.println("###2"); res = rh.executeGetRequest("/esb-alias-*/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -634,15 +634,15 @@ public void testITT1635() throws Exception { res = rh.executeGetRequest("/esb-prod-all/_search?pretty", encodeBasicHeader("itt1635", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); } - + @Test public void testTenantInfo() throws Exception { final Settings settings = Settings.builder() .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings); - + /* - + [admin_1, praxisrw, abcdef_2_2, kltentro, praxisro, kltentrw] admin_1==.kibana_-1139640511_admin1 praxisrw==.kibana_-1386441176_praxisrw @@ -650,11 +650,11 @@ public void testTenantInfo() throws Exception { kltentro==.kibana_-2014056171_kltentro praxisro==.kibana_-1386441184_praxisro kltentrw==.kibana_-2014056163_kltentrw - + */ - + try (Client tc = getClient()) { - + tc.index(new IndexRequest(".kibana-6").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest(".kibana_-1139640511_admin1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest(".kibana_-1386441176_praxisrw").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); @@ -664,7 +664,7 @@ public void testTenantInfo() throws Exception { tc.index(new IndexRequest(".kibana_9876_xxx_ccc").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest(".kibana_fff_eee").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("esb-prod-5").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":5}", XContentType.JSON)).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".kibana-6").alias(".kibana"))).actionGet(); @@ -672,11 +672,11 @@ public void testTenantInfo() throws Exception { tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("esb-prod-5").alias("esb-alias-5"))).actionGet(); } - + final RestHelper rh = nonSslRestHelper(); HttpResponse res = rh.executeGetRequest("_opendistro/_security/tenantinfo?pretty", encodeBasicHeader("itt1635", "nagilum")); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); res = rh.executeGetRequest("_opendistro/_security/tenantinfo?pretty", encodeBasicHeader("kibanaserver", "kibanaserver")); System.out.println(res.getBody()); @@ -691,7 +691,7 @@ public void testTenantInfo() throws Exception { Assert.assertFalse(res.getBody().contains("xxx")); Assert.assertFalse(res.getBody().contains(".kibana2")); } - + @Test public void testRestImpersonation() throws Exception { final Settings settings = Settings.builder() @@ -699,7 +699,7 @@ public void testRestImpersonation() throws Exception { .build(); setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_rest_impersonation.yml"), settings); final RestHelper rh = nonSslRestHelper(); - + //rest impersonation HttpResponse res = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as","someotherusernotininternalusersfile"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); diff --git a/src/test/java/org/opensearch/security/IndexIntegrationTests.java b/src/test/java/org/opensearch/security/IndexIntegrationTests.java index 8f2ee960bd..7dcef21483 100644 --- a/src/test/java/org/opensearch/security/IndexIntegrationTests.java +++ b/src/test/java/org/opensearch/security/IndexIntegrationTests.java @@ -59,46 +59,46 @@ public class IndexIntegrationTests extends SingleClusterTest { @Test public void testComposite() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("composite_config.yml").setSecurityRoles("roles_composite.yml"), Settings.EMPTY, true); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { tc.index(new IndexRequest("starfleet").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("klingonempire").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("public").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); } - - String msearchBody = + + String msearchBody = "{\"index\":\"starfleet\", \"ignore_unavailable\": true}"+System.lineSeparator()+ "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ "{\"index\":\"klingonempire\", \"ignore_unavailable\": true}"+System.lineSeparator()+ "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator()+ "{\"index\":\"public\", \"ignore_unavailable\": true}"+System.lineSeparator()+ "{\"size\":10, \"query\":{\"bool\":{\"must\":{\"match_all\":{}}}}}"+System.lineSeparator(); - - + + HttpResponse resc = rh.executePostRequest("_msearch", msearchBody, encodeBasicHeader("worf", "worf")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"_index\":\"klingonempire\"")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); Assert.assertTrue(resc.getBody(), resc.getBody().contains("no permissions for [indices:data/read/search]")); - + } - + @Test public void testBulkShards() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles_bs.yml"), Settings.EMPTY, true); final RestHelper rh = nonSslRestHelper(); - + try (Client tc = getClient()) { //create indices and mapping upfront tc.index(new IndexRequest("test").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("lorem").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"field2\":\"init\"}", XContentType.JSON)).actionGet(); } - - String bulkBody = + + String bulkBody = "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"1\" } }"+System.lineSeparator()+ "{ \"field2\" : \"value1\" }" +System.lineSeparator()+ "{ \"index\" : { \"_index\" : \"test\", \"_id\" : \"2\" } }"+System.lineSeparator()+ @@ -120,7 +120,7 @@ public void testBulkShards() throws Exception { "{ \"index\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }"+System.lineSeparator()+ "{ \"field2\" : \"value2\" }"+System.lineSeparator()+ "{ \"delete\" : { \"_index\" : \"lorem\", \"_id\" : \"5\" } }"+System.lineSeparator(); - + System.out.println("############ _bulk"); HttpResponse res = rh.executePostRequest("_bulk?refresh=true&pretty=true", bulkBody, encodeBasicHeader("worf", "worf")); System.out.println(res.getBody()); @@ -128,43 +128,43 @@ public void testBulkShards() throws Exception { Assert.assertTrue(res.getBody().contains("\"errors\" : true")); Assert.assertTrue(res.getBody().contains("\"status\" : 201")); Assert.assertTrue(res.getBody().contains("no permissions for")); - + System.out.println("############ check shards"); System.out.println(rh.executeGetRequest("_cat/shards?v", encodeBasicHeader("nagilum", "nagilum"))); - + } @Test public void testCreateIndex() throws Exception { - + setup(); RestHelper rh = nonSslRestHelper(); - + HttpResponse res; Assert.assertEquals("Unable to create index 'nag'", HttpStatus.SC_OK, rh.executePutRequest("nag1", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); Assert.assertEquals("Unable to create index 'starfleet_library'", HttpStatus.SC_OK, rh.executePutRequest("starfleet_library", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - + clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10), clusterInfo.numNodes); - + Assert.assertEquals("Unable to close index 'starfleet_library'", HttpStatus.SC_OK, rh.executePostRequest("starfleet_library/_close", null, encodeBasicHeader("nagilum", "nagilum")).getStatusCode()); - + Assert.assertEquals("Unable to open index 'starfleet_library'", HttpStatus.SC_OK, (res = rh.executePostRequest("starfleet_library/_open", null, encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); Assert.assertTrue("open index 'starfleet_library' not acknowledged", res.getBody().contains("acknowledged")); Assert.assertFalse("open index 'starfleet_library' not acknowledged", res.getBody().contains("false")); - + clusterHelper.waitForCluster(ClusterHealthStatus.GREEN, TimeValue.timeValueSeconds(10), clusterInfo.numNodes); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executePutRequest("public", null, encodeBasicHeader("spock", "spock")).getStatusCode()); - - + + } @Test public void testFilteredAlias() throws Exception { - + setup(); - + try (Client tc = getClient()) { tc.index(new IndexRequest("theindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); @@ -173,30 +173,30 @@ public void testFilteredAlias() throws Exception { tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("alias2").filter(QueryBuilders.termQuery("_type", "type2")).index("theindex"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().alias("alias3").filter(QueryBuilders.termQuery("_type", "type2")).index("otherindex"))).actionGet(); } - - + + RestHelper rh = nonSslRestHelper(); - + //opendistro_security_user1 -> worf //opendistro_security_user2 -> picard - + HttpResponse resc = rh.executeGetRequest("alias*/_search", encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("theindex/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("alias3/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); resc = rh.executeGetRequest("_cat/indices", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + } - + @Test public void testIndexTypeEvaluation() throws Exception { - + setup(); try (Client tc = getClient()) { @@ -212,45 +212,45 @@ public void testIndexTypeEvaluation() throws Exception { //expected } } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse resc = rh.executeGetRequest("/foo1/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); - + resc = rh.executeGetRequest("/foo2/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 2")); - + resc = rh.executeGetRequest("/foo/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 3")); - + //resc = rh.executeGetRequest("/fooba/z/_search?pretty", encodeBasicHeader("baz", "worf")); - //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); + resc = rh.executeGetRequest("/foo1/_doc/1?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); - + resc = rh.executeGetRequest("/foo2/_doc/2?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 2")); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); - + resc = rh.executeGetRequest("/foo/_doc/3?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 3")); Assert.assertTrue(resc.getBody().contains("\"found\" : true")); - + //resc = rh.executeGetRequest("/fooba/z/4?pretty", encodeBasicHeader("baz", "worf")); //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + //resc = rh.executeGetRequest("/foo*/_search?pretty", encodeBasicHeader("baz", "worf")); //Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/foo*,-fooba/_search?pretty", encodeBasicHeader("baz", "worf")); Assert.assertEquals(200, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\" : 1")); @@ -259,32 +259,32 @@ public void testIndexTypeEvaluation() throws Exception { @Test public void testIndices() throws Exception { - + setup(); - + try (Client tc = getClient()) { tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash-4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd", SecurityUtils.EN_Locale); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); - + String date = sdf.format(new Date()); tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse res = null; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + //nonexistent index with permissions Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + //existent index without permissions Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nopermindex/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); @@ -298,25 +298,25 @@ public void testIndices() throws Exception { Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); //nonexistent index with failed login - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("nouser", "nosuer"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search", encodeBasicHeader("nouser", "nosuer"))).getStatusCode()); + //nonexistent index with no login - Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search")).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, (res = rh.executeGetRequest("/logstash-nonex/_search")).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_all/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nopermindex,logstash-1,nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/logstash-1,nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/nonexist/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/%3Clogstash-%7Bnow%2Fd%7D%3E/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/%3Cnonex-%7Bnow%2Fd%7D%3E/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/%3Clogstash-%7Bnow%2Fd%7D%3E,logstash-*/_search", encodeBasicHeader("opendistro_security_logstash", "nagilum"))).getStatusCode()); @@ -337,7 +337,7 @@ public void testIndices() throws Exception { Assert.assertTrue(res.getBody().contains("logstash-cnew-20")); Assert.assertFalse(res.getBody().contains("<")); } - + @Test public void testAliases() throws Exception { @@ -346,10 +346,10 @@ public void testAliases() throws Exception { .build(); setup(settings); - + try (Client tc = getClient()) { tc.index(new IndexRequest("nopermindex").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.index(new IndexRequest("logstash-1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash-2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash-3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); @@ -360,28 +360,28 @@ public void testAliases() throws Exception { String date = new SimpleDateFormat("YYYY.MM.dd").format(new Date()); tc.index(new IndexRequest("logstash-"+date).setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("nopermindex").alias("nopermalias"))).actionGet(); tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices(".opendistro_security").alias("mysgi"))).actionGet(); } - + RestHelper rh = nonSslRestHelper(); - + HttpResponse res = null; - + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("/mysgi/_doc", "{}",encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/mysgi/_search?pretty", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); assertContains(res, "*\"hits\" : {*\"value\" : 0,*\"hits\" : [ ]*"); - + System.out.println("#### add alias to allowed index"); Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executePutRequest("/logstash-1/_alias/alog1", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); System.out.println("#### add alias to not existing (no perm)"); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/nonexitent/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + System.out.println("#### add alias to not existing (with perm)"); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (res = rh.executePutRequest("/logstash-nonex/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + System.out.println("#### add alias to not allowed index"); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/nopermindex/_alias/alnp", "",encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); @@ -391,32 +391,32 @@ public void testAliases() throws Exception { "{ \"remove_index\": { \"index\": \"logstash-del\" } } "+ "]"+ "}"; - + System.out.println("#### remove_index"); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePostRequest("/_aliases", aliasRemoveIndex,encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + System.out.println("#### get alias for permitted index"); Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash-1/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + System.out.println("#### get alias for all indices"); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_alias/alog1", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + System.out.println("#### get alias no perm"); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executeGetRequest("/_alias/nopermalias", encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); - + String alias = "{"+ "\"aliases\": {"+ "\"alias1\": {}"+ "}"+ "}"; - - + + System.out.println("#### create alias along with index"); - Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/beats-withalias", alias,encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); + Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (res = rh.executePutRequest("/beats-withalias", alias,encodeBasicHeader("aliasmngt", "nagilum"))).getStatusCode()); } @Test @@ -429,10 +429,10 @@ public void testIndexResolveInvalidIndexName() throws Exception { Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("invalid_index_name_exception")); } - + @Test public void testCCSIndexResolve() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); @@ -452,7 +452,7 @@ public void testCCSIndexResolve() throws Exception { @Test @Ignore public void testCCSIndexResolve2() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); @@ -462,46 +462,46 @@ public void testCCSIndexResolve2() throws Exception { tc.index(new IndexRequest("noperm").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":3}", XContentType.JSON)).actionGet(); } - + HttpResponse res = rh.executeGetRequest("/*:.abc,.abc/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); - + res = rh.executeGetRequest("/ba*bcuzh/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":12")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/*:xyz,xyz/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":2")); - + //res = rh.executeGetRequest("/*noexist/_search", encodeBasicHeader("nagilum", "nagilum")); - //Assert.assertEquals(HttpStatus.SC_NOT_FOUND, res.getStatusCode()); - + //Assert.assertEquals(HttpStatus.SC_NOT_FOUND, res.getStatusCode()); + res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); - + res = rh.executeGetRequest("/*:xyz/_search", encodeBasicHeader("nagilum", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":2")); - + res = rh.executeGetRequest("/.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:.abc,.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:xyz,xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:.abc/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:xyz/_search", encodeBasicHeader("ccsresolv", "nagilum")); - Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); + Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:noperm/_search", encodeBasicHeader("ccsresolv", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); res = rh.executeGetRequest("/*:noperm/_search", encodeBasicHeader("ccsresolv", "nagilum")); @@ -532,7 +532,7 @@ public void testIndexResolveIgnoreUnavailable() throws Exception { Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody(), resc.getBody().contains("\"total\":{\"value\":1")); } - + @Test public void testIndexResolveIndicesAlias() throws Exception { @@ -545,19 +545,19 @@ public void testIndexResolveIndicesAlias() throws Exception { tc.admin().indices().aliases(new IndicesAliasesRequest().addAliasAction(AliasActions.add().indices("foo-index").alias("foo-alias"))).actionGet(); tc.admin().indices().delete(new DeleteIndexRequest("foo-index")).actionGet(); } - + HttpResponse resc = rh.executeGetRequest("/_cat/aliases", encodeBasicHeader("nagilum", "nagilum")); Assert.assertFalse(resc.getBody().contains("foo")); resc = rh.executeGetRequest("/foo-alias/_search", encodeBasicHeader("foo_index", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/foo-index/_search", encodeBasicHeader("foo_index", "nagilum")); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, resc.getStatusCode()); - + resc = rh.executeGetRequest("/foo-alias/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_NOT_FOUND, resc.getStatusCode()); - + } @Test @@ -576,30 +576,30 @@ public void testIndexResolveMinus() throws Exception { resc = rh.executeGetRequest("/*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/**,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); resc = rh.executeGetRequest("/*,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("/*,-*security,-foo*/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("foo_all", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + resc = rh.executeGetRequest("/_all,-*security/_search", encodeBasicHeader("nagilum", "nagilum")); Assert.assertEquals(HttpStatus.SC_BAD_REQUEST, resc.getStatusCode()); - + } } diff --git a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java index 17ced9e325..87241ee110 100644 --- a/src/test/java/org/opensearch/security/InitializationIntegrationTests.java +++ b/src/test/java/org/opensearch/security/InitializationIntegrationTests.java @@ -65,7 +65,7 @@ public class InitializationIntegrationTests extends SingleClusterTest { @Test public void testEnsureInitViaRestDoesWork() throws Exception { - + final Settings settings = Settings.builder() .put(SSLConfigConstants.SECURITY_SSL_HTTP_CLIENTAUTH_MODE, "REQUIRE") .put("plugins.security.ssl.http.enabled",true) @@ -80,11 +80,11 @@ public void testEnsureInitViaRestDoesWork() throws Exception { rh.sendAdminCertificate = true; Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executePutRequest(".opendistro_security/_doc/0", "{}", encodeBasicHeader("___", "")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode()); - - + + rh.keystore = "kirk-keystore.jks"; Assert.assertEquals(HttpStatus.SC_CREATED, rh.executePutRequest(".opendistro_security/_doc/config", "{}", encodeBasicHeader("___", "")).getStatusCode()); - + Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"tx_size_in_bytes\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_count\" : 0")); Assert.assertFalse(rh.executeSimpleRequest("_nodes/stats?pretty").contains("\"rx_size_in_bytes\" : 0")); @@ -157,11 +157,11 @@ public void testWhoAmIForceHttp1() throws Exception { @Test public void testConfigHotReload() throws Exception { - + setup(); RestHelper rh = nonSslRestHelper(); Header spock = encodeBasicHeader("spock", "spock"); - + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); HttpResponse res = rh.executeRequest(new HttpGet("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort() + "/" + "_opendistro/_security/authinfo?pretty=true"), spock); @@ -169,14 +169,14 @@ public void testConfigHotReload() throws Exception { Assert.assertFalse(res.getBody().contains("additionalrole")); Assert.assertTrue(res.getBody().contains("vulcan")); } - + try (Client tc = getClient()) { Assert.assertEquals(clusterInfo.numNodes, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("internalusers").source("internalusers", FileHelper.readYamlContent("internal_users_spock_add_roles.yml"))).actionGet(); ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); - } - + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + } + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); log.debug("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort()); @@ -186,14 +186,14 @@ public void testConfigHotReload() throws Exception { Assert.assertTrue(res.getBody().contains("additionalrole2")); Assert.assertFalse(res.getBody().contains("starfleet")); } - + try (Client tc = getClient()) { Assert.assertEquals(clusterInfo.numNodes, tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); tc.index(new IndexRequest(".opendistro_security").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("config").source("config", FileHelper.readYamlContent("config_anon.yml"))).actionGet(); ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config"})).actionGet(); - Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); + Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + for (Iterator iterator = clusterInfo.httpAdresses.iterator(); iterator.hasNext();) { TransportAddress TransportAddress = (TransportAddress) iterator.next(); HttpResponse res = rh.executeRequest(new HttpGet("http://"+TransportAddress.getAddress()+":"+TransportAddress.getPort() + "/" + "_opendistro/_security/authinfo?pretty=true")); @@ -214,7 +214,7 @@ public void testDefaultConfig() throws Exception { setup(Settings.EMPTY, null, settings, false); RestHelper rh = nonSslRestHelper(); Thread.sleep(10000); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("admin", "admin")).getStatusCode()); HttpResponse res = rh.executeGetRequest("/_cluster/health", encodeBasicHeader("admin", "admin")); Assert.assertEquals(res.getBody(), HttpStatus.SC_OK, res.getStatusCode()); @@ -244,19 +244,19 @@ public void testInvalidDefaultConfig() throws Exception { @Test public void testDisabled() throws Exception { - + final Settings settings = Settings.builder().put("plugins.security.disabled", true).build(); - + setup(Settings.EMPTY, null, settings, false); RestHelper rh = nonSslRestHelper(); - + HttpResponse resc = rh.executeGetRequest("_search"); Assert.assertEquals(200, resc.getStatusCode()); - Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); + Assert.assertTrue(resc.getBody(), resc.getBody().contains("hits")); } @Test - public void testDiscoveryWithoutInitialization() throws Exception { + public void testDiscoveryWithoutInitialization() throws Exception { setup(Settings.EMPTY, null, Settings.EMPTY, false); Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); diff --git a/src/test/java/org/opensearch/security/IntegrationTests.java b/src/test/java/org/opensearch/security/IntegrationTests.java index 226551a5ae..8f2b0f7282 100644 --- a/src/test/java/org/opensearch/security/IntegrationTests.java +++ b/src/test/java/org/opensearch/security/IntegrationTests.java @@ -62,7 +62,7 @@ public class IntegrationTests extends SingleClusterTest { @Test - public void testSearchScroll() throws Exception { + public void testSearchScroll() throws Exception { final Settings settings = Settings.builder() .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".worf", "knuddel","nonexists") .build(); @@ -73,12 +73,12 @@ public void testSearchScroll() throws Exception { for(int i=0; i<3; i++) tc.index(new IndexRequest("vulcangov").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); } - - + + System.out.println("########search"); HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res=rh.executeGetRequest("vulcangov/_search?scroll=1m&pretty=true", encodeBasicHeader("nagilum", "nagilum"))).getStatusCode()); - + System.out.println(res.getBody()); int start = res.getBody().indexOf("_scroll_id") + 15; String scrollid = res.getBody().substring(start, res.getBody().indexOf("\"", start+1)); @@ -88,8 +88,8 @@ public void testSearchScroll() throws Exception { System.out.println("########search done"); - - + + } @Test @@ -101,21 +101,21 @@ public void testDnParsingCertAuth() throws Exception { HTTPClientCertAuthenticator auth = new HTTPClientCertAuthenticator(settings, null); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("cn=abc,cn=xxx,l=ert,st=zui,c=qwe")).getUsername()); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getUsername()); - Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("CN=abc,L=ert,st=zui,c=qwe")).getUsername()); + Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("CN=abc,L=ert,st=zui,c=qwe")).getUsername()); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("l=ert,cn=abc,st=zui,c=qwe")).getUsername()); Assert.assertNull(auth.extractCredentials(null, newThreadContext("L=ert,CN=abc,c,st=zui,c=qwe"))); Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("l=ert,st=zui,c=qwe,cn=abc")).getUsername()); - Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe,CN=abc")).getUsername()); - Assert.assertEquals("L=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe")).getUsername()); + Assert.assertEquals("abc", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe,CN=abc")).getUsername()); + Assert.assertEquals("L=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("L=ert,st=zui,c=qwe")).getUsername()); Assert.assertArrayEquals(new String[] {"ert"}, auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getBackendRoles().toArray(new String[0])); Assert.assertArrayEquals(new String[] {"bleh", "ert"}, new TreeSet<>(auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,L=bleh,st=zui,c=qwe")).getBackendRoles()).toArray(new String[0])); - + settings = Settings.builder() .build(); auth = new HTTPClientCertAuthenticator(settings, null); Assert.assertEquals("cn=abc,l=ert,st=zui,c=qwe", auth.extractCredentials(null, newThreadContext("cn=abc,l=ert,st=zui,c=qwe")).getUsername()); } - + private ThreadContext newThreadContext(String sslPrincipal) { ThreadContext threadContext = new ThreadContext(Settings.EMPTY); threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL, sslPrincipal); @@ -124,7 +124,7 @@ private ThreadContext newThreadContext(String sslPrincipal) { @Test public void testDNSpecials() throws Exception { - + final Settings settings = Settings.builder() .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") @@ -133,24 +133,24 @@ public void testDNSpecials() throws Exception { .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, "EMAILADDRESS=unt@xxx.com,CN=node-untspec6.example.com,OU=SSL,O=Te\\, st,L=Test,C=DE") .put(ConfigConstants.SECURITY_CERT_OID,"1.2.3.4.5.6") .build(); - - + + Settings tcSettings = Settings.builder() .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") .build(); - + setup(tcSettings, new DynamicSecurityConfig(), settings, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); - + } - + @Test public void testDNSpecials1() throws Exception { - + final Settings settings = Settings.builder() .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_FILEPATH, FileHelper.getAbsoluteFilePathFromClassPath("node-untspec5-keystore.p12")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS, "1") @@ -159,16 +159,16 @@ public void testDNSpecials1() throws Exception { .putList("plugins.security.authcz.admin_dn", "EMAILADDREss=unt@xxx.com, cn=node-untspec6.example.com, OU=SSL,O=Te\\, st,L=Test, c=DE") .put("plugins.security.cert.oid","1.2.3.4.5.6") .build(); - - + + Settings tcSettings = Settings.builder() .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("node-untspec6-keystore.p12")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_TYPE, "PKCS12") .build(); - + setup(tcSettings, new DynamicSecurityConfig(), settings, true); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("").getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("worf", "worf")).getStatusCode()); } @@ -181,17 +181,17 @@ public void testEnsureOpenSSLAvailability() { @Test public void testMultiget() throws Exception { - + setup(); - + try (Client tc = getClient()) { tc.index(new IndexRequest("mindex1").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("mindex2").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); } - + //opendistro_security_multiget -> picard - - + + String mgetBody = "{"+ "\"docs\" : ["+ "{"+ @@ -204,86 +204,86 @@ public void testMultiget() throws Exception { "}"+ "]"+ "}"; - + RestHelper rh = nonSslRestHelper(); HttpResponse resc = rh.executePostRequest("_mget?refresh=true", mgetBody, encodeBasicHeader("picard", "picard")); System.out.println(resc.getBody()); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertFalse(resc.getBody().contains("type2")); - + } @Test public void testRestImpersonation() throws Exception { - + final Settings settings = Settings.builder() .putList(ConfigConstants.SECURITY_AUTHCZ_REST_IMPERSONATION_USERS+".spock", "knuddel","userwhonotexists").build(); - + setup(settings); - + RestHelper rh = nonSslRestHelper(); - + //knuddel: // hash: _rest_impersonation_only_ - + HttpResponse resp; resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "knuddel"), encodeBasicHeader("worf", "worf")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); - + resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "knuddel"), encodeBasicHeader("spock", "spock")); Assert.assertEquals(HttpStatus.SC_OK, resp.getStatusCode()); Assert.assertTrue(resp.getBody().contains("name=knuddel")); Assert.assertFalse(resp.getBody().contains("spock")); - + resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "userwhonotexists"), encodeBasicHeader("spock", "spock")); System.out.println(resp.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); - + resp = rh.executeGetRequest("/_opendistro/_security/authinfo", new BasicHeader("opendistro_security_impersonate_as", "invalid"), encodeBasicHeader("spock", "spock")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resp.getStatusCode()); } @Test public void testSingle() throws Exception { - + setup(); - + try (Client tc = getClient()) { tc.index(new IndexRequest("shakespeare").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); - + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config","roles","rolesmapping","internalusers","actiongroups"})).actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + RestHelper rh = nonSslRestHelper(); //opendistro_security_shakespeare -> picard - + HttpResponse resc = rh.executeGetRequest("shakespeare/_search", encodeBasicHeader("picard", "picard")); System.out.println(resc.getBody()); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("\"content\":1")); - + resc = rh.executeHeadRequest("shakespeare", encodeBasicHeader("picard", "picard")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); - + } @Test public void testSpecialUsernames() throws Exception { - - setup(); + + setup(); RestHelper rh = nonSslRestHelper(); - + Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("bug.99", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, rh.executeGetRequest("", encodeBasicHeader("a", "b")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("\"'+-,;_?*@<>!$%&/()=#", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("", encodeBasicHeader("§ÄÖÜäöüß", "nagilum")).getStatusCode()); - + } @Test public void testXff() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_xff.yml"), Settings.EMPTY, true); RestHelper rh = nonSslRestHelper(); HttpResponse resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader("x-forwarded-for", "10.0.0.7"), encodeBasicHeader("worf", "worf")); @@ -293,7 +293,7 @@ public void testXff() throws Exception { @Test public void testRegexExcludes() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); try (Client tc = getClient()) { @@ -303,7 +303,7 @@ public void testRegexExcludes() throws Exception { tc.index(new IndexRequest("special").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"special\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("alsonotallowed").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"alsonotallowed\":1}", XContentType.JSON)).actionGet(); } - + RestHelper rh = nonSslRestHelper(); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("index*/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_OK, rh.executeGetRequest("indexa/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); @@ -311,10 +311,10 @@ public void testRegexExcludes() throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("special/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, rh.executeGetRequest("alsonotallowed/_search",encodeBasicHeader("rexclude", "nagilum")).getStatusCode()); } - + @Test public void testMultiRoleSpan() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); @@ -322,31 +322,31 @@ public void testMultiRoleSpan() throws Exception { tc.index(new IndexRequest("mindex_1").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":1}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("mindex_2").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); } - + HttpResponse res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); Assert.assertFalse(res.getBody().contains("\"content\":1")); Assert.assertFalse(res.getBody().contains("\"content\":2")); - + try (Client tc = getClient()) { tc.index(new IndexRequest(".opendistro_security").id("config").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("config", FileHelper.readYamlContent("config_multirolespan.yml"))).actionGet(); - + ConfigUpdateResponse cur = tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest(new String[]{"config"})).actionGet(); Assert.assertEquals(clusterInfo.numNodes, cur.getNodes().size()); } - + res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); System.out.println(res.getBody()); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); Assert.assertTrue(res.getBody().contains("\"content\":1")); Assert.assertTrue(res.getBody().contains("\"content\":2")); - + } - + @Test public void testMultiRoleSpan2() throws Exception { - + setup(Settings.EMPTY, new DynamicSecurityConfig().setConfig("config_multirolespan.yml"), Settings.EMPTY); final RestHelper rh = nonSslRestHelper(); @@ -356,26 +356,26 @@ public void testMultiRoleSpan2() throws Exception { tc.index(new IndexRequest("mindex_3").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("mindex_4").setRefreshPolicy(RefreshPolicy.IMMEDIATE).source("{\"content\":2}", XContentType.JSON)).actionGet(); } - + HttpResponse res = rh.executeGetRequest("/mindex_1,mindex_2/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); - + res = rh.executeGetRequest("/mindex_1,mindex_3/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); res = rh.executeGetRequest("/mindex_1,mindex_4/_search", encodeBasicHeader("mindex12", "nagilum")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, res.getStatusCode()); - + } - + @Test public void testSecurityUnderscore() throws Exception { - + setup(); final RestHelper rh = nonSslRestHelper(); - + HttpResponse res = rh.executePostRequest("abc_xyz_2018_05_24/_doc/1", "{\"content\":1}", encodeBasicHeader("underscore", "nagilum")); - + res = rh.executeGetRequest("abc_xyz_2018_05_24/_doc/1", encodeBasicHeader("underscore", "nagilum")); Assert.assertTrue(res.getBody(),res.getBody().contains("\"content\":1")); Assert.assertEquals(HttpStatus.SC_OK, res.getStatusCode()); @@ -573,10 +573,10 @@ public void testDnfof() throws Exception { Assert.assertEquals(HttpStatus.SC_FORBIDDEN, (resc=rh.executeGetRequest("notexists/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); System.out.println(resc.getBody()); - + Assert.assertEquals(HttpStatus.SC_NOT_FOUND, (resc=rh.executeGetRequest("permitnotexistentindex/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); System.out.println(resc.getBody()); - + Assert.assertEquals(HttpStatus.SC_OK, (resc=rh.executeGetRequest("permitnotexistentindex*/_search?pretty", encodeBasicHeader("user_a", "user_a"))).getStatusCode()); System.out.println(resc.getBody()); diff --git a/src/test/java/org/opensearch/security/ResolveAPITests.java b/src/test/java/org/opensearch/security/ResolveAPITests.java index 2c297e3bbe..a27c338dd1 100644 --- a/src/test/java/org/opensearch/security/ResolveAPITests.java +++ b/src/test/java/org/opensearch/security/ResolveAPITests.java @@ -34,7 +34,7 @@ public class ResolveAPITests extends SingleClusterTest { - + protected final Logger log = LogManager.getLogger(this.getClass()); @Test diff --git a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java index d14f8d6600..af71d590bf 100644 --- a/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesInjectorIntegTest.java @@ -84,7 +84,7 @@ public void testRolesInject() throws Exception { Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster(). health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") diff --git a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java index 1b4aee3e51..9a8278804a 100644 --- a/src/test/java/org/opensearch/security/RolesValidationIntegTest.java +++ b/src/test/java/org/opensearch/security/RolesValidationIntegTest.java @@ -75,7 +75,7 @@ public Collection createComponents(Client client, ClusterService cluster public void testRolesValidation() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig().setSecurityRoles("roles.yml"), Settings.EMPTY); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") diff --git a/src/test/java/org/opensearch/security/SecurityAdminTests.java b/src/test/java/org/opensearch/security/SecurityAdminTests.java index bd032fc332..553ab0a5f2 100644 --- a/src/test/java/org/opensearch/security/SecurityAdminTests.java +++ b/src/test/java/org/opensearch/security/SecurityAdminTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security; @@ -43,7 +43,7 @@ import static org.junit.Assert.assertThrows; public class SecurityAdminTests extends SingleClusterTest { - + @Test public void testSecurityAdmin() throws Exception { final Settings settings = Settings.builder() @@ -52,9 +52,9 @@ public void testSecurityAdmin() throws Exception { .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) .build(); setup(Settings.EMPTY, null, settings, false); - + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -66,11 +66,11 @@ public void testSecurityAdmin() throws Exception { argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); Assert.assertEquals(HttpStatus.SC_OK, (rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); @@ -211,9 +211,9 @@ public void testSecurityAdminV6Update() throws Exception { .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) .build(); setup(Settings.EMPTY, null, settings, false); - + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -225,11 +225,11 @@ public void testSecurityAdminV6Update() throws Exception { argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, new File("./legacy/securityconfig_v6").getAbsolutePath()); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + RestHelper rh = restHelper(); Assert.assertEquals(HttpStatus.SC_SERVICE_UNAVAILABLE, rh.executeGetRequest("_opendistro/_security/health?pretty").getStatusCode()); @@ -238,7 +238,7 @@ public void testSecurityAdminV6Update() throws Exception { //assertContains(res, "*strict*"); //assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminRegularUpdate() throws Exception { final Settings settings = Settings.builder() @@ -247,9 +247,9 @@ public void testSecurityAdminRegularUpdate() throws Exception { .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) .build(); setup(Settings.EMPTY, null, settings, true); - + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -261,21 +261,21 @@ public void testSecurityAdminRegularUpdate() throws Exception { argsAsList.add(clusterInfo.clustername); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminSingularV7Updates() throws Exception { final Settings settings = Settings.builder() @@ -284,9 +284,9 @@ public void testSecurityAdminSingularV7Updates() throws Exception { .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) .build(); setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); - + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -301,11 +301,11 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("config"); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -320,11 +320,11 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("rolesmapping"); argsAsList.add("-nhnv"); - - + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -339,21 +339,21 @@ public void testSecurityAdminSingularV7Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("tenants"); argsAsList.add("-nhnv"); - - + + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminSingularV6Updates() throws Exception { final Settings settings = Settings.builder() @@ -364,7 +364,7 @@ public void testSecurityAdminSingularV6Updates() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -379,21 +379,21 @@ public void testSecurityAdminSingularV6Updates() throws Exception { argsAsList.add("-t"); argsAsList.add("config"); argsAsList.add("-nhnv"); - + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminInvalidYml() throws Exception { final Settings settings = Settings.builder() @@ -404,7 +404,7 @@ public void testSecurityAdminInvalidYml() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), settings, true); final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -419,21 +419,21 @@ public void testSecurityAdminInvalidYml() throws Exception { argsAsList.add("-t"); argsAsList.add("roles"); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + RestHelper rh = restHelper(); HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); System.out.println(res.getBody()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminReloadInvalidConfig() throws Exception { final Settings settings = Settings.builder() @@ -451,10 +451,10 @@ public void testSecurityAdminReloadInvalidConfig() throws Exception { rh.keystore = "kirk-keystore.jks"; System.out.println(rh.executePutRequest(".opendistro_security/_doc/roles", FileHelper.loadFile("roles_invalidxcontent.yml")).getBody());; Assert.assertEquals(HttpStatus.SC_OK, rh.executePutRequest(".opendistro_security/_doc/roles", "{\"roles\":\"dummy\"}").getStatusCode()); - - + + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -466,98 +466,98 @@ public void testSecurityAdminReloadInvalidConfig() throws Exception { argsAsList.add(clusterInfo.clustername); argsAsList.add("-rl"); argsAsList.add("-nhnv"); - - + + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + HttpResponse res; - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_opendistro/_security/health?pretty")).getStatusCode()); assertContains(res, "*UP*"); assertContains(res, "*strict*"); assertNotContains(res, "*DOWN*"); } - + @Test public void testSecurityAdminValidateConfig() throws Exception { List argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); - + int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/test/resources/roles.yml").getAbsolutePath()); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_roles.yml").getAbsolutePath()); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_action_groups.yml").getAbsolutePath()); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(new File(PROJECT_ROOT_RELATIVE_PATH + "src/main/resources/static_config/static_tenants.yml").getAbsolutePath()); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-f"); argsAsList.add(TEST_RESOURCE_ABSOLUTE_PATH + "roles.yml"); argsAsList.add("-vc"); argsAsList.add("-t"); argsAsList.add("config"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); argsAsList.add("-ks"); argsAsList.add(TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH + "legacy/securityconfig_v6"); argsAsList.add("-vc"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH + "legacy/securityconfig_v6"); argsAsList.add("-vc"); argsAsList.add("6"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + argsAsList = new ArrayList<>(); addDirectoryPath(argsAsList, TEST_RESOURCE_ABSOLUTE_PATH); argsAsList.add("-vc"); argsAsList.add("8"); - + returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertNotEquals(0, returnCode); } @@ -570,9 +570,9 @@ public void testIsLegacySecurityIndexOnV7Index() throws Exception { .put("plugins.security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("truststore.jks")) .build(); setup(Settings.EMPTY, null, settings, false); - + final String prefix = getResourceFolder()==null?"":getResourceFolder()+"/"; - + List argsAsList = new ArrayList<>(); argsAsList.add("-ts"); argsAsList.add(FileHelper.getAbsoluteFilePathFromClassPath(prefix+"truststore.jks").toFile().getAbsolutePath()); @@ -588,7 +588,7 @@ public void testIsLegacySecurityIndexOnV7Index() throws Exception { // Execute first time to create the index int returnCode = SecurityAdmin.execute(argsAsList.toArray(new String[0])); Assert.assertEquals(0, returnCode); - + ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); PrintStream old = System.out; diff --git a/src/test/java/org/opensearch/security/SlowIntegrationTests.java b/src/test/java/org/opensearch/security/SlowIntegrationTests.java index 6a90ef8e71..b2efada0d8 100644 --- a/src/test/java/org/opensearch/security/SlowIntegrationTests.java +++ b/src/test/java/org/opensearch/security/SlowIntegrationTests.java @@ -53,7 +53,7 @@ public class SlowIntegrationTests extends SingleClusterTest { @Test public void testCustomInterclusterRequestEvaluator() throws Exception { - + final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_INTERCLUSTER_REQUEST_EVALUATOR_CLASS, "org.opensearch.security.AlwaysFalseInterClusterRequestEvaluator") .put("discovery.initial_state_timeout","8s") @@ -69,9 +69,9 @@ public void testNodeClientAllowedWithServerCertificate() throws Exception { setup(); Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") @@ -81,24 +81,24 @@ public void testNodeClientAllowedWithServerCertificate() throws Exception { .put("discovery.initial_state_timeout","8s") .putList("discovery.zen.ping.unicast.hosts", clusterInfo.nodeHost+":"+clusterInfo.nodePort) .build(); - + log.debug("Start node client"); - + try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { Assert.assertFalse(node.client().admin().cluster().health(new ClusterHealthRequest().waitForNodes(String.valueOf(clusterInfo.numNodes+1))).actionGet().isTimedOut()); - Assert.assertEquals(clusterInfo.numNodes+1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(clusterInfo.numNodes+1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); } } - + @SuppressWarnings("resource") @Test public void testNodeClientDisallowedWithNonServerCertificate() throws Exception { setup(); Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") @@ -110,26 +110,26 @@ public void testNodeClientDisallowedWithNonServerCertificate() throws Exception .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("kirk-keystore.jks")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS,"kirk") .build(); - + log.debug("Start node client"); try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { Thread.sleep(10000); - Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); } catch (Exception e) { Assert.fail(e.toString()); } - + } - + @SuppressWarnings("resource") @Test public void testNodeClientDisallowedWithNonServerCertificate2() throws Exception { setup(); Assert.assertEquals(clusterInfo.numNodes, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getNumberOfNodes()); Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster().health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") @@ -141,12 +141,12 @@ public void testNodeClientDisallowedWithNonServerCertificate2() throws Exception .put("plugins.security.ssl.transport.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("spock-keystore.jks")) .put(SSLConfigConstants.SECURITY_SSL_TRANSPORT_KEYSTORE_ALIAS,"spock") .build(); - + log.debug("Start node client"); - + try (Node node = new PluginAwareNode(false, tcSettings, Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class).start()) { Thread.sleep(10000); - Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); + Assert.assertEquals(1, node.client().admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet().getNodes().size()); } catch (Exception e) { Assert.fail(e.toString()); } diff --git a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java index 4e647a6324..6ccc11104a 100644 --- a/src/test/java/org/opensearch/security/SystemIntegratorsTests.java +++ b/src/test/java/org/opensearch/security/SystemIntegratorsTests.java @@ -40,31 +40,31 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class SystemIntegratorsTests extends SingleClusterTest { - + @Test public void testInjectedUserMalformed() throws Exception { - - final Settings settings = Settings.builder() + + final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") .build(); - + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, null)); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "|||")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "username||ip|")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); @@ -82,24 +82,24 @@ public void testInjectedUserMalformed() throws Exception { resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "||127.0.0:80|key1,value1,key2,value2")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); - + } @Test public void testInjectedUser() throws Exception { - - final Settings settings = Settings.builder() + + final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") .build(); - + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin||127.0.0:80|")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=admin, backend_roles=[], requestedTenant=null]")); @@ -139,7 +139,7 @@ public void testInjectedUser() throws Exception { // mapped by username Assert.assertTrue(resc.getBody().contains("\"roles\":[\"opendistro_security_all_access\"")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); Assert.assertTrue(resc.getBody().contains("User [name=myuser, backend_roles=[role1, vulcanadmin], requestedTenant=null]")); @@ -149,7 +149,7 @@ public void testInjectedUser() throws Exception { // mapped by backend role "twitter" Assert.assertTrue(resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); Assert.assertTrue(resc.getBody().contains("\"custom_attribute_names\":[\"key1\",\"key2\"]")); - + // add requested tenant resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "myuser|role1,vulcanadmin|8.8.8.8:8|key1,value1,key2,value2|")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); @@ -179,43 +179,43 @@ public void testInjectedUser() throws Exception { Assert.assertTrue(resc.getBody().contains("\"backend_roles\":[\"role1\",\"vulcanadmin\"]")); // mapped by backend role "twitter" Assert.assertTrue(resc.getBody().contains("\"roles\":[\"public\",\"role_vulcans_admin\"]")); - - } + + } @Test public void testInjectedUserDisabled() throws Exception { - - final Settings settings = Settings.builder() + + final Settings settings = Settings.builder() .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") .build(); - + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); // username|role1,role2|remoteIP|attributes - + HttpResponse resc; - + resc = rh.executeGetRequest("_opendistro/_security/authinfo", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "admin|role1|127.0.0:80|key1,value1")); Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, resc.getStatusCode()); } @Test public void testInjectedAdminUser() throws Exception { - - final Settings settings = Settings.builder() + + final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_ADMIN_USER_ENABLED, true) .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE","injectedadmin")) .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") .build(); - + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); HttpResponse resc; - + // injected user is admin, access to Security index must be allowed resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1")); Assert.assertEquals(HttpStatus.SC_OK, resc.getStatusCode()); @@ -223,26 +223,26 @@ public void testInjectedAdminUser() throws Exception { Assert.assertTrue(resc.getBody().contains("\"_id\" : \"roles\"")); Assert.assertTrue(resc.getBody().contains("\"_id\" : \"internalusers\"")); Assert.assertTrue(resc.getBody().contains("\"total\" : 5")); - + resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "wrongadmin|role1|127.0.0:80|key1,value1")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); - + } @Test public void testInjectedAdminUserAdminInjectionDisabled() throws Exception { - - final Settings settings = Settings.builder() + + final Settings settings = Settings.builder() .put(ConfigConstants.SECURITY_UNSUPPORTED_INJECT_USER_ENABLED, true) .putList(ConfigConstants.SECURITY_AUTHCZ_ADMIN_DN, Lists.newArrayList("CN=kirk,OU=client,O=client,L=Test,C=DE","injectedadmin")) .put("http.type", "org.opensearch.security.http.UserInjectingServerTransport") .build(); - + setup(settings, ClusterConfiguration.USERINJECTOR); - + final RestHelper rh = nonSslRestHelper(); HttpResponse resc; - + // injected user is admin, access to Security index must be allowed resc = rh.executeGetRequest(".opendistro_security/_search?pretty", new BasicHeader(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, "injectedadmin|role1|127.0.0:80|key1,value1")); Assert.assertEquals(HttpStatus.SC_FORBIDDEN, resc.getStatusCode()); @@ -251,7 +251,7 @@ public void testInjectedAdminUserAdminInjectionDisabled() throws Exception { Assert.assertFalse(resc.getBody().contains("\"_id\" : \"internalusers\"")); Assert.assertFalse(resc.getBody().contains("\"_id\" : \"tattr\"")); Assert.assertFalse(resc.getBody(), resc.getBody().contains("\"total\" : 6")); - - } + + } } diff --git a/src/test/java/org/opensearch/security/TaskTests.java b/src/test/java/org/opensearch/security/TaskTests.java index 0ec671af27..3a86b7e2bf 100644 --- a/src/test/java/org/opensearch/security/TaskTests.java +++ b/src/test/java/org/opensearch/security/TaskTests.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security; @@ -30,11 +30,11 @@ import org.opensearch.tasks.Task; public class TaskTests extends SingleClusterTest { - + @Test public void testXOpaqueIdHeader() throws Exception { setup(Settings.EMPTY, new DynamicSecurityConfig(), Settings.EMPTY); - + RestHelper rh = nonSslRestHelper(); HttpResponse res; Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("_tasks?group_by=parents&pretty" diff --git a/src/test/java/org/opensearch/security/UtilTests.java b/src/test/java/org/opensearch/security/UtilTests.java index 16baf932cc..83728e165d 100644 --- a/src/test/java/org/opensearch/security/UtilTests.java +++ b/src/test/java/org/opensearch/security/UtilTests.java @@ -110,31 +110,31 @@ public void testWildcardMatchers() { public void testMapFromArray() { Map map = SecurityUtils.mapFromArray((Object)null); assertTrue(map == null); - + map = SecurityUtils.mapFromArray("key"); assertTrue(map == null); map = SecurityUtils.mapFromArray("key", "value", "otherkey"); assertTrue(map == null); - + map = SecurityUtils.mapFromArray("key", "value"); - assertNotNull(map); + assertNotNull(map); assertEquals(1, map.size()); assertEquals("value", map.get("key")); map = SecurityUtils.mapFromArray("key", "value", "key", "value"); - assertNotNull(map); + assertNotNull(map); assertEquals(1, map.size()); assertEquals("value", map.get("key")); map = SecurityUtils.mapFromArray("key1", "value1", "key2", "value2"); - assertNotNull(map); + assertNotNull(map); assertEquals(2, map.size()); assertEquals("value1", map.get("key1")); assertEquals("value2", map.get("key2")); } - + @Test public void testEnvReplace() { Settings settings = Settings.EMPTY; @@ -150,7 +150,7 @@ public void testEnvReplace() { Map env = System.getenv(); assertTrue(env.size() > 0); - + boolean checked = false; for(String k: env.keySet()) { @@ -166,10 +166,10 @@ public void testEnvReplace() { assertTrue(OpenBSDBCrypt.checkPassword(SecurityUtils.replaceEnvVars("${envbc."+k+"}",settings), val.toCharArray())); checked = true; } - + assertTrue(checked); } - + @Test public void testNoEnvReplace() { Settings settings = Settings.builder().put(ConfigConstants.SECURITY_DISABLE_ENVVAR_REPLACEMENT, true).build(); @@ -182,7 +182,7 @@ public void testNoEnvReplace() { assertEquals("abv${env.MYENV-tTt}xyz", SecurityUtils.replaceEnvVars("abv${env.MYENV-tTt}xyz",settings)); Map env = System.getenv(); assertTrue(env.size() > 0); - + for(String k: env.keySet()) { assertEquals("abv${env."+k+"}xyz", SecurityUtils.replaceEnvVars("abv${env."+k+"}xyz",settings)); assertEquals("abv${"+k+"}xyz", SecurityUtils.replaceEnvVars("abv${"+k+"}xyz",settings)); diff --git a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java index dd53cd16a8..96773dfee4 100644 --- a/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/compliance/ComplianceAuditlogTest.java @@ -136,7 +136,7 @@ public void testComplianceEnable() throws Exception { final List mappingCreation = messages.stream().filter(msg -> "indices:admin/mapping/auto_put".equals(msg.getPrivilege())).collect(Collectors.toList()); assertThat(mappingCreation.size(), anyOf(equalTo(4), equalTo(2))); - + // disable compliance auditConfig = new AuditConfig(true, AuditConfig.Filter.DEFAULT , ComplianceConfig.from(ImmutableMap.of("enabled", false, "write_watched_indices", Collections.singletonList("emp")), additionalSettings)); updateAuditConfig(AuditTestUtils.createAuditPayload(auditConfig)); diff --git a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java index 1a99e8cdb0..afb102293b 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java @@ -83,7 +83,7 @@ public void testSimpleAuthenticatedSetting() throws Exception { final Settings settings = Settings.builder() .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) .put(FilterEntries.DISABLE_TRANSPORT_CATEGORIES.getKeyWithNamespace(), "NONE") - .build(); + .build(); verifyAuthenticated(settings); } @@ -133,7 +133,7 @@ public void testSSLPlainText() throws Exception { final RuntimeException ex = Assert.assertThrows(RuntimeException.class, () -> nonSslRestHelper().executeGetRequest("_search", encodeBasicHeader("admin", "admin"))); Assert.assertEquals("org.apache.hc.core5.http.NoHttpResponseException", ex.getCause().getClass().getName()); - }, 1); /* no retry on NotSslRecordException exceptions */ + }, 1); /* no retry on NotSslRecordException exceptions */ // All of the messages should be the same as the http client is attempting multiple times. messages.stream().forEach((message) -> { diff --git a/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java b/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java index 391b48ed70..3adc7a577f 100644 --- a/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java +++ b/src/test/java/org/opensearch/security/auth/blocking/HeapBasedClientBlockRegistryTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.blocking; @@ -23,33 +23,33 @@ import static org.junit.Assert.assertTrue; public class HeapBasedClientBlockRegistryTest { - + @Test - public void simpleTest() throws Exception { + public void simpleTest() throws Exception { HeapBasedClientBlockRegistry registry = new HeapBasedClientBlockRegistry<>(50, 3, String.class); - + assertFalse(registry.isBlocked("a")); registry.block("a"); assertTrue(registry.isBlocked("a")); - + registry.block("b"); assertTrue(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); - + registry.block("c"); assertTrue(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); assertTrue(registry.isBlocked("c")); - + registry.block("d"); assertFalse(registry.isBlocked("a")); assertTrue(registry.isBlocked("b")); assertTrue(registry.isBlocked("c")); assertTrue(registry.isBlocked("d")); } - + @Test - public void expiryTest() throws Exception { + public void expiryTest() throws Exception { HeapBasedClientBlockRegistry registry = new HeapBasedClientBlockRegistry<>(50, 3, String.class); assertFalse(registry.isBlocked("a")); diff --git a/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java b/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java index bd0cadfa6c..827bfa24b6 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/AddressBasedRateLimiterTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; diff --git a/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java b/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java index d3383f2dbe..2e8ddec15b 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/HeapBasedRateTrackerTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; @@ -26,11 +26,11 @@ import static org.junit.Assert.assertTrue; public class HeapBasedRateTrackerTest { - + @Test - public void simpleTest() throws Exception { + public void simpleTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 5, 100_000); - + assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); @@ -38,12 +38,12 @@ public void simpleTest() throws Exception { assertTrue(tracker.track("a")); } - + @Test @Ignore // https://github.com/opensearch-project/security/issues/2193 - public void expiryTest() throws Exception { + public void expiryTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 5, 100_000); - + assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); assertFalse(tracker.track("a")); @@ -55,38 +55,38 @@ public void expiryTest() throws Exception { assertFalse(tracker.track("b")); assertFalse(tracker.track("b")); assertTrue(tracker.track("b")); - - assertFalse(tracker.track("c")); - + + assertFalse(tracker.track("c")); + Thread.sleep(50); - - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - - Thread.sleep(55); - - assertFalse(tracker.track("c")); - assertTrue(tracker.track("c")); - - assertFalse(tracker.track("a")); - + + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + + Thread.sleep(55); + + assertFalse(tracker.track("c")); + assertTrue(tracker.track("c")); + + assertFalse(tracker.track("a")); + Thread.sleep(55); - assertFalse(tracker.track("c")); - assertFalse(tracker.track("c")); - assertTrue(tracker.track("c")); + assertFalse(tracker.track("c")); + assertFalse(tracker.track("c")); + assertTrue(tracker.track("c")); + - } - + @Test @Ignore // https://github.com/opensearch-project/security/issues/2193 - public void maxTwoTriesTest() throws Exception { + public void maxTwoTriesTest() throws Exception { HeapBasedRateTracker tracker = new HeapBasedRateTracker<>(100, 2, 100_000); - + assertFalse(tracker.track("a")); assertTrue(tracker.track("a")); - + assertFalse(tracker.track("b")); Thread.sleep(50); assertTrue(tracker.track("b")); diff --git a/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java b/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java index 9e7d95fd00..e42d2bd1b8 100644 --- a/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java +++ b/src/test/java/org/opensearch/security/auth/limiting/UserNameBasedRateLimiterTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2019 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.auth.limiting; diff --git a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java index 64e73202c7..b9b4d22d49 100644 --- a/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java +++ b/src/test/java/org/opensearch/security/ccstest/CrossClusterSearchTests.java @@ -67,7 +67,7 @@ import static org.hamcrest.Matchers.not; public class CrossClusterSearchTests extends AbstractSecurityUnitTest { - + private final ClusterHelper cl1 = new ClusterHelper("crl1_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); private final ClusterHelper cl2 = new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); private ClusterInfo cl1Info; @@ -143,13 +143,13 @@ private Tuple setupCluster(ClusterHelper ch, ClusterTra System.out.println("### " + ch.getClusterName() + " complete ###"); return new Tuple<>(clusterInfo, rh); } - + @After public void tearDown() throws Exception { cl1.stopCluster(); cl2.stopCluster(); } - + @Test public void testCcs() throws Exception { setupCcs(); @@ -1004,7 +1004,7 @@ public void testCcsWithRoleInjection() throws Exception { } final Settings.Builder clusterClientSettings = Settings.builder().putList("node.roles", "remote_cluster_client"); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(clusterClientSettings, false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(clusterClientSettings, false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", cl1Info.clustername) .put("path.data", "./target/data/" + cl1Info.clustername + "/cert/data") diff --git a/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java b/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java index 0d6efe1bb9..ad449aa20b 100644 --- a/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java +++ b/src/test/java/org/opensearch/security/ccstest/RemoteReindexTests.java @@ -45,57 +45,57 @@ import org.opensearch.security.test.helper.rest.RestHelper.HttpResponse; public class RemoteReindexTests extends AbstractSecurityUnitTest { - + private final ClusterHelper cl1 = new ClusterHelper("crl1_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); private final ClusterHelper cl2 = new ClusterHelper("crl2_n"+num.incrementAndGet()+"_f"+System.getProperty("forkno")+"_t"+System.nanoTime()); private ClusterInfo cl1Info; private ClusterInfo cl2Info; - - private void setupReindex() throws Exception { - + + private void setupReindex() throws Exception { + System.setProperty("security.display_lic_none","true"); - + cl2Info = cl2.startCluster(minimumSecuritySettings(Settings.EMPTY), ClusterConfiguration.DEFAULT); initialize(cl2, cl2Info); - + cl1Info = cl1.startCluster(minimumSecuritySettings(crossClusterNodeSettings(cl2Info)), ClusterConfiguration.DEFAULT); initialize(cl1, cl1Info); } - + @After public void tearDown() throws Exception { cl1.stopCluster(); cl2.stopCluster(); } - + private Settings crossClusterNodeSettings(ClusterInfo remote) { Settings.Builder builder = Settings.builder() .putList("reindex.remote.whitelist", remote.httpHost+":"+remote.httpPort); return builder.build(); } - + //TODO add ssl tests //https://github.com/elastic/elasticsearch/issues/27267 - + @Test public void testNonSSLReindex() throws Exception { setupReindex(); - + final String cl1BodyMain = new RestHelper(cl1Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); Assert.assertTrue(cl1BodyMain.contains("crl1")); - + try (Client tc = cl1.nodeClient()) { tc.admin().indices().create(new CreateIndexRequest("twutter")).actionGet(); } - + final String cl2BodyMain = new RestHelper(cl2Info, false, false, getResourceFolder()).executeGetRequest("", encodeBasicHeader("nagilum","nagilum")).getBody(); Assert.assertTrue(cl2BodyMain.contains("crl2")); - + try (Client tc = cl2.nodeClient()) { tc.index(new IndexRequest("twitter").setRefreshPolicy(RefreshPolicy.IMMEDIATE).id("0") .source("{\"cluster\": \""+cl1Info.clustername+"\"}", XContentType.JSON)).actionGet(); } - + String reindex = "{"+ "\"source\": {"+ "\"remote\": {"+ @@ -110,11 +110,11 @@ public void testNonSSLReindex() throws Exception { "\"index\": \"twutter\""+ "}"+ "}"; - + System.out.println(reindex); - + HttpResponse ccs = null; - + System.out.println("###################### reindex"); ccs = new RestHelper(cl1Info, false, false, getResourceFolder()).executePostRequest("_reindex?pretty", reindex, encodeBasicHeader("nagilum","nagilum")); System.out.println(ccs.getBody()); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java index 06d428a483..2e1eedcf57 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/AbstractDlsFlsTest.java @@ -64,7 +64,7 @@ protected final void setup(Settings override, DynamicSecurityConfig dynamicSecur rh = nonSslRestHelper(); } - + protected SearchResponse executeSearch(String indexName, String user, String password) throws Exception { HttpResponse response = rh.executeGetRequest("/"+indexName+"/_search?from=0&size=50&pretty", encodeBasicHeader(user, password)); @@ -80,15 +80,15 @@ protected GetResponse executeGet(String indexName, String id, String user, Strin LoggingDeprecationHandler.INSTANCE, response.getBody()); return GetResponse.fromXContent(xcp); } - + protected MultiSearchResponse executeMSearchMatchAll(String user, String password, String ... indexName) throws Exception { StringBuilder body = new StringBuilder(); - + for (String index : indexName) { body.append("{\"index\": \"").append(index).append("\"}\n"); body.append("{\"query\" : {\"match_all\" : {}}}\n"); } - + HttpResponse response = rh.executePostRequest("/_msearch?pretty", body.toString(), encodeBasicHeader(user, password)); Assert.assertEquals(200, response.getStatusCode()); @@ -98,13 +98,13 @@ protected MultiSearchResponse executeMSearchMatchAll(String user, String passwor } protected MultiGetResponse executeMGet(String user, String password, Map indicesAndIds) throws Exception { - + Set indexAndIdJson = new HashSet<>(); for (Map.Entry indexAndId : indicesAndIds.entrySet()) { indexAndIdJson.add("{ \"_index\": \""+indexAndId.getKey()+"\", \"_id\": \""+indexAndId.getValue()+"\" }"); } String body = "{ \"docs\": ["+ String.join(",", indexAndIdJson) +"] }"; - + HttpResponse response = rh.executePostRequest("/_mget?pretty", body,encodeBasicHeader(user, password)); Assert.assertEquals(200, response.getStatusCode()); XContentParser xcp = XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java index 4cd6987b5a..4ac8077c34 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/CCReplicationTest.java @@ -185,7 +185,7 @@ public void testReplication() throws Exception { Assert.assertEquals(ClusterHealthStatus.GREEN, clusterHelper.nodeClient().admin().cluster(). health(new ClusterHealthRequest().waitForGreenStatus()).actionGet().getStatus()); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put(minimumSecuritySettings(Settings.EMPTY).get(0)) .put("cluster.name", clusterInfo.clustername) .put("path.data", "./target/data/" + clusterInfo.clustername + "/cert/data") diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java index c4105c11e9..bfd0773f44 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsDateMathTest.java @@ -39,7 +39,7 @@ protected void populateData(Client tc) { LocalDateTime today = LocalDateTime.now(ZoneId.of("UTC")); LocalDateTime tomorrow = LocalDateTime.now(ZoneId.of("UTC")).plusDays(1); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); - + tc.index(new IndexRequest("logstash").id("1").setRefreshPolicy(RefreshPolicy.IMMEDIATE) .source("{\"@timestamp\": \""+formatter.format(yesterday)+"\"}", XContentType.JSON)).actionGet(); tc.index(new IndexRequest("logstash").id("2").setRefreshPolicy(RefreshPolicy.IMMEDIATE) @@ -48,7 +48,7 @@ protected void populateData(Client tc) { .source("{\"@timestamp\": \""+formatter.format(tomorrow)+"\"}", XContentType.JSON)).actionGet(); } - + @Test public void testDlsDateMathQuery() throws Exception { final Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_ALLOW_NOW_IN_DLS,true).build(); @@ -60,13 +60,13 @@ public void testDlsDateMathQuery() throws Exception { System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 1,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); Assert.assertTrue(res.getBody().contains("\"failed\" : 0")); } - + @Test public void testDlsDateMathQueryNotAllowed() throws Exception { setup(); @@ -77,7 +77,7 @@ public void testDlsDateMathQueryNotAllowed() throws Exception { System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("'now' is not allowed in DLS queries")); Assert.assertTrue(res.getBody().contains("error")); - + Assert.assertEquals(HttpStatus.SC_OK, (res = rh.executeGetRequest("/logstash/_search?pretty", encodeBasicHeader("admin", "admin"))).getStatusCode()); System.out.println(res.getBody()); Assert.assertTrue(res.getBody().contains("\"value\" : 3,\n \"relation")); diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java index b4a0d1f129..098d659d88 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/DlsTermLookupQueryTest.java @@ -545,7 +545,7 @@ public void testSimpleAggregation_tlqdocuments_AccessCode_1337() throws Exceptio setup(new DynamicSecurityConfig().setConfig("securityconfig_tlq.yml") .setSecurityInternalUsers("internal_users_tlq.yml").setSecurityRoles("roles_tlq.yml") .setSecurityRolesMapping("roles_mapping_tlq.yml")); - + String body = "" + " {\n" + " \"aggs\": {\n" @@ -580,7 +580,7 @@ public void testSimpleAggregation_tlqdocuments_AccessCode_1337() throws Exceptio Assert.assertTrue("Expected doc count in bucket " + bucketName + " to be 2", bucket.getDocCount() == 2); } // expect FFF to be absent - Assert.assertNull("Expected bucket FFF to be absent", agg.getBucketByKey("FFF")); + Assert.assertNull("Expected bucket FFF to be absent", agg.getBucketByKey("FFF")); } diff --git a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java index bbac74e6eb..a3b5d2809e 100644 --- a/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java +++ b/src/test/java/org/opensearch/security/dlic/dlsfls/FlsIndexingTests.java @@ -55,7 +55,7 @@ public void testSingleIndexFlsApplied() throws Exception { setup(new DynamicSecurityConfig() .setSecurityRoles("roles_fls_indexing.yml") .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); - + final HttpResponse phoneOneFilteredResponse = rh.executeGetRequest(searchQuery, asPhoneOneUser); assertThat(phoneOneFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(phoneOneFilteredResponse.getBody(), not(containsString("1003"))); @@ -76,7 +76,7 @@ public void testSingleIndexFlsAppliedForLimitedResults() throws Exception { setup(new DynamicSecurityConfig() .setSecurityRoles("roles_fls_indexing.yml") .setSecurityRolesMapping("roles_mapping_fls_indexing.yml")); - + final HttpResponse phoneOneFilteredResponse = rh.executeGetRequest("/yellow-pages/_search?filter_path=hits.hits&pretty", asPhoneOneUser); assertThat(phoneOneFilteredResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); assertThat(phoneOneFilteredResponse.getBody(), not(containsString("1003"))); diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java index 9f6bcb65c9..25974e322f 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AccountApiTest.java @@ -29,8 +29,8 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class AccountApiTest extends AbstractRestApiUnitTest { - private final String BASE_ENDPOINT; - private final String ENDPOINT; + private final String BASE_ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java index 926ee23f28..8030703197 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/ActionGroupsApiTest.java @@ -32,7 +32,7 @@ import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class ActionGroupsApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java index 450a5de83b..018af18293 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/AuditApiActionTest.java @@ -51,7 +51,7 @@ public class AuditApiActionTest extends AbstractRestApiUnitTest { // non-admin final Header nonAdminCredsHeader = encodeBasicHeader("random", "random"); - private final String ENDPOINT; + private final String ENDPOINT; private final String CONFIG_ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java index c17e997dc3..7d2396ecb0 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/DashboardsInfoActionTest.java @@ -22,7 +22,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class DashboardsInfoActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpoint() { return PLUGINS_PREFIX + "/dashboardsinfo"; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java index c998bf5a19..1d25b7dee2 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/FlushCacheApiTest.java @@ -23,7 +23,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class FlushCacheApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java index ea5e96d37e..9f767fd7a6 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/GetConfigurationApiTest.java @@ -24,7 +24,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class GetConfigurationApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java index c2313fe434..1b403760f8 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/IndexMissingTest.java @@ -24,7 +24,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class IndexMissingTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java index ef1042682b..1f752bd0b2 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/NodesDnApiTest.java @@ -42,7 +42,7 @@ public class NodesDnApiTest extends AbstractRestApiUnitTest { private HttpResponse response; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java index 5adac7ca78..9b5c7dc8c5 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RoleBasedAccessTest.java @@ -25,7 +25,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class RoleBasedAccessTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java index 3bc647bf12..c15651fcc8 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/RolesMappingApiTest.java @@ -32,7 +32,7 @@ import static org.opensearch.security.support.ConfigConstants.SECURITY_RESTAPI_ADMIN_ENABLED; public class RolesMappingApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java index 83630c036a..53c6ff2e96 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityApiAccessTest.java @@ -18,7 +18,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityApiAccessTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java index d717dcbf6c..50014993c1 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityConfigApiTest.java @@ -25,7 +25,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityConfigApiTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } @@ -57,7 +57,7 @@ public void testSecurityConfigApiRead() throws Exception { response = rh.executeDeleteRequest(ENDPOINT + "/securityconfig", new Header[0]); Assert.assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, response.getStatusCode()); } - + @Test public void testSecurityConfigApiWrite() throws Exception { diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java index 13dc4ee885..93371b548a 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityHealthActionTest.java @@ -22,7 +22,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityHealthActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java index 506ea3bdd2..654e0c6230 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/SecurityInfoActionTest.java @@ -22,7 +22,7 @@ import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX; public class SecurityInfoActionTest extends AbstractRestApiUnitTest { - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java index ab7e807153..00e983cc4f 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/TenantInfoActionTest.java @@ -27,7 +27,7 @@ public class TenantInfoActionTest extends AbstractRestApiUnitTest { "\"backend_roles\":[\"starfleet*\",\"ambassador\"],\"and_backend_roles\":[],\"description\":\"Migrated " + "from v6\"}"; private final String BASE_ENDPOINT; - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } @@ -60,7 +60,7 @@ public void testTenantInfoAPIAccess() throws Exception { public void testTenantInfoAPIUpdate() throws Exception { Settings settings = Settings.builder().put(ConfigConstants.SECURITY_UNSUPPORTED_RESTAPI_ALLOW_SECURITYCONFIG_MODIFICATION, true).build(); setup(settings); - + rh.keystore = "restapi/kirk-keystore.jks"; rh.sendHTTPClientCredentials = true; rh.sendAdminCertificate = true; diff --git a/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java b/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java index e4fca1e99b..cc148393c1 100644 --- a/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java +++ b/src/test/java/org/opensearch/security/dlic/rest/api/WhitelistApiTest.java @@ -51,7 +51,7 @@ public class WhitelistApiTest extends AbstractRestApiUnitTest { */ private final Header adminCredsHeader = encodeBasicHeader("admin_all_access", "admin_all_access"); private final Header nonAdminCredsHeader = encodeBasicHeader("sarek", "sarek"); - private final String ENDPOINT; + private final String ENDPOINT; protected String getEndpointPrefix() { return PLUGINS_PREFIX; } diff --git a/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java b/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java index 9430450875..161e8aab72 100644 --- a/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java +++ b/src/test/java/org/opensearch/security/filter/SecurityFilterTest.java @@ -119,7 +119,7 @@ public void testUnexepectedCausesAreNotSendToCallers() { final ArgumentCaptor cap = ArgumentCaptor.forClass(OpenSearchSecurityException.class); verify(listener).onFailure(cap.capture()); - assertThat("The cause should never be included as it will leak to callers", cap.getValue().getCause(), nullValue()); + assertThat("The cause should never be included as it will leak to callers", cap.getValue().getCause(), nullValue()); assertThat("Make sure the cause exception wasn't toStringed in the method", cap.getValue().getMessage(), not(containsString("ABC!"))); verifyNoMoreInteractions(auditLog, listener); diff --git a/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java b/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java index 111a07bf40..487da55767 100644 --- a/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java +++ b/src/test/java/org/opensearch/security/http/proxy/HTTPExtendedProxyAuthenticatorTest.java @@ -90,11 +90,11 @@ public void testReturnsNullWhenUserHeaderIsUnconfigured() { @Test public void testReturnsNullWhenUserHeaderIsMissing() { - + assertNull(authenticator.extractCredentials(new TestRestRequest(), context)); } @Test - + public void testReturnsCredentials() { headers.put("user", new ArrayList<>()); headers.put("proxy_uid", new ArrayList<>()); @@ -103,7 +103,7 @@ public void testReturnsCredentials() { headers.get("proxy_uid").add("123"); headers.get("proxy_uid").add("456"); headers.get("proxy_other").add("someothervalue"); - + settings = Settings.builder().put(settings).put("attr_header_prefix","proxy_").build(); authenticator = new HTTPExtendedProxyAuthenticator(settings,null); AuthCredentials creds = authenticator.extractCredentials(new TestRestRequest(headers), context); @@ -113,14 +113,14 @@ public void testReturnsCredentials() { assertEquals("someothervalue", creds.getAttributes().get("attr.proxy.other")); assertTrue(creds.isComplete()); } - + @Test public void testTrimOnRoles() { headers.put("user", new ArrayList<>()); headers.put("roles", new ArrayList<>()); headers.get("user").add("aValidUser"); headers.get("roles").add("role1, role2,\t"); - + settings = Settings.builder().put(settings) .put("roles_header","roles") .put("roles_separator", ",") @@ -134,7 +134,7 @@ public void testTrimOnRoles() { } static class TestRestRequest extends RestRequest { - + public TestRestRequest() { super(NamedXContentRegistry.EMPTY, new HashMap<>(), "", new HashMap<>(),new HttpRequestImpl(),new HttpChannelImpl()); } @@ -162,7 +162,7 @@ public boolean hasContent() { } } - + static class HttpRequestImpl implements HttpRequest { @Override @@ -228,19 +228,19 @@ public Exception getInboundException() { return null; } } - + static class HttpChannelImpl implements HttpChannel { @Override public void close() { // TODO Auto-generated method stub - + } @Override public void addCloseListener(ActionListener listener) { // TODO Auto-generated method stub - + } @Override @@ -252,7 +252,7 @@ public boolean isOpen() { @Override public void sendResponse(HttpResponse response, ActionListener listener) { // TODO Auto-generated method stub - + } @Override @@ -266,6 +266,6 @@ public InetSocketAddress getRemoteAddress() { // TODO Auto-generated method stub return null; } - + } } diff --git a/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java b/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java index bd9664a84c..4839155232 100644 --- a/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java +++ b/src/test/java/org/opensearch/security/multitenancy/test/TenancyMultitenancyEnabledTests.java @@ -29,7 +29,7 @@ public class TenancyMultitenancyEnabledTests extends SingleClusterTest { private static final Header AS_REST_API_USER = encodeBasicHeader("user_rest_api_access", "user_rest_api_access"); private static final Header AS_USER = encodeBasicHeader("admin", "admin"); private static final Header ON_USER_TENANT = new BasicHeader("securitytenant", "__user__"); - + private static String createIndexPatternDoc(final String title) { return "{"+ "\"type\" : \"index-pattern\","+ @@ -37,7 +37,7 @@ private static String createIndexPatternDoc(final String title) { "\"index-pattern\" : {"+ "\"title\" : \"" + title + "\""+ "}}"; - } + } @Override protected String getResourceFolder() { diff --git a/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java b/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java index 6d81c3b1da..d84d62c6b4 100644 --- a/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java +++ b/src/test/java/org/opensearch/security/privileges/SecurityIndexAccessEvaluatorTest.java @@ -58,8 +58,8 @@ public class SecurityIndexAccessEvaluatorTest { private SecurityIndexAccessEvaluator evaluator; - private static final String UNPROTECTED_ACTION = "indices:data/read"; - private static final String PROTECTED_ACTION = "indices:data/write"; + private static final String UNPROTECTED_ACTION = "indices:data/read"; + private static final String PROTECTED_ACTION = "indices:data/write"; @Before public void before() { @@ -79,7 +79,7 @@ public void before() { public void after() { verifyNoMoreInteractions(auditLog, irr, request, task, presponse, log); } - + @Test public void actionIsNotProtected_noSystemIndexInvolved() { final Resolved resolved = createResolved(".test"); diff --git a/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java b/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java index be7c2da7b0..856f026d72 100644 --- a/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java +++ b/src/test/java/org/opensearch/security/securityconf/impl/v7/IndexPatternTests.java @@ -68,7 +68,7 @@ public void before() { @After public void after() { verifyNoMoreInteractions(user, resolver, clusterService); - } + } @Test public void testCtor() { @@ -78,7 +78,7 @@ public void testCtor() { /** Ensure that concreteIndexNames sends correct parameters are sent to getResolvedIndexPattern */ @Test public void testConcreteIndexNamesOverload() { - doReturn(ImmutableSet.of("darn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, false); + doReturn(ImmutableSet.of("darn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, false); final Set results = ip.concreteIndexNames(user, resolver, clusterService); @@ -93,7 +93,7 @@ public void testConcreteIndexNamesOverload() { @Test public void testAttemptResolveIndexNamesOverload() { doReturn(ImmutableSet.of("yarn")).when(ip).getResolvedIndexPattern(user, resolver, clusterService, true); - + final Set results = ip.attemptResolveIndexNames(user, resolver, clusterService); assertThat(results, contains("yarn")); @@ -172,7 +172,7 @@ public void testMultipleConcreteIndicesWithOneAlias() { verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100")); verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*")); } - + /** Verify attemptResolveIndexNames with multiple aliases */ @Test public void testMultipleConcreteAliasedAndUnresolved() { @@ -200,7 +200,7 @@ private ClusterState createClusterState(final IndexShorthand... indices) { Arrays.stream(indices).forEach(indexShorthand -> { final IndexAbstraction indexAbstraction = mock(IndexAbstraction.class); when(indexAbstraction.getType()).thenReturn(indexShorthand.type); - indexMap.put(indexShorthand.name, indexAbstraction); + indexMap.put(indexShorthand.name, indexAbstraction); }); final Metadata mockMetadata = mock(Metadata.class, withSettings().strictness(Strictness.LENIENT)); diff --git a/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java b/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java index 72c1bc3741..143efe9b11 100644 --- a/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java +++ b/src/test/java/org/opensearch/security/setting/DeprecatedSettingsTest.java @@ -29,7 +29,7 @@ public class DeprecatedSettingsTest { @Mock private DeprecationLogger logger; - private DeprecationLogger original; + private DeprecationLogger original; @Before public void before() { diff --git a/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java b/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java index f1f7f9ea84..b619c2707f 100644 --- a/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java +++ b/src/test/java/org/opensearch/security/ssl/CertificateValidatorTest.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -41,28 +41,28 @@ import org.opensearch.security.test.helper.file.FileHelper; public class CertificateValidatorTest { - + public static final Date CRL_DATE = new Date(1525546426000L); protected final Logger log = LogManager.getLogger(this.getClass()); - + @Test public void testStaticCRL() throws Exception { - + File staticCrl = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl").toFile(); Collection crls = null; try(FileInputStream crlin = new FileInputStream(staticCrl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + Assert.assertEquals(crls.size(), 1); - + //trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem").toFile(); try(FileInputStream trin = new FileInputStream(trustedCas)) { rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); //certificate chain to validate (client cert + intermediates but without root) @@ -71,9 +71,9 @@ public void testStaticCRL() throws Exception { try(FileInputStream trin = new FileInputStream(certs)) { certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), crls); validator.setDate(CRL_DATE); try { @@ -83,25 +83,25 @@ public void testStaticCRL() throws Exception { Assert.assertTrue(ExceptionUtils.getRootCause(e) instanceof CertificateRevokedException); } } - + @Test public void testStaticCRLOk() throws Exception { - + File staticCrl = FileHelper.getAbsoluteFilePathFromClassPath("ssl/crl/revoked.crl").toFile(); Collection crls = null; try(FileInputStream crlin = new FileInputStream(staticCrl)) { crls = CertificateFactory.getInstance("X.509").generateCRLs(crlin); } - + Assert.assertEquals(crls.size(), 1); - + //trust chain incl intermediate certificates (root + intermediates) Collection rootCas; final File trustedCas = FileHelper.getAbsoluteFilePathFromClassPath("ssl/chain-ca.pem").toFile(); try(FileInputStream trin = new FileInputStream(trustedCas)) { rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); //certificate chain to validate (client cert + intermediates but without root) @@ -110,9 +110,9 @@ public void testStaticCRLOk() throws Exception { try(FileInputStream trin = new FileInputStream(certs)) { certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 3); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), crls); validator.setDate(CRL_DATE); try { @@ -121,7 +121,7 @@ public void testStaticCRLOk() throws Exception { Assert.fail(ExceptionsHelper.stackTrace(ExceptionUtils.getRootCause(e))); } } - + @Test public void testNoValidationPossible() throws Exception { @@ -131,7 +131,7 @@ public void testNoValidationPossible() throws Exception { try(FileInputStream trin = new FileInputStream(trustedCas)) { rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 2); //certificate chain to validate (client cert + intermediates but without root) @@ -140,7 +140,7 @@ public void testNoValidationPossible() throws Exception { try(FileInputStream trin = new FileInputStream(certs)) { certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), Collections.emptyList()); @@ -153,7 +153,7 @@ public void testNoValidationPossible() throws Exception { Assert.assertTrue(e.getCause().getMessage().contains("unable to find valid certification path to requested target")); } } - + @Test public void testCRLDP() throws Exception { @@ -163,7 +163,7 @@ public void testCRLDP() throws Exception { try(FileInputStream trin = new FileInputStream(trustedCas)) { rootCas = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(rootCas.size(), 1); //certificate chain to validate (client cert + intermediates but without root) @@ -173,9 +173,9 @@ public void testCRLDP() throws Exception { try(FileInputStream trin = new FileInputStream(certs)) { certsToValidate = (Collection) CertificateFactory.getInstance("X.509").generateCertificates(trin); } - + Assert.assertEquals(certsToValidate.size(), 2); - + CertificateValidator validator = new CertificateValidator(rootCas.toArray(new X509Certificate[0]), Collections.emptyList()); validator.setEnableCRLDP(true); validator.setEnableOCSP(true); diff --git a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java index 6d473c0160..4334d9a91c 100644 --- a/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java +++ b/src/test/java/org/opensearch/security/ssl/OpenSSLTest.java @@ -1,10 +1,10 @@ /* * Copyright 2015-2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -111,14 +111,14 @@ public void testNodeClientSSL() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testNodeClientSSL(); } - + @Override @Test public void testHttpsOptionalAuth() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsOptionalAuth(); } - + @Test public void testAvailCiphersOpenSSL() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); @@ -139,7 +139,7 @@ public void testAvailCiphersOpenSSL() throws Exception { System.out.println("OpenSSL secure ciphers: " + openSSLSecureCiphers); Assert.assertTrue(openSSLSecureCiphers.size() > 0); } - + @Test public void testHttpsEnforceFail() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); @@ -157,22 +157,22 @@ public void testHttpsAndNodeSSLFailedCipher() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLFailedCipher(); } - + @Test public void testHttpsAndNodeSSLPem() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLPKCS8Pem(); } - + @Test public void testHttpsAndNodeSSLPemEnc() throws Exception { Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable()); super.testHttpsAndNodeSSLPemEnc(); } - + @Test public void testNodeClientSSLwithOpenSslTLSv13() throws Exception { - + Assume.assumeTrue(OpenSearchSecuritySSLPlugin.OPENSSL_SUPPORTED && OpenSsl.isAvailable() && OpenSsl.version() > 0x10101009L); final Settings settings = Settings.builder().put("plugins.security.ssl.transport.enabled", true) @@ -190,10 +190,10 @@ public void testNodeClientSSLwithOpenSslTLSv13() throws Exception { .build(); setupSslOnlyMode(settings); - + RestHelper rh = nonSslRestHelper(); - final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) + final Settings tcSettings = AbstractSecurityUnitTest.nodeRolesSettings(Settings.builder(), false, false) .put("cluster.name", clusterInfo.clustername).put("path.home", "/tmp") .put("node.name", "client_node_" + new Random().nextInt()) .put("path.data", "./target/data/" + clusterInfo.clustername + "/ssl/data") diff --git a/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java b/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java index 6102327fe4..0dfaa557e1 100644 --- a/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java +++ b/src/test/java/org/opensearch/security/ssl/TestPrincipalExtractor.java @@ -1,10 +1,10 @@ /* * Copyright 2017 floragunn GmbH - * + * * Licensed 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 @@ -12,7 +12,7 @@ * 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.opensearch.security.ssl; @@ -25,7 +25,7 @@ public class TestPrincipalExtractor implements PrincipalExtractor { private static int transportCount = 0; private static int httpCount = 0; - + public TestPrincipalExtractor() { } @@ -34,11 +34,11 @@ public String extractPrincipal(X509Certificate x509Certificate, Type type) { if(type == Type.HTTP) { httpCount++; } - + if(type == Type.TRANSPORT) { transportCount++; } - + return "testdn"; } @@ -49,7 +49,7 @@ public static int getTransportCount() { public static int getHttpCount() { return httpCount; } - + public static void reset() { httpCount = 0; transportCount = 0; diff --git a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java index 72b05abb91..950409a3e3 100644 --- a/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java +++ b/src/test/java/org/opensearch/security/test/AbstractSecurityUnitTest.java @@ -95,11 +95,11 @@ import org.opensearch.threadpool.ThreadPool; /* - * There are real thread leaks during test execution, not all threads are + * There are real thread leaks during test execution, not all threads are * properly waited on or interrupted. While this normally doesn't create test * failures, retries mitigate this. Remove this attribute to explore these * issues. - */ + */ @ThreadLeakScope(Scope.NONE) public abstract class AbstractSecurityUnitTest extends RandomizedTest { diff --git a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java index 871cf5a59d..5a0c41fd33 100644 --- a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java +++ b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterConfiguration.java @@ -47,7 +47,7 @@ public enum ClusterConfiguration { //first one needs to be a cluster manager //HUGE(new NodeSettings(true, false, false), new NodeSettings(true, false, false), new NodeSettings(true, false, false), new NodeSettings(false, true,false), new NodeSettings(false, true, false)), - + //3 nodes (1m, 2d) DEFAULT(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true)), @@ -65,7 +65,7 @@ public enum ClusterConfiguration { //1 node (1md) SINGLENODE(new NodeSettings(true, true)), - + //4 node (1m, 2d, 1c) CLIENTNODE(new NodeSettings(true, false), new NodeSettings(false, true), new NodeSettings(false, true), new NodeSettings(false, false)), @@ -73,50 +73,50 @@ public enum ClusterConfiguration { USERINJECTOR(new NodeSettings(true, false, Lists.newArrayList(UserInjectorPlugin.class)), new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class)), new NodeSettings(false, true, Lists.newArrayList(UserInjectorPlugin.class))); private List nodeSettings = new LinkedList<>(); - + private ClusterConfiguration(NodeSettings ... settings) { nodeSettings.addAll(Arrays.asList(settings)); } - + public List getNodeSettings() { return Collections.unmodifiableList(nodeSettings); } - + public List getClusterManagerNodeSettings() { return Collections.unmodifiableList(nodeSettings.stream().filter(a->a.clusterManagerNode).collect(Collectors.toList())); } - + public List getNonClusterManagerNodeSettings() { return Collections.unmodifiableList(nodeSettings.stream().filter(a->!a.clusterManagerNode).collect(Collectors.toList())); } - + public int getNodes() { return nodeSettings.size(); } - + public int getClusterManagerNodes() { return (int) nodeSettings.stream().filter(a->a.clusterManagerNode).count(); } - + public int getDataNodes() { return (int) nodeSettings.stream().filter(a->a.dataNode).count(); } - + public int getClientNodes() { return (int) nodeSettings.stream().filter(a->!a.clusterManagerNode && !a.dataNode).count(); } - + public static class NodeSettings { public boolean clusterManagerNode; public boolean dataNode; public List> plugins = Lists.newArrayList(Netty4ModulePlugin.class, OpenSearchSecurityPlugin.class, MatrixAggregationModulePlugin.class, MustacheModulePlugin.class, ParentJoinModulePlugin.class, PercolatorModulePlugin.class, ReindexModulePlugin.class); - + public NodeSettings(boolean clusterManagerNode, boolean dataNode) { super(); this.clusterManagerNode = clusterManagerNode; this.dataNode = dataNode; } - + public NodeSettings(boolean clusterManagerNode, boolean dataNode, List> additionalPlugins) { this(clusterManagerNode, dataNode); this.plugins.addAll(additionalPlugins); @@ -126,7 +126,7 @@ public NodeSettings removePluginIfPresent(Class pluginToRemove this.plugins.remove(pluginToRemove); return this; } - + public Class[] getPlugins() { return plugins.toArray(new Class[0] ); } diff --git a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java index 5aea8f7dfe..efa0a8f89d 100644 --- a/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/cluster/ClusterHelper.java @@ -74,7 +74,7 @@ public final class ClusterHelper { static { resetSystemProperties(); } - + /** Resets all system properties associated with a cluster */ public static void resetSystemProperties() { System.setProperty("opensearch.enforce.bootstrap.checks", "true"); @@ -84,7 +84,7 @@ public static void resetSystemProperties() { /** * Update the default directory used by the security plugin * NOTE: this setting is system wide, use ClusterHelper.resetSystemProperties() to restore the original state - * + * * @return the previous value if one was set, otherwise null */ public static String updateDefaultDirectory(final String newValue) { diff --git a/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java b/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java index 6aadd2acbb..803088771a 100644 --- a/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/file/FileHelper.java @@ -64,14 +64,14 @@ public static KeyStore getKeystoreFromClassPath(final String fileNameFromClasspa if(path==null) { return null; } - + KeyStore ks = KeyStore.getInstance("JKS"); try (FileInputStream fin = new FileInputStream(path.toFile())) { ks.load(fin, password==null||password.isEmpty()?null:password.toCharArray()); } return ks; } - + public static Path getAbsoluteFilePathFromClassPath(final String fileNameFromClasspath) { File file = null; final URL fileUrl = FileHelper.class.getClassLoader().getResource(fileNameFromClasspath); @@ -99,9 +99,9 @@ public static final String loadFile(final String file) throws IOException { IOUtils.copy(FileHelper.class.getResourceAsStream("/" + file), sw, StandardCharsets.UTF_8); return sw.toString(); } - + public static BytesReference readYamlContent(final String file) { - + XContentParser parser = null; try { parser = XContentFactory.xContent(XContentType.YAML).createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(loadFile(file))); @@ -122,9 +122,9 @@ public static BytesReference readYamlContent(final String file) { } } } - + public static BytesReference readYamlContentFromString(final String yaml) { - + XContentParser parser = null; try { parser = XContentFactory.xContent(XContentType.YAML).createParser(NamedXContentRegistry.EMPTY, THROW_UNSUPPORTED_OPERATION, new StringReader(yaml)); diff --git a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java index 367332f160..7ed23b9c73 100644 --- a/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java +++ b/src/test/java/org/opensearch/security/test/helper/rest/RestHelper.java @@ -95,7 +95,7 @@ public class RestHelper { protected final Logger log = LogManager.getLogger(RestHelper.class); - + public boolean enableHTTPClientSSL = true; public boolean enableHTTPClientSSLv3Only = false; public boolean sendAdminCertificate = false; @@ -105,12 +105,12 @@ public class RestHelper { public final String prefix; //public String truststore = "truststore.jks"; private ClusterInfo clusterInfo; - + public RestHelper(ClusterInfo clusterInfo, String prefix) { this.clusterInfo = clusterInfo; this.prefix = prefix; } - + public RestHelper(ClusterInfo clusterInfo, boolean enableHTTPClientSSL, boolean trustHTTPServerCertificate, String prefix) { this.clusterInfo = clusterInfo; this.enableHTTPClientSSL = enableHTTPClientSSL; @@ -191,11 +191,11 @@ public HttpResponse executeGetRequest(final String request, String body, Header. getRequest.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); return executeRequest(getRequest, header); } - + public HttpResponse executeHeadRequest(final String request, Header... header) { return executeRequest(new HttpHead(getRequestUri(request)), header); } - + public HttpResponse executeOptionsRequest(final String request) { return executeRequest(new HttpOptions(getRequestUri(request))); } @@ -228,15 +228,15 @@ public HttpResponse executePostRequest(final String request, String body, Header return executeRequest(uriRequest, header); } - + public HttpResponse executePatchRequest(final String request, String body, Header... header) { HttpPatch uriRequest = new HttpPatch(getRequestUri(request)); if (body != null && !body.isEmpty()) { uriRequest.setEntity(createStringEntity(body)); } return executeRequest(uriRequest, header); - } - + } + public HttpResponse executeRequest(HttpUriRequest uriRequest, Header... header) { CloseableHttpAsyncClient httpClient = null; @@ -255,7 +255,7 @@ public HttpResponse executeRequest(HttpUriRequest uriRequest, Header... header) if (!uriRequest.containsHeader("Content-Type")) { uriRequest.addHeader("Content-Type","application/json"); } - + final CompletableFuture future = new CompletableFuture<>(); final SimpleHttpRequest simpleRequest = SimpleRequestBuilder.copy(uriRequest).build(); if (uriRequest.getEntity() != null) { @@ -283,7 +283,7 @@ public void cancelled() { if (enableHTTPClientSSL && !res.getProtocolVersion().equals(HttpVersion.HTTP_2)) { throw new IllegalStateException("HTTP/2 expected for HTTPS communication but " + res.getProtocolVersion() + " was used"); } - + log.debug(res.getBody()); return res; } catch (final CompletionException e) { @@ -313,7 +313,7 @@ public void cancelled() { private HttpEntity createStringEntity(String body) { return new StringEntity(body); } - + protected final String getHttpServerUri() { final String address = "http" + (enableHTTPClientSSL ? "s" : "") + "://" + clusterInfo.httpHost + ":" + clusterInfo.httpPort; log.debug("Connect to {}", address); @@ -323,7 +323,7 @@ protected final String getHttpServerUri() { protected final String getRequestUri(String request) { return getHttpServerUri() + "/" + StringUtils.strip(request, "/"); } - + protected final CloseableHttpAsyncClient getHTTPClient() throws Exception { final HttpAsyncClientBuilder hcb = HttpAsyncClients.custom(); @@ -338,13 +338,13 @@ protected final CloseableHttpAsyncClient getHTTPClient() throws Exception { if (enableHTTPClientSSL) { log.debug("Configure HTTP client with SSL"); - + if(prefix != null && !keystore.contains("/")) { keystore = prefix+"/"+keystore; } - + final String keyStorePath = FileHelper.getAbsoluteFilePathFromClassPath(keystore).toFile().getParent(); - + final KeyStore myTrustStore = KeyStore.getInstance("JKS"); myTrustStore.load(new FileInputStream(keyStorePath+"/truststore.jks"), "changeit".toCharArray()); @@ -399,7 +399,7 @@ public TlsDetails create(final SSLEngine sslEngine) { return hcb.setDefaultRequestConfig(requestConfigBuilder.build()).disableAutomaticRetries().build(); } - + public static class HttpResponse { private final SimpleHttpResponse inner; private final String body; @@ -473,7 +473,7 @@ public String toString() { } /** - * Given a json path with dots delimiated returns the object at the leaf + * Given a json path with dots delimiated returns the object at the leaf */ public String findValueInJson(final String jsonDotPath) { // Make sure its json / then parse it @@ -539,5 +539,5 @@ private static HttpResponse from(Future future) { } } - + } diff --git a/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java b/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java index b0ee40384d..c194d7e6de 100644 --- a/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java +++ b/src/test/java/org/opensearch/security/test/helper/rules/SecurityTestWatcher.java @@ -30,7 +30,7 @@ import org.junit.runner.Description; public class SecurityTestWatcher extends TestWatcher{ - + @Override protected void starting(final Description description) { final String methodName = description.getMethodName(); diff --git a/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java b/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java index ae6f5116a1..f0059d50fb 100644 --- a/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java +++ b/src/test/java/org/opensearch/security/test/plugin/UserInjectorPlugin.java @@ -58,12 +58,12 @@ * @author jkressin */ public class UserInjectorPlugin extends Plugin implements NetworkPlugin { - + Settings settings; private final SharedGroupFactory sharedGroupFactory; ThreadPool threadPool; - - public UserInjectorPlugin(final Settings settings, final Path configPath) { + + public UserInjectorPlugin(final Settings settings, final Path configPath) { this.settings = settings; sharedGroupFactory = new SharedGroupFactory(settings); } @@ -77,17 +77,17 @@ public Map> getHttpTransports(Settings set return ImmutableMap.of("org.opensearch.security.http.UserInjectingServerTransport", () -> new UserInjectingServerTransport(settings, networkService, bigArrays, threadPool, xContentRegistry, validatingDispatcher, clusterSettings, sharedGroupFactory)); } - + class UserInjectingServerTransport extends Netty4HttpServerTransport { - + public UserInjectingServerTransport(final Settings settings, final NetworkService networkService, final BigArrays bigArrays, final ThreadPool threadPool, final NamedXContentRegistry namedXContentRegistry, final Dispatcher dispatcher, ClusterSettings clusterSettings, SharedGroupFactory sharedGroupFactory) { super(settings, networkService, bigArrays, threadPool, namedXContentRegistry, dispatcher, clusterSettings, sharedGroupFactory); } } - + class UserInjectingDispatcher implements Dispatcher { - + private Dispatcher originalDispatcher; public UserInjectingDispatcher(final Dispatcher originalDispatcher) { @@ -99,7 +99,7 @@ public UserInjectingDispatcher(final Dispatcher originalDispatcher) { public void dispatchRequest(RestRequest request, RestChannel channel, ThreadContext threadContext) { threadContext.putTransient(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER, request.header(ConfigConstants.OPENDISTRO_SECURITY_INJECTED_USER)); originalDispatcher.dispatchRequest(request, channel, threadContext); - + } @Override