This is an automated email from the ASF dual-hosted git repository.

krisden pushed a commit to branch branch_9_0
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9_0 by this push:
     new 2f69a9f  SOLR-13989: Create hadoop-auth module
2f69a9f is described below

commit 2f69a9ff7079e5c799ee61108a69f1e650102828
Author: Kevin Risden <[email protected]>
AuthorDate: Mon Feb 14 13:06:45 2022 -0500

    SOLR-13989: Create hadoop-auth module
---
 gradle/documentation/render-javadoc.gradle         |   5 +-
 gradle/validation/rat-sources.gradle               |   4 +
 gradle/validation/spotless.gradle                  |   1 +
 settings.gradle                                    |   9 +-
 solr/CHANGES.txt                                   |   2 +
 solr/core/build.gradle                             |  24 +-
 .../org/apache/solr/core/SolrResourceLoader.java   |   2 +-
 .../src/java/org/apache/solr/update/UpdateLog.java |   6 -
 .../SSLCredentialProviderFactory.java              |   4 +-
 solr/core/src/test-files/log4j2.xml                |   2 -
 .../VMParamsZkACLAndCredentialsProvidersTest.java  | 306 +--------------------
 .../util/configuration/SSLConfigurationsTest.java  |  84 +-----
 solr/modules/hadoop-auth/README.md                 |  29 ++
 solr/modules/hadoop-auth/build.gradle              | 119 ++++++++
 .../hadoop}/AttributeOnlyServletContext.java       |   2 +-
 .../ConfigurableInternodeAuthHadoopPlugin.java     |   3 +-
 .../hadoop}/DelegationTokenKerberosFilter.java     |   2 +-
 .../solr/security/hadoop}/HadoopAuthFilter.java    |   2 +-
 .../solr/security/hadoop}/HadoopAuthPlugin.java    |   7 +-
 .../solr/security/hadoop}/KerberosFilter.java      |   5 +-
 .../solr/security/hadoop}/KerberosPlugin.java      |   4 +-
 ...uestContinuesRecorderAuthenticationHandler.java |   4 +-
 .../apache/solr/security/hadoop/package-info.java} |  19 +-
 .../hadoop}/HadoopSSLCredentialProvider.java       |   3 +-
 .../providers/hadoop/package-info.java}            |  19 +-
 .../hadoop-auth}/src/test-files/core-site.xml      |   0
 .../hadoop-auth/src/test-files/krb5-template.conf  |  11 +
 .../hadoop-auth}/src/test-files/log4j2.xml         |   0
 .../security/hadoop_kerberos_authz_config.json     |   2 +-
 .../solr/security/hadoop_kerberos_config.json      |   4 +-
 .../hadoop_simple_auth_with_delegation.json        |   4 +-
 .../client/solrj/impl/Krb5HttpClientUtils.java     |   0
 .../hadoop/HadoopAuthFakeGroupMapping.java         |   0
 .../solr/security/hadoop/HadoopTestUtil.java       |   0
 .../hadoop}/HttpParamDelegationTokenPlugin.java    |   2 +-
 .../solr/security/hadoop/ImpersonationUtil.java    |   2 -
 .../hadoop/ImpersonatorCollectionsHandler.java     |   2 -
 .../security/hadoop}/KerberosTestServices.java     |   2 +-
 .../apache/solr/security/hadoop/KerberosUtils.java |   2 -
 .../apache/solr/security/hadoop}/LocaleTest.java   |   2 +-
 .../security/hadoop}/SaslZkACLProviderTest.java    |   9 +-
 .../hadoop/TestDelegationWithHadoopAuth.java       |   0
 .../hadoop/TestImpersonationWithHadoopAuth.java    |   3 +-
 .../TestRuleBasedAuthorizationWithKerberos.java    |   3 +-
 .../hadoop}/TestSolrCloudWithDelegationTokens.java |   9 +-
 .../hadoop/TestSolrCloudWithHadoopAuthPlugin.java  |   1 -
 .../hadoop}/TestSolrCloudWithKerberosAlt.java      |   6 +-
 .../TestSolrCloudWithSecureImpersonation.java      |  12 +-
 .../security/hadoop/TestZkAclsWithHadoopAuth.java  |   0
 .../util/configuration/SSLConfigurationsTest.java  | 131 +++++++++
 .../hadoop}/HadoopSSLCredentialProviderTest.java   |   5 +-
 solr/modules/hdfs/build.gradle                     |   6 +-
 .../solr/core/snapshots/SolrSnapshotsTool.java     |   0
 solr/packaging/build.gradle                        |   1 +
 .../authentication-and-authorization-plugins.adoc  |   2 +-
 .../pages/kerberos-authentication-plugin.adoc      |   2 +-
 .../pages/major-changes-in-solr-9.adoc             |   3 +
 solr/test-framework/build.gradle                   |   1 +
 ...aramsZkACLAndCredentialsProvidersTestBase.java} |   8 +-
 .../core/MockQuerySenderListenerReqHandler.java    |   0
 .../component/DummyCustomParamSpellChecker.java    |   0
 .../org/apache/solr/search/FooQParserPlugin.java   |   0
 .../src/java/org/apache/solr/search/package.html   |  23 ++
 .../org/apache/solr/spelling/SampleComparator.java |   0
 .../src/java/org/apache/solr/spelling/package.html |  23 ++
 65 files changed, 429 insertions(+), 519 deletions(-)

diff --git a/gradle/documentation/render-javadoc.gradle 
b/gradle/documentation/render-javadoc.gradle
index 5e1b321..b111cdc 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -153,10 +153,12 @@ configure(project(":solr:test-framework")) {
         "org.apache.solr.handler.component",
         "org.apache.solr.update.processor",
         "org.apache.solr.util",
+        "org.apache.solr.search",
         "org.apache.solr.search.similarities",
         "org.apache.solr.search.function",
         "org.apache.solr.search.facet",
-        "org.apache.solr.schema"
+        "org.apache.solr.schema",
+        "org.apache.solr.spelling"
     ]
   }
 }
@@ -167,6 +169,7 @@ configure(project(":solr:modules:hdfs")) {
     javadocMissingIgnore = [
         "org.apache.solr.core",
         "org.apache.solr.core.backup.repository",
+        "org.apache.solr.core.snapshots",
         "org.apache.solr.update",
         "org.apache.solr.util"
     ]
diff --git a/gradle/validation/rat-sources.gradle 
b/gradle/validation/rat-sources.gradle
index b6ba8bf..f082b20 100644
--- a/gradle/validation/rat-sources.gradle
+++ b/gradle/validation/rat-sources.gradle
@@ -103,6 +103,10 @@ allprojects {
                     exclude "src/test-files/META-INF/services/*"
                     break
 
+                case ":solr:modules:hadoop-auth":
+                    exclude "src/test-files/**/*.conf"
+                    break
+
                 case ":solr:modules:hdfs":
                     exclude "src/test-files/**/*.aff"
                     exclude "src/test-files/**/*.dic"
diff --git a/gradle/validation/spotless.gradle 
b/gradle/validation/spotless.gradle
index 0f6f5b0..8f4f0f5 100644
--- a/gradle/validation/spotless.gradle
+++ b/gradle/validation/spotless.gradle
@@ -49,6 +49,7 @@ configure(project(":solr").subprojects) { prj ->
           case ":solr:modules:clustering":
           case ":solr:modules:extraction":
           case ":solr:modules:gcs-repository":
+          case ":solr:modules:hadoop-auth":
           case ":solr:modules:hdfs":
           case ":solr:modules:langid":
           case ":solr:modules:ltr":
diff --git a/settings.gradle b/settings.gradle
index 9a2dcd7..02b4b27 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -33,14 +33,15 @@ include "solr:modules:analysis-extras"
 include "solr:modules:analytics"
 include "solr:modules:clustering"
 include "solr:modules:extraction"
-include "solr:modules:langid"
+include "solr:modules:gcs-repository"
+include "solr:modules:hadoop-auth"
+include "solr:modules:hdfs"
 include "solr:modules:jaegertracer-configurator"
 include "solr:modules:jwt-auth"
+include "solr:modules:langid"
+include "solr:modules:ltr"
 include "solr:modules:s3-repository"
 include "solr:modules:scripting"
-include "solr:modules:ltr"
-include "solr:modules:gcs-repository"
-include "solr:modules:hdfs"
 include "solr:webapp"
 include "solr:benchmark"
 include "solr:test-framework"
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c14cb7f..38db731 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -52,6 +52,8 @@ New Features
 
 * SOLR-14660: Move HDFS support to a new HDFS module (Istvan Farkas, Kevin 
Risden)
 
+* SOLR-13989: Move Hadoop Authentication support to a new hadoop-auth module 
(Kevin Risden)
+
 Improvements
 ----------------------
 * LUCENE-8984: MoreLikeThis MLT is biased for uncommon fields (Andy Hind via 
Anshum Gupta)
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index ae9d012..11ada69 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -103,7 +103,7 @@ dependencies {
   compileOnlyApi 'org.eclipse.jetty:jetty-servlet'
   compileOnlyApi 'org.eclipse.jetty:jetty-util'
 
-  // ZooKeeper & Curator
+  // ZooKeeper
   implementation('org.apache.zookeeper:zookeeper', {
     exclude group: "org.apache.yetus", module: "audience-annotations"
     exclude group: "log4j", module: "log4j"
@@ -114,9 +114,6 @@ dependencies {
   }
   // required for instantiating a Zookeeper server (for embedding ZK or 
running tests)
   runtimeOnly ('org.xerial.snappy:snappy-java')
-  implementation ('org.apache.curator:curator-client')
-  implementation ('org.apache.curator:curator-framework')
-  runtimeOnly ('org.apache.curator:curator-recipes')
 
   // For Package Manager
   implementation 'com.github.zafarkhaja:java-semver'
@@ -169,25 +166,6 @@ dependencies {
   implementation ('org.apache.calcite.avatica:avatica-core') { transitive = 
false }
   permitUnusedDeclared 'org.apache.calcite.avatica:avatica-core'
 
-  // Hadoop auth framework
-  implementation 'org.apache.hadoop:hadoop-annotations'
-  permitUnusedDeclared 'org.apache.hadoop:hadoop-annotations'
-  implementation ('org.apache.hadoop:hadoop-auth') { transitive = false }
-  implementation ('org.apache.hadoop:hadoop-common') { transitive = false }
-  // transitive of hadoop-common; used by Kerberos auth
-  runtimeOnly 'commons-collections:commons-collections'
-  runtimeOnly 'com.google.re2j:re2j'
-  runtimeOnly 'org.apache.commons:commons-configuration2'
-  runtimeOnly 'org.apache.htrace:htrace-core4' // note: removed in Hadoop 3.3.2
-  runtimeOnly 'org.apache.kerby:kerb-core'
-  runtimeOnly 'org.apache.kerby:kerb-util'
-
-  // Hadoop MiniKdc Dependencies (for Kerberos auth tests)
-  testImplementation ('org.apache.hadoop:hadoop-minikdc', {
-    exclude group:'org.apache.kerby', module:'kerby-xdr'
-    exclude group:'org.apache.kerby', module:'token-provider'
-  })
-
   testRuntimeOnly 'org.slf4j:jcl-over-slf4j'
 
   testRuntimeOnly "org.apache.lucene:lucene-analysis-icu"
diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java 
b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
index 2109694..655e80d 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
@@ -88,7 +88,7 @@ public class SolrResourceLoader implements ResourceLoader, 
Closeable, SolrClassL
       "", "analysis.", "schema.", "handler.", "handler.tagger.", "search.", 
"update.", "core.", "response.", "request.",
       "update.processor.", "util.", "spelling.", "handler.component.",
       "spelling.suggest.", "spelling.suggest.fst.", "rest.schema.analysis.", 
"security.", "handler.admin.",
-      "security.jwt."
+      "security.jwt.", "security.hadoop."
   };
   private static final Charset UTF_8 = StandardCharsets.UTF_8;
   public static final String SOLR_ALLOW_UNSAFE_RESOURCELOADING_PARAM = 
"solr.allow.unsafe.resourceloading";
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateLog.java 
b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
index 87be666..e27a166 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateLog.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateLog.java
@@ -50,7 +50,6 @@ import java.util.stream.Stream;
 
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.Meter;
-import org.apache.hadoop.fs.FileSystem;
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.common.SolrDocumentBase;
 import org.apache.solr.common.SolrException;
@@ -107,11 +106,6 @@ public class UpdateLog implements PluginInfoInitialized, 
SolrMetricProducer {
   private boolean trace = log.isTraceEnabled();
   private boolean usableForChildDocs;
 
-  // TODO: hack
-  public FileSystem getFs() {
-    return null;
-  }
-
   public enum SyncLevel { NONE, FLUSH, FSYNC;
     public static SyncLevel getSyncLevel(String level){
       if (level == null) {
diff --git 
a/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
 
b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
index 55c2f44..7ea6717 100644
--- 
a/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
+++ 
b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
@@ -26,7 +26,6 @@ import java.util.Map;
 
 import com.google.common.collect.ImmutableMap;
 import org.apache.solr.util.configuration.providers.EnvSSLCredentialProvider;
-import 
org.apache.solr.util.configuration.providers.HadoopSSLCredentialProvider;
 import 
org.apache.solr.util.configuration.providers.SysPropSSLCredentialProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,8 +40,7 @@ public class SSLCredentialProviderFactory {
 
   private static final Map<String, Class<? extends SSLCredentialProvider>> 
defaultProviders = ImmutableMap.of(
       "env", EnvSSLCredentialProvider.class,
-      "sysprop", SysPropSSLCredentialProvider.class,
-      "hadoop", HadoopSSLCredentialProvider.class
+      "sysprop", SysPropSSLCredentialProvider.class
   );
 
   private String providerChain;
diff --git a/solr/core/src/test-files/log4j2.xml 
b/solr/core/src/test-files/log4j2.xml
index 0e8f08c..689aa96 100644
--- a/solr/core/src/test-files/log4j2.xml
+++ b/solr/core/src/test-files/log4j2.xml
@@ -30,9 +30,7 @@
   <Loggers>
     <!-- Use <AsyncLogger/<AsyncRoot and <Logger/<Root for asynchronous 
logging or synchonous logging respectively -->
     <Logger name="org.apache.zookeeper" level="WARN"/>
-    <Logger name="org.apache.hadoop" level="WARN"/>
     <Logger name="org.apache.directory" level="WARN"/>
-    <Logger name="org.apache.solr.hadoop" level="INFO"/>
     <Logger name="org.eclipse.jetty" level="INFO"/>
     <Logger name="org.apache.calcite" level="INFO"/>
 
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
 
b/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
index 3b441bf..32de743 100644
--- 
a/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
+++ 
b/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
@@ -16,310 +16,6 @@
  */
 package org.apache.solr.cloud;
 
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.util.Properties;
-
-import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
-import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider;
-import 
org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException.NoAuthException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.zookeeper.ZooDefs.Ids.OPEN_ACL_UNSAFE;
-
-public class VMParamsZkACLAndCredentialsProvidersTest extends SolrTestCaseJ4 {
-  
-  private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-  
-  private static final Charset DATA_ENCODING = StandardCharsets.UTF_8;
-  
-  protected ZkTestServer zkServer;
-  
-  protected Path zkDir;
-  
-  @BeforeClass
-  public static void beforeClass() {
-    System.setProperty("solrcloud.skip.autorecovery", "true");
-  }
-  
-  @AfterClass
-  public static void afterClass() throws InterruptedException {
-    System.clearProperty("solrcloud.skip.autorecovery");
-  }
-  
-  @Override
-  public void setUp() throws Exception {
-    super.setUp();
-    if (log.isInfoEnabled()) {
-      log.info("####SETUP_START {}", getTestName());
-    }
-    createTempDir();
-    
-    zkDir = createTempDir().resolve("zookeeper/server1/data");
-    log.info("ZooKeeper dataDir:{}", zkDir);
-    zkServer = new ZkTestServer(zkDir);
-    zkServer.run(false);
-    
-    System.setProperty("zkHost", zkServer.getZkAddress());
-
-    setSecuritySystemProperties();
-
-    SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(),
-        AbstractZkTestCase.TIMEOUT, AbstractZkTestCase.TIMEOUT, null, null, 
null);
-    zkClient.makePath("/solr", false, true);
-    zkClient.close();
-
-    zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT);
-    zkClient.create("/protectedCreateNode", "content".getBytes(DATA_ENCODING), 
CreateMode.PERSISTENT, false);
-    zkClient.makePath("/protectedMakePathNode", 
"content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
-
-    zkClient.create(SecurityAwareZkACLProvider.SECURITY_ZNODE_PATH, 
"content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
-    zkClient.close();
-    
-    clearSecuritySystemProperties();
-
-    zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT);
-    // Currently no credentials on ZK connection, because those same VM-params 
are used for adding ACLs, and here we want
-    // no (or completely open) ACLs added. Therefore hack your way into being 
authorized for creating anyway
-    zkClient.getSolrZooKeeper().addAuthInfo("digest", 
("connectAndAllACLUsername:connectAndAllACLPassword")
-        .getBytes(StandardCharsets.UTF_8));
-    zkClient.create("/unprotectedCreateNode", 
"content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
-    zkClient.makePath("/unprotectedMakePathNode", 
"content".getBytes(DATA_ENCODING), CreateMode.PERSISTENT, false);
-    zkClient.close();
-
-    if (log.isInfoEnabled()) {
-      log.info("####SETUP_END {}", getTestName());
-    }
-  }
-  
-  @Override
-  public void tearDown() throws Exception {
-    zkServer.shutdown();
-    
-    clearSecuritySystemProperties();
-    
-    super.tearDown();
-  }
-  
-  @Test
-  public void testNoCredentials() throws Exception {
-    useNoCredentials();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-              false, false, false, false, false,
-              false, false, false, false, false);
-    }
-  }
-
-  @Test
-  public void testWrongCredentials() throws Exception {
-    useWrongCredentials();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-              false, false, false, false, false,
-              false, false, false, false, false);
-    }
-  }
-
-  @Test
-  public void testAllCredentials() throws Exception {
-    useAllCredentials();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-              true, true, true, true, true,
-              true, true, true, true, true);
-    }
-  }
-  
-  @Test
-  public void testReadonlyCredentials() throws Exception {
-    useReadonlyCredentials();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-              true, true, false, false, false,
-              false, false, false, false, false);
-    }
-  }
-
-  @Test
-  public void testReadonlyCredentialsFromFile() throws Exception {
-    useReadonlyCredentialsFromFile();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-          true, true, false, false, false,
-          false, false, false, false, false);
-    }
-  }
-
-  @Test
-  public void testAllCredentialsFromFile() throws Exception {
-    useAllCredentialsFromFile();
-
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      doTest(zkClient,
-          true, true, true, true, true,
-          true, true, true, true, true);
-    }
-  }
-
-  @Test
-  public void testRepairACL() throws Exception {
-    clearSecuritySystemProperties();
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      // Currently no credentials on ZK connection, because those same 
VM-params are used for adding ACLs, and here we want
-      // no (or completely open) ACLs added. Therefore hack your way into 
being authorized for creating anyway
-      zkClient.getSolrZooKeeper().addAuthInfo("digest", 
("connectAndAllACLUsername:connectAndAllACLPassword")
-          .getBytes(StandardCharsets.UTF_8));
-
-      zkClient.create("/security.json", "{}".getBytes(StandardCharsets.UTF_8), 
CreateMode.PERSISTENT, false);
-      assertEquals(OPEN_ACL_UNSAFE, zkClient.getACL("/security.json", null, 
false));
-    }
-
-    setSecuritySystemProperties();
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      ZkController.createClusterZkNodes(zkClient);
-      assertNotEquals(OPEN_ACL_UNSAFE, zkClient.getACL("/security.json", null, 
false));
-    }
-
-    useReadonlyCredentials();
-    try (SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT)) {
-      NoAuthException e = assertThrows(NoAuthException.class, () -> 
zkClient.getData("/security.json", null, null, false));
-      assertEquals("/security.json", e.getPath());
-    }
-  }
-    
-  protected static void doTest(
-      SolrZkClient zkClient,
-      boolean getData, boolean list, boolean create, boolean setData, boolean 
delete,
-      boolean secureGet, boolean secureList, boolean secureCreate, boolean 
secureSet, boolean secureDelete) throws Exception {
-    doTest(zkClient, "/protectedCreateNode", getData, list, create, setData, 
delete);
-    doTest(zkClient, "/protectedMakePathNode", getData, list, create, setData, 
delete);
-    doTest(zkClient, "/unprotectedCreateNode", true, true, true, true, delete);
-    doTest(zkClient, "/unprotectedMakePathNode", true, true, true, true, 
delete);
-    doTest(zkClient, SecurityAwareZkACLProvider.SECURITY_ZNODE_PATH, 
secureGet, secureList, secureCreate, secureSet, secureDelete);
-  }
-  
-  protected static void doTest(SolrZkClient zkClient, String path, boolean 
getData, boolean list, boolean create, boolean setData, boolean delete) throws 
Exception {
-    doTest(getData, () -> zkClient.getData(path, null, null, false));
-    doTest(list, () -> zkClient.getChildren(path, null, false));
-
-    doTest(create, () -> {
-      zkClient.create(path + "/subnode", null, CreateMode.PERSISTENT, false);
-      zkClient.delete(path + "/subnode", -1, false);
-    });
-    doTest(create, () -> {
-      zkClient.makePath(path + "/subnode/subsubnode", false);
-      zkClient.delete(path + "/subnode/subsubnode", -1, false);
-      zkClient.delete(path + "/subnode", -1, false);
-    });
-
-    doTest(setData, () -> zkClient.setData(path, (byte[])null, false));
-
-    // Actually about the ACLs on /solr, but that is protected
-    doTest(delete, () -> zkClient.delete(path, -1, false));
-  }
-
-  interface ExceptingRunnable {
-    void run() throws Exception;
-  }
-
-  private static void doTest(boolean shouldSucceed, ExceptingRunnable action) 
throws Exception {
-    if (shouldSucceed) {
-      action.run();
-    } else {
-      expectThrows(NoAuthException.class, action::run);
-    }
-  }
-  
-  private void useNoCredentials() {
-    clearSecuritySystemProperties();
-  }
-  
-  private void useWrongCredentials() {
-    clearSecuritySystemProperties();
-    
-    System.setProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsSingleSetCredentialsDigestZkCredentialsProvider.class.getName());
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
 "connectAndAllACLUsername");
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
 "connectAndAllACLPasswordWrong");
-  }
-  
-  private void useAllCredentials() {
-    clearSecuritySystemProperties();
-    
-    System.setProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsSingleSetCredentialsDigestZkCredentialsProvider.class.getName());
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
 "connectAndAllACLUsername");
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
 "connectAndAllACLPassword");
-  }
-  
-  private void useReadonlyCredentials() {
-    clearSecuritySystemProperties();
-
-    System.setProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsSingleSetCredentialsDigestZkCredentialsProvider.class.getName());
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
 "readonlyACLUsername");
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
 "readonlyACLPassword");
-  }
-
-  private void useReadonlyCredentialsFromFile() throws IOException {
-    useCredentialsFromFile("readonlyACLUsername", "readonlyACLPassword");
-  }
-
-  private void useAllCredentialsFromFile() throws IOException {
-    useCredentialsFromFile("connectAndAllACLUsername", 
"connectAndAllACLPassword");
-  }
-
-  private void useCredentialsFromFile(String username, String password) throws 
IOException {
-    clearSecuritySystemProperties();
-
-    System.setProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsSingleSetCredentialsDigestZkCredentialsProvider.class.getName());
-
-    Properties props = new Properties();
-    
props.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
 username);
-    
props.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
 password);
-    saveCredentialsFile(props);
-  }
-
-  private void saveCredentialsFile(Properties props) throws IOException {
-    Path tmp = createTempFile("zk-creds", "properties");
-    try (FileWriter w = new FileWriter(tmp.toFile(), StandardCharsets.UTF_8)) {
-      props.store(w, "test");
-    }
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_FILE_VM_PARAM_NAME,
 tmp.toAbsolutePath().toString());
-  }
-  
-  private void setSecuritySystemProperties() {
-    System.setProperty(SolrZkClient.ZK_ACL_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsAllAndReadonlyDigestZkACLProvider.class.getName());
-    System.setProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME, 
VMParamsSingleSetCredentialsDigestZkCredentialsProvider.class.getName());
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
 "connectAndAllACLUsername");
-    
System.setProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
 "connectAndAllACLPassword");
-    
System.setProperty(VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_USERNAME_VM_PARAM_NAME,
 "readonlyACLUsername");
-    
System.setProperty(VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME,
 "readonlyACLPassword");
-  }
-  
-  private void clearSecuritySystemProperties() {
-    
System.clearProperty(SolrZkClient.ZK_ACL_PROVIDER_CLASS_NAME_VM_PARAM_NAME);
-    
System.clearProperty(SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME);
-    
System.clearProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME);
-    
System.clearProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME);
-    
System.clearProperty(VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_USERNAME_VM_PARAM_NAME);
-    
System.clearProperty(VMParamsAllAndReadonlyDigestZkACLProvider.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME);
-    
System.clearProperty(VMParamsSingleSetCredentialsDigestZkCredentialsProvider.DEFAULT_DIGEST_FILE_VM_PARAM_NAME);
-  }
+public class VMParamsZkACLAndCredentialsProvidersTest extends 
AbstractVMParamsZkACLAndCredentialsProvidersTestBase {
   
 }
diff --git 
a/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
 
b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
index 29ad4b8..25ecfd0 100644
--- 
a/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
+++ 
b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
@@ -22,22 +22,16 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.hadoop.conf.Configuration;
 import org.apache.lucene.util.TestRuleRestoreSystemProperties;
-import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.util.configuration.providers.EnvSSLCredentialProvider;
-import 
org.apache.solr.util.configuration.providers.HadoopSSLCredentialProvider;
 import 
org.apache.solr.util.configuration.providers.SysPropSSLCredentialProvider;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
-import org.mockito.Mockito;
 
-import static 
org.apache.hadoop.security.alias.CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
 
 public class SSLConfigurationsTest {
   private Map<String, String> envs;
@@ -56,8 +50,7 @@ public class SSLConfigurationsTest {
       SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
       SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD,
       SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
-      SSLConfigurations.SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD,
-      CREDENTIAL_PROVIDER_PATH
+      SSLConfigurations.SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD
   );
 
   @Before
@@ -65,17 +58,6 @@ public class SSLConfigurationsTest {
     envs = new HashMap<>();
   }
 
-  private SSLConfigurations createSut(Configuration mockHadoopConfiguration) {
-    EnvSSLCredentialProvider envSSLCredentialProvider = new 
EnvSSLCredentialProvider();
-    envSSLCredentialProvider.setEnvVars(envs);
-    sut = new SSLConfigurations(Arrays.asList(
-        new HadoopSSLCredentialProvider(mockHadoopConfiguration),
-        envSSLCredentialProvider,
-        new SysPropSSLCredentialProvider())
-    );
-    return sut;
-  }
-
   private SSLConfigurations createSut() {
     EnvSSLCredentialProvider envSSLCredentialProvider = new 
EnvSSLCredentialProvider();
     envSSLCredentialProvider.setEnvVars(envs);
@@ -106,20 +88,6 @@ public class SSLConfigurationsTest {
   }
 
   @Test
-  public void testSslConfigKeystorePwFromKeystoreHadoopCredentialProvider() 
throws IOException {
-    
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
 SAMPLE_PW1)
-        .init();
-    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW1));
-  }
-
-  @Test
-  public void 
testSslConfigKeystorePwFromClientKeystoreHadoopCredentialProvider() throws 
IOException {
-    
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
 SAMPLE_PW2)
-        .init();
-    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW2));
-  }
-
-  @Test
   public void testSslConfigKeystorePwNotOverwrittenIfExists() {
     System.setProperty(CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW3);
     envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, 
SAMPLE_PW1);
@@ -173,13 +141,6 @@ public class SSLConfigurationsTest {
   }
 
   @Test
-  public void testGetKeyStorePasswordFromHadoopCredentialProvider() throws 
IOException {
-    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
 SAMPLE_PW3);
-    assertThat(sut.getKeyStorePassword(), is(SAMPLE_PW3));
-  }
-
-
-  @Test
   public void testGetTrustStorePasswordFromProperty() {
     System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW1);
     assertThat(createSut().getTrustStorePassword(), is(SAMPLE_PW1));
@@ -192,12 +153,6 @@ public class SSLConfigurationsTest {
   }
 
   @Test
-  public void testGetTruststorePasswordFromHadoopCredentialProvider() throws 
IOException {
-    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD,
 SAMPLE_PW3);
-    assertThat(sut.getTrustStorePassword(), is(SAMPLE_PW3));
-  }
-
-  @Test
   public void testGetClientKeyStorePasswordFromProperty() {
     System.setProperty(CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW1);
     assertThat(createSut().getClientKeyStorePassword(), is(SAMPLE_PW1));
@@ -210,13 +165,6 @@ public class SSLConfigurationsTest {
   }
 
   @Test
-  public void testGetClientKeyStorePasswordFromHadoopCredentialProvider() 
throws IOException {
-    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
 SAMPLE_PW3);
-    assertThat(sut.getClientKeyStorePassword(), is(SAMPLE_PW3));
-  }
-
-
-  @Test
   public void testGetClientTrustStorePasswordFromProperty() {
     System.setProperty(CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW1);
     assertThat(createSut().getClientTrustStorePassword(), is(SAMPLE_PW1));
@@ -229,40 +177,10 @@ public class SSLConfigurationsTest {
   }
 
   @Test
-  public void testGetClientTruststorePasswordFromHadoopCredentialProvider() 
throws IOException {
-    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD,
 SAMPLE_PW3);
-    assertThat(sut.getClientTrustStorePassword(), is(SAMPLE_PW3));
-  }
-
-  @Test
   public void testSystemPropertyPriorityOverEnvVar() throws IOException {
     envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, 
SAMPLE_PW2);
     assertThat(createSut().getKeyStorePassword(), is(SAMPLE_PW2));
     System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW1);
     assertThat(createSut().getKeyStorePassword(), is(SAMPLE_PW2));
   }
-
-  @Test
-  public void testHadoopCredentialProviderPrioritySysPropAndEnvVars() throws 
IOException {
-    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, 
SAMPLE_PW2);
-    assertThat(createSut().getKeyStorePassword(), is(SAMPLE_PW2));
-    System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW1);
-    assertThat(createSut().getKeyStorePassword(), is(SAMPLE_PW2));
-    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(KEY_STORE_PASSWORD, SAMPLE_PW3);
-    assertThat(sut.getKeyStorePassword(), is(SAMPLE_PW3));
-  }
-
-  private SSLConfigurations getSutWithMockedHadoopCredentialProvider(String 
key, String pw) throws IOException {
-    Configuration mockHadoopConfiguration = getMockHadoopConfiguration();
-    when(mockHadoopConfiguration.getPassword(key))
-        .then(invocationOnMock -> 
invocationOnMock.getArguments()[0].equals(key) ? pw.toCharArray() : null);
-    System.setProperty(CREDENTIAL_PROVIDER_PATH, "/some/path"); // enables HCP
-    return createSut(mockHadoopConfiguration);
-  }
-
-  private Configuration getMockHadoopConfiguration() {
-    SolrTestCaseJ4.assumeWorkingMockito();
-    return Mockito.mock(Configuration.class);
-  }
-
 }
diff --git a/solr/modules/hadoop-auth/README.md 
b/solr/modules/hadoop-auth/README.md
new file mode 100644
index 0000000..b7d8265
--- /dev/null
+++ b/solr/modules/hadoop-auth/README.md
@@ -0,0 +1,29 @@
+Apache Solr Hadoop Authentication Module
+===============================
+
+Introduction
+------------
+This module implements the support for Hadoop Authentication in Apache Solr. 
+
+Building
+--------
+The Hadoop Authentication module uses the same Gradle build as the core Solr 
components. 
+
+To build the module, you can use
+
+```
+./gradlew :solr:modules:hadoop-auth:assemble
+```
+
+The resulting module will be placed to the libs directory, for example:
+`solr/modules/hdfs/build/libs/solr-hadoop-auth-9.0.0-SNAPSHOT.jar`
+
+To execute the module tests:
+
+```
+./gradlew :solr:modules:hadoop-auth:test
+```
+
+Usage
+-----
+Please refer to the 'Hadoop Authentication Plugin' and 'Kerberos 
Authentication Plugin' sections of the reference guide: 
https://solr.apache.org/guide/solr/latest/deployment-guide/hadoop-authentication-plugin.html
 and 
https://solr.apache.org/guide/solr/latest/deployment-guide/kerberos-authentication-plugin.html
diff --git a/solr/modules/hadoop-auth/build.gradle 
b/solr/modules/hadoop-auth/build.gradle
new file mode 100644
index 0000000..7f051f6
--- /dev/null
+++ b/solr/modules/hadoop-auth/build.gradle
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+apply plugin: 'java-library'
+
+description = 'Hadoop Authentication Module'
+
+dependencies {
+  // Spotbugs Annotations are only needed for old findbugs
+  // annotation usage like in Zookeeper during compilation time.
+  // It is not included in the release so exclude from checks.
+  testCompileOnly 'com.github.spotbugs:spotbugs-annotations'
+  permitUnusedDeclared 'com.github.spotbugs:spotbugs-annotations'
+  // Exclude these from jar validation and license checks.
+  configurations.jarValidation {
+    exclude group: "com.github.spotbugs", module: "spotbugs-annotations"
+  }
+
+  implementation project(':solr:core')
+  implementation project(':solr:solrj')
+
+  implementation 'org.slf4j:slf4j-api'
+
+  implementation 'javax.servlet:javax.servlet-api'
+
+  implementation 'com.fasterxml.jackson.core:jackson-core'
+  implementation 'com.google.guava:guava'
+  implementation 'io.dropwizard.metrics:metrics-core'
+  implementation 'org.apache.httpcomponents:httpclient'
+  implementation 'org.apache.httpcomponents:httpcore'
+
+  implementation 'org.eclipse.jetty:jetty-client'
+
+  // ZooKeeper & Curator
+  implementation('org.apache.zookeeper:zookeeper', {
+    exclude group: "org.apache.yetus", module: "audience-annotations"
+    exclude group: "log4j", module: "log4j"
+    exclude group: "org.slf4j", module: "slf4j-log4j12"
+  })
+  implementation ('org.apache.zookeeper:zookeeper-jute') {
+    exclude group: 'org.apache.yetus', module: 'audience-annotations'
+  }
+  // required for instantiating a Zookeeper server (for embedding ZK or 
running tests)
+  runtimeOnly 'org.xerial.snappy:snappy-java'
+  implementation 'org.apache.curator:curator-client'
+  implementation 'org.apache.curator:curator-framework'
+  runtimeOnly 'org.apache.curator:curator-recipes'
+
+  // Hadoop auth framework
+  implementation 'org.apache.hadoop:hadoop-annotations'
+  permitUnusedDeclared 'org.apache.hadoop:hadoop-annotations'
+  implementation ('org.apache.hadoop:hadoop-auth') { transitive = false }
+  implementation ('org.apache.hadoop:hadoop-common') { transitive = false }
+  // transitive of hadoop-common; used by Kerberos auth
+  runtimeOnly 'commons-collections:commons-collections'
+  runtimeOnly 'com.google.re2j:re2j'
+  runtimeOnly 'org.apache.commons:commons-configuration2'
+  runtimeOnly 'org.apache.htrace:htrace-core4' // note: removed in Hadoop 3.3.2
+  runtimeOnly 'org.apache.kerby:kerb-core'
+  runtimeOnly 'org.apache.kerby:kerb-util'
+
+  testImplementation project(':solr:test-framework')
+  testImplementation 'org.apache.lucene:lucene-test-framework'
+  testImplementation 
'com.carrotsearch.randomizedtesting:randomizedtesting-runner'
+  testImplementation 'junit:junit'
+  testImplementation 'org.hamcrest:hamcrest'
+
+  testImplementation('org.mockito:mockito-core', {
+    exclude group: "net.bytebuddy", module: "byte-buddy-agent"
+  })
+
+  testImplementation 'commons-io:commons-io'
+
+  testImplementation 'org.apache.lucene:lucene-core'
+
+  // classes like solr.ICUCollationField, used by 
TestSolrCloudWithSecureImpersonation for example.
+  testRuntimeOnly project(':solr:modules:analysis-extras')
+
+  // Hadoop MiniKdc Dependencies (for Kerberos auth tests)
+  testImplementation ('org.apache.hadoop:hadoop-minikdc', {
+    exclude group:'org.apache.kerby', module:'kerby-xdr'
+    exclude group:'org.apache.kerby', module:'token-provider'
+  })
+
+  // Zookeeper dependency - some tests like HdfsCloudBackupRestore need this
+  testImplementation 'org.apache.zookeeper:zookeeper'
+  // required for instantiating a Zookeeper server in tests or embedded
+  runtimeOnly ('org.xerial.snappy:snappy-java')
+}
+
+
+// Copy all the test resource files from core to the build/resources/test 
directory
+// of the Hadoop Authentication module so we can avoid duplication of the test
+// resource files like schemas and SolrConfigs. This can be improved later by 
making
+// the test classes load the resources from core directories directly.
+task copySolrCoreTestResources(type: Copy) {
+  from(project(':solr:core').sourceSets.test.resources.srcDirs) {
+    exclude '**/*.java'
+  }
+  into sourceSets.test.output.resourcesDir
+}
+
+tasks.processTestResources.configure {
+  dependsOn copySolrCoreTestResources
+}
diff --git 
a/solr/core/src/java/org/apache/solr/security/AttributeOnlyServletContext.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/AttributeOnlyServletContext.java
similarity index 99%
rename from 
solr/core/src/java/org/apache/solr/security/AttributeOnlyServletContext.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/AttributeOnlyServletContext.java
index 4abcd40..27831c5 100644
--- 
a/solr/core/src/java/org/apache/solr/security/AttributeOnlyServletContext.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/AttributeOnlyServletContext.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.InputStream;
 import java.net.MalformedURLException;
diff --git 
a/solr/core/src/java/org/apache/solr/security/ConfigurableInternodeAuthHadoopPlugin.java
 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/ConfigurableInternodeAuthHadoopPlugin.java
similarity index 97%
rename from 
solr/core/src/java/org/apache/solr/security/ConfigurableInternodeAuthHadoopPlugin.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/ConfigurableInternodeAuthHadoopPlugin.java
index 8ad112d..ca1bffb 100644
--- 
a/solr/core/src/java/org/apache/solr/security/ConfigurableInternodeAuthHadoopPlugin.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/ConfigurableInternodeAuthHadoopPlugin.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import org.apache.http.HttpRequest;
 import org.apache.http.client.methods.HttpRequestWrapper;
@@ -25,6 +25,7 @@ import 
org.apache.solr.client.solrj.impl.HttpClientBuilderFactory;
 import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.request.SolrRequestInfo;
+import org.apache.solr.security.HttpClientBuilderPlugin;
 import org.apache.solr.servlet.SolrDispatchFilter;
 import org.eclipse.jetty.client.api.Request;
 import org.slf4j.Logger;
diff --git 
a/solr/core/src/java/org/apache/solr/security/DelegationTokenKerberosFilter.java
 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/DelegationTokenKerberosFilter.java
similarity index 99%
rename from 
solr/core/src/java/org/apache/solr/security/DelegationTokenKerberosFilter.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/DelegationTokenKerberosFilter.java
index 68a97a15..2ee87ec 100644
--- 
a/solr/core/src/java/org/apache/solr/security/DelegationTokenKerberosFilter.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/DelegationTokenKerberosFilter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.IOException;
 import java.util.Enumeration;
diff --git a/solr/core/src/java/org/apache/solr/security/HadoopAuthFilter.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthFilter.java
similarity index 99%
rename from solr/core/src/java/org/apache/solr/security/HadoopAuthFilter.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthFilter.java
index 1b80070..10812ca 100644
--- a/solr/core/src/java/org/apache/solr/security/HadoopAuthFilter.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthFilter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.IOException;
 import java.util.LinkedList;
diff --git a/solr/core/src/java/org/apache/solr/security/HadoopAuthPlugin.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthPlugin.java
similarity index 97%
rename from solr/core/src/java/org/apache/solr/security/HadoopAuthPlugin.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthPlugin.java
index 2a68ee3..039be88 100644
--- a/solr/core/src/java/org/apache/solr/security/HadoopAuthPlugin.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/HadoopAuthPlugin.java
@@ -14,10 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
-import static 
org.apache.solr.security.RequestContinuesRecorderAuthenticationHandler.REQUEST_CONTINUES_ATTR;
-import static 
org.apache.solr.security.HadoopAuthFilter.DELEGATION_TOKEN_ZK_CLIENT;
+import static 
org.apache.solr.security.hadoop.RequestContinuesRecorderAuthenticationHandler.REQUEST_CONTINUES_ATTR;
+import static 
org.apache.solr.security.hadoop.HadoopAuthFilter.DELEGATION_TOKEN_ZK_CLIENT;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -45,6 +45,7 @@ import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.core.CoreContainer;
+import org.apache.solr.security.AuthenticationPlugin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/solr/core/src/java/org/apache/solr/security/KerberosFilter.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosFilter.java
similarity index 96%
rename from solr/core/src/java/org/apache/solr/security/KerberosFilter.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosFilter.java
index 6dd6c7f..7c44403 100644
--- a/solr/core/src/java/org/apache/solr/security/KerberosFilter.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosFilter.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -33,6 +33,9 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.hadoop.security.authentication.server.AuthenticationFilter;
 import org.apache.hadoop.security.authentication.server.AuthenticationHandler;
 import org.apache.solr.core.CoreContainer;
+import org.apache.solr.security.AuthorizationPlugin;
+import org.apache.solr.security.PermissionNameProvider;
+import org.apache.solr.security.RuleBasedAuthorizationPlugin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosPlugin.java
similarity index 98%
rename from solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosPlugin.java
index 5da7c29..5d6827e 100644
--- a/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/KerberosPlugin.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.lang.invoke.MethodHandles;
 import java.util.Collections;
@@ -47,6 +47,8 @@ import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.request.SolrRequestInfo;
+import org.apache.solr.security.AuthenticationPlugin;
+import org.apache.solr.security.HttpClientBuilderPlugin;
 import org.apache.solr.servlet.SolrDispatchFilter;
 import org.eclipse.jetty.client.api.Request;
 import org.slf4j.Logger;
diff --git 
a/solr/core/src/java/org/apache/solr/security/RequestContinuesRecorderAuthenticationHandler.java
 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/RequestContinuesRecorderAuthenticationHandler.java
similarity index 98%
rename from 
solr/core/src/java/org/apache/solr/security/RequestContinuesRecorderAuthenticationHandler.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/RequestContinuesRecorderAuthenticationHandler.java
index 344f805..10d4998 100644
--- 
a/solr/core/src/java/org/apache/solr/security/RequestContinuesRecorderAuthenticationHandler.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/RequestContinuesRecorderAuthenticationHandler.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.IOException;
 import java.util.Properties;
@@ -68,4 +68,4 @@ public class RequestContinuesRecorderAuthenticationHandler 
implements Authentica
       throws IOException, AuthenticationException {
     return authHandler.authenticate(request, response);
   }
-}
\ No newline at end of file
+}
diff --git a/solr/core/src/test/org/apache/solr/spelling/SampleComparator.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/package-info.java
similarity index 67%
copy from solr/core/src/test/org/apache/solr/spelling/SampleComparator.java
copy to 
solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/package-info.java
index 095edbb..65cdfbe 100644
--- a/solr/core/src/test/org/apache/solr/spelling/SampleComparator.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/security/hadoop/package-info.java
@@ -14,22 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.spelling;
-import org.apache.lucene.search.spell.SuggestWord;
-
-import java.util.Comparator;
-
 
 /**
- * Comparator for testing purposes
- *
- **/
-public class SampleComparator implements Comparator<SuggestWord> {
-
-
-  @Override
-  public int compare(SuggestWord suggestWord, SuggestWord suggestWord1) {
-    return suggestWord.string.compareTo(suggestWord1.string);
-  }
+ * Commonly used classes for Solr security framework.
+ */
+package org.apache.solr.security.hadoop;
 
-}
diff --git 
a/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProvider.java
similarity index 94%
rename from 
solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
rename to 
solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProvider.java
index ed92f38..77aa6e7 100644
--- 
a/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProvider.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.util.configuration.providers;
+package org.apache.solr.util.configuration.providers.hadoop;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -23,6 +23,7 @@ import java.util.EnumMap;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.solr.common.StringUtils;
+import 
org.apache.solr.util.configuration.providers.AbstractSSLCredentialProvider;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/solr/core/src/test/org/apache/solr/spelling/SampleComparator.java 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/package-info.java
similarity index 67%
copy from solr/core/src/test/org/apache/solr/spelling/SampleComparator.java
copy to 
solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/package-info.java
index 095edbb..0c11f90 100644
--- a/solr/core/src/test/org/apache/solr/spelling/SampleComparator.java
+++ 
b/solr/modules/hadoop-auth/src/java/org/apache/solr/util/configuration/providers/hadoop/package-info.java
@@ -14,22 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.spelling;
-import org.apache.lucene.search.spell.SuggestWord;
-
-import java.util.Comparator;
-
 
 /**
- * Comparator for testing purposes
- *
- **/
-public class SampleComparator implements Comparator<SuggestWord> {
-
-
-  @Override
-  public int compare(SuggestWord suggestWord, SuggestWord suggestWord1) {
-    return suggestWord.string.compareTo(suggestWord1.string);
-  }
+ * Commonly used classes for Solr security framework.
+ */
+package org.apache.solr.util.configuration.providers.hadoop;
 
-}
diff --git a/solr/core/src/test-files/core-site.xml 
b/solr/modules/hadoop-auth/src/test-files/core-site.xml
similarity index 100%
rename from solr/core/src/test-files/core-site.xml
rename to solr/modules/hadoop-auth/src/test-files/core-site.xml
diff --git a/solr/modules/hadoop-auth/src/test-files/krb5-template.conf 
b/solr/modules/hadoop-auth/src/test-files/krb5-template.conf
new file mode 100644
index 0000000..81c381e
--- /dev/null
+++ b/solr/modules/hadoop-auth/src/test-files/krb5-template.conf
@@ -0,0 +1,11 @@
+[libdefaults]
+    kdc_realm = _REALM_
+    default_realm = _REALM_
+    udp_preference_limit = _UDP_LIMIT_
+    allow_weak_crypto = true
+    #_KDC_TCP_PORT_
+    #_KDC_UDP_PORT_
+[realms]
+    _REALM_ = {
+        kdc = localhost:_KDC_PORT_
+    }
diff --git a/solr/core/src/test-files/log4j2.xml 
b/solr/modules/hadoop-auth/src/test-files/log4j2.xml
similarity index 100%
copy from solr/core/src/test-files/log4j2.xml
copy to solr/modules/hadoop-auth/src/test-files/log4j2.xml
diff --git 
a/solr/core/src/test-files/solr/security/hadoop_kerberos_authz_config.json 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_authz_config.json
similarity index 92%
rename from 
solr/core/src/test-files/solr/security/hadoop_kerberos_authz_config.json
rename to 
solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_authz_config.json
index 660418e..8799fed 100644
--- a/solr/core/src/test-files/solr/security/hadoop_kerberos_authz_config.json
+++ 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_authz_config.json
@@ -1,6 +1,6 @@
 {
   "authentication": {
-    "class": "org.apache.solr.security.ConfigurableInternodeAuthHadoopPlugin",
+    "class": "solr.ConfigurableInternodeAuthHadoopPlugin",
     "sysPropPrefix": "solr.",
     "type": "kerberos",
     "clientBuilderFactory": 
"org.apache.solr.client.solrj.impl.Krb5HttpClientBuilder",
diff --git a/solr/core/src/test-files/solr/security/hadoop_kerberos_config.json 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_config.json
similarity index 82%
rename from solr/core/src/test-files/solr/security/hadoop_kerberos_config.json
rename to 
solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_config.json
index 679474e..a25b706 100644
--- a/solr/core/src/test-files/solr/security/hadoop_kerberos_config.json
+++ 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_kerberos_config.json
@@ -1,6 +1,6 @@
 {
     "authentication": {
-        "class": 
"org.apache.solr.security.ConfigurableInternodeAuthHadoopPlugin",
+        "class": "solr.ConfigurableInternodeAuthHadoopPlugin",
         "sysPropPrefix": "solr.",
         "type": "kerberos",
         "clientBuilderFactory": 
"org.apache.solr.client.solrj.impl.Krb5HttpClientBuilder",
@@ -13,4 +13,4 @@
         "defaultConfigs": {
         }
     }
-}
\ No newline at end of file
+}
diff --git 
a/solr/core/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
similarity index 94%
rename from 
solr/core/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
rename to 
solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
index 2248329..c06c58a 100644
--- 
a/solr/core/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
+++ 
b/solr/modules/hadoop-auth/src/test-files/solr/security/hadoop_simple_auth_with_delegation.json
@@ -1,6 +1,6 @@
 {
     "authentication": {
-        "class": "org.apache.solr.security.HadoopAuthPlugin",
+        "class": "solr.HadoopAuthPlugin",
         "sysPropPrefix": "solr.",
         "type": "simple",
         "enableDelegationToken":"true",
@@ -26,4 +26,4 @@
             "cookie.domain": "127.0.0.1"
         }
     }
-}
\ No newline at end of file
+}
diff --git 
a/solr/core/src/test/org/apache/solr/client/solrj/impl/Krb5HttpClientUtils.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/client/solrj/impl/Krb5HttpClientUtils.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/client/solrj/impl/Krb5HttpClientUtils.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/client/solrj/impl/Krb5HttpClientUtils.java
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/HadoopAuthFakeGroupMapping.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HadoopAuthFakeGroupMapping.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/HadoopAuthFakeGroupMapping.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HadoopAuthFakeGroupMapping.java
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/HadoopTestUtil.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HadoopTestUtil.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/HadoopTestUtil.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HadoopTestUtil.java
diff --git 
a/solr/core/src/test/org/apache/solr/security/HttpParamDelegationTokenPlugin.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HttpParamDelegationTokenPlugin.java
similarity index 99%
rename from 
solr/core/src/test/org/apache/solr/security/HttpParamDelegationTokenPlugin.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HttpParamDelegationTokenPlugin.java
index a85b36a..27e353a 100644
--- 
a/solr/core/src/test/org/apache/solr/security/HttpParamDelegationTokenPlugin.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/HttpParamDelegationTokenPlugin.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.security;
+package org.apache.solr.security.hadoop;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java
similarity index 96%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java
index b1d3957..1d2c189 100644
--- a/solr/core/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonationUtil.java
@@ -26,8 +26,6 @@ import 
org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.security.HadoopAuthPlugin;
-import org.apache.solr.security.KerberosPlugin;
 
 /**
  * This class implements utility functions required to test the secure 
impersonation feature for {@linkplain HadoopAuthPlugin}
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
similarity index 95%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
index 2a2a469..51bbb16 100644
--- 
a/solr/core/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/ImpersonatorCollectionsHandler.java
@@ -25,8 +25,6 @@ import org.apache.solr.core.CoreContainer;
 import org.apache.solr.handler.admin.CollectionsHandler;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.security.HadoopAuthPlugin;
-import org.apache.solr.security.KerberosPlugin;
 import org.junit.Assert;
 
 /**
diff --git a/solr/core/src/test/org/apache/solr/cloud/KerberosTestServices.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosTestServices.java
similarity index 99%
rename from solr/core/src/test/org/apache/solr/cloud/KerberosTestServices.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosTestServices.java
index e3ac813..3e619cd 100644
--- a/solr/core/src/test/org/apache/solr/cloud/KerberosTestServices.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosTestServices.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import javax.security.auth.login.AppConfigurationEntry;
 import javax.security.auth.login.Configuration;
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/KerberosUtils.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosUtils.java
similarity index 98%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/KerberosUtils.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosUtils.java
index ac3077b..1db7c5b 100644
--- a/solr/core/src/test/org/apache/solr/security/hadoop/KerberosUtils.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/KerberosUtils.java
@@ -20,8 +20,6 @@ import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import org.apache.solr.cloud.KerberosTestServices;
-
 /**
  * A utility class which provides common functionality required to test 
kerberos integration.
  */
diff --git a/solr/core/src/test/org/apache/solr/cloud/LocaleTest.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/LocaleTest.java
similarity index 98%
rename from solr/core/src/test/org/apache/solr/cloud/LocaleTest.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/LocaleTest.java
index 040fe97..20f3cab 100644
--- a/solr/core/src/test/org/apache/solr/cloud/LocaleTest.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/LocaleTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import org.apache.hadoop.minikdc.MiniKdc;
 import org.apache.lucene.util.LuceneTestCase;
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/SaslZkACLProviderTest.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/SaslZkACLProviderTest.java
similarity index 95%
rename from solr/core/src/test/org/apache/solr/cloud/SaslZkACLProviderTest.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/SaslZkACLProviderTest.java
index c8a7fda..1dbe2b0 100644
--- a/solr/core/src/test/org/apache/solr/cloud/SaslZkACLProviderTest.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/SaslZkACLProviderTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import java.io.File;
 import java.io.IOException;
@@ -27,6 +27,9 @@ import org.apache.lucene.util.Constants;
 import org.apache.lucene.util.QuickPatchThreadsFilter;
 import org.apache.solr.SolrIgnoredThreadsFilter;
 import org.apache.solr.SolrTestCaseJ4;
+import 
org.apache.solr.cloud.AbstractVMParamsZkACLAndCredentialsProvidersTestBase;
+import org.apache.solr.cloud.AbstractZkTestCase;
+import org.apache.solr.cloud.ZkTestServer;
 import org.apache.solr.common.cloud.DefaultZkACLProvider;
 import org.apache.solr.common.cloud.SaslZkACLProvider;
 import org.apache.solr.common.cloud.SecurityAwareZkACLProvider;
@@ -132,7 +135,7 @@ public class SaslZkACLProviderTest extends SolrTestCaseJ4 {
     // Test with Sasl enabled
     SolrZkClient zkClient = new SolrZkClientWithACLs(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT);
     try {
-      VMParamsZkACLAndCredentialsProvidersTest.doTest(zkClient,
+      AbstractVMParamsZkACLAndCredentialsProvidersTestBase.doTest(zkClient,
           true, true, true, true, true,
           true, true, true, true, true);
      } finally {
@@ -144,7 +147,7 @@ public class SaslZkACLProviderTest extends SolrTestCaseJ4 {
     System.setProperty("zookeeper.sasl.client", "false");
     zkClient = new SolrZkClientNoACLs(zkServer.getZkAddress(), 
AbstractZkTestCase.TIMEOUT);
     try {
-      VMParamsZkACLAndCredentialsProvidersTest.doTest(zkClient,
+      AbstractVMParamsZkACLAndCredentialsProvidersTestBase.doTest(zkClient,
           true, true, false, false, false,
           false, false, false, false, false);
     } finally {
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestDelegationWithHadoopAuth.java
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
similarity index 98%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
index 049d756..91db855 100644
--- 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestImpersonationWithHadoopAuth.java
@@ -31,13 +31,12 @@ import 
org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.HadoopAuthPlugin;
 import org.apache.solr.servlet.SolrRequestParsers;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import static 
org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM;
+import static 
org.apache.solr.security.hadoop.HttpParamDelegationTokenPlugin.USER_PARAM;
 import static 
org.apache.solr.security.hadoop.ImpersonationUtil.getExpectedGroupExMsg;
 import static 
org.apache.solr.security.hadoop.ImpersonationUtil.getExpectedHostExMsg;
 import static 
org.apache.solr.security.hadoop.ImpersonationUtil.getProxyRequest;
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
similarity index 98%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
index fa89891..ec3a613 100644
--- 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestRuleBasedAuthorizationWithKerberos.java
@@ -26,7 +26,6 @@ import org.apache.solr.client.solrj.impl.Krb5HttpClientUtils;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.cloud.AbstractDistribZkTestBase;
-import org.apache.solr.cloud.KerberosTestServices;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.util.LogLevel;
@@ -117,4 +116,4 @@ public class TestRuleBasedAuthorizationWithKerberos extends 
SolrCloudTestCase {
         AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName,
                 solrClient.getZkStateReader(), true, 330);
     }
-}
\ No newline at end of file
+}
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithDelegationTokens.java
similarity index 98%
rename from 
solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithDelegationTokens.java
index e75f1b8..02c1df8 100644
--- 
a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithDelegationTokens.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import java.lang.invoke.MethodHandles;
 import java.util.Collections;
@@ -40,23 +40,22 @@ import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
 import org.apache.solr.client.solrj.response.DelegationTokenResponse;
 import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.cloud.MiniSolrCloudCluster;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.security.HttpParamDelegationTokenPlugin;
-import org.apache.solr.security.KerberosPlugin;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static 
org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM;
+import static 
org.apache.solr.security.hadoop.HttpParamDelegationTokenPlugin.USER_PARAM;
 
 /**
- * Test the delegation token support in the {@link 
org.apache.solr.security.KerberosPlugin}.
+ * Test the delegation token support in the {@link KerberosPlugin}.
  */
 @LuceneTestCase.Slow
 public class TestSolrCloudWithDelegationTokens extends SolrTestCaseJ4 {
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
similarity index 98%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
index 063f3dc..1030aed 100644
--- 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHadoopAuthPlugin.java
@@ -21,7 +21,6 @@ import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.cloud.AbstractDistribZkTestBase;
-import org.apache.solr.cloud.KerberosTestServices;
 import org.apache.solr.cloud.SolrCloudAuthTestCase;
 import org.apache.solr.common.SolrInputDocument;
 import org.junit.AfterClass;
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithKerberosAlt.java
similarity index 97%
rename from 
solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithKerberosAlt.java
index 80b55de..698d8a6 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithKerberosAlt.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import java.io.File;
 import java.lang.invoke.MethodHandles;
@@ -32,6 +32,8 @@ import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.cloud.AbstractDistribZkTestBase;
+import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.util.BadZookeeperThreadsFilter;
 import org.junit.Test;
 import org.slf4j.Logger;
@@ -98,7 +100,7 @@ public class TestSolrCloudWithKerberosAlt extends 
SolrCloudTestCase {
     System.setProperty("solr.kerberos.cookie.domain", "127.0.0.1");
     System.setProperty("solr.kerberos.principal", solrServerPrincipal);
     System.setProperty("solr.kerberos.keytab", keytabFile.getAbsolutePath());
-    System.setProperty("authenticationPlugin", 
"org.apache.solr.security.KerberosPlugin");
+    System.setProperty("authenticationPlugin", 
"org.apache.solr.security.hadoop.KerberosPlugin");
     boolean enableDt = random().nextBoolean();
     log.info("Enable delegation token: {}", enableDt);
     System.setProperty("solr.kerberos.delegation.token.enabled", 
Boolean.toString(enableDt));
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithSecureImpersonation.java
similarity index 96%
rename from 
solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithSecureImpersonation.java
index e4d8447..7d885f9 100644
--- 
a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithSecureImpersonation.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithSecureImpersonation.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.cloud;
+package org.apache.solr.security.hadoop;
 
 import javax.servlet.http.HttpServletRequest;
 import java.net.InetAddress;
@@ -32,7 +32,7 @@ import org.apache.solr.client.solrj.impl.BaseHttpSolrClient;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
-import org.apache.solr.security.hadoop.HadoopTestUtil;
+import org.apache.solr.cloud.MiniSolrCloudCluster;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.IOUtils;
@@ -40,17 +40,15 @@ import org.apache.solr.core.CoreContainer;
 import org.apache.solr.handler.admin.CollectionsHandler;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.security.HttpParamDelegationTokenPlugin;
-import org.apache.solr.security.KerberosPlugin;
 import org.apache.solr.servlet.SolrRequestParsers;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
-import static 
org.apache.solr.security.HttpParamDelegationTokenPlugin.REMOTE_ADDRESS_PARAM;
-import static 
org.apache.solr.security.HttpParamDelegationTokenPlugin.REMOTE_HOST_PARAM;
-import static 
org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM;
+import static 
org.apache.solr.security.hadoop.HttpParamDelegationTokenPlugin.REMOTE_ADDRESS_PARAM;
+import static 
org.apache.solr.security.hadoop.HttpParamDelegationTokenPlugin.REMOTE_HOST_PARAM;
+import static 
org.apache.solr.security.hadoop.HttpParamDelegationTokenPlugin.USER_PARAM;
 
 public class TestSolrCloudWithSecureImpersonation extends SolrTestCaseJ4 {
   private static final int NUM_SERVERS = 2;
diff --git 
a/solr/core/src/test/org/apache/solr/security/hadoop/TestZkAclsWithHadoopAuth.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestZkAclsWithHadoopAuth.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/security/hadoop/TestZkAclsWithHadoopAuth.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/security/hadoop/TestZkAclsWithHadoopAuth.java
diff --git 
a/solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
new file mode 100644
index 0000000..4e09691
--- /dev/null
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.util.configuration;
+
+import static 
org.apache.hadoop.security.alias.CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.lucene.util.TestRuleRestoreSystemProperties;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.util.configuration.providers.EnvSSLCredentialProvider;
+import 
org.apache.solr.util.configuration.providers.hadoop.HadoopSSLCredentialProvider;
+import 
org.apache.solr.util.configuration.providers.SysPropSSLCredentialProvider;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.mockito.Mockito;
+
+public class SSLConfigurationsTest {
+  private Map<String, String> envs;
+  private SSLConfigurations sut;
+
+  public static final String SAMPLE_PW1 = "pw123";
+  public static final String SAMPLE_PW2 = "pw456";
+  public static final String SAMPLE_PW3 = "pw789";
+  public static final String KEY_STORE_PASSWORD = 
SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD;
+  public static final String CLIENT_KEY_STORE_PASSWORD = 
SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD;
+
+  @Rule
+  public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
+      SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
+      SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
+      CREDENTIAL_PROVIDER_PATH
+  );
+
+  @Before
+  public void setUp() {
+    envs = new HashMap<>();
+  }
+
+  private SSLConfigurations createSut(Configuration mockHadoopConfiguration) {
+    EnvSSLCredentialProvider envSSLCredentialProvider = new 
EnvSSLCredentialProvider();
+    envSSLCredentialProvider.setEnvVars(envs);
+    sut = new SSLConfigurations(Arrays.asList(
+        new HadoopSSLCredentialProvider(mockHadoopConfiguration),
+        envSSLCredentialProvider,
+        new SysPropSSLCredentialProvider())
+    );
+    return sut;
+  }
+
+  @Test
+  public void testSslConfigKeystorePwFromKeystoreHadoopCredentialProvider() 
throws IOException {
+    
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
 SAMPLE_PW1)
+        .init();
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW1));
+  }
+
+  @Test
+  public void 
testSslConfigKeystorePwFromClientKeystoreHadoopCredentialProvider() throws 
IOException {
+    
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
 SAMPLE_PW2)
+        .init();
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @Test
+  public void testGetKeyStorePasswordFromHadoopCredentialProvider() throws 
IOException {
+    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
 SAMPLE_PW3);
+    assertThat(sut.getKeyStorePassword(), is(SAMPLE_PW3));
+  }
+
+  @Test
+  public void testGetTruststorePasswordFromHadoopCredentialProvider() throws 
IOException {
+    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD,
 SAMPLE_PW3);
+    assertThat(sut.getTrustStorePassword(), is(SAMPLE_PW3));
+  }
+
+  @Test
+  public void testGetClientKeyStorePasswordFromHadoopCredentialProvider() 
throws IOException {
+    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD,
 SAMPLE_PW3);
+    assertThat(sut.getClientKeyStorePassword(), is(SAMPLE_PW3));
+  }
+
+  @Test
+  public void testGetClientTruststorePasswordFromHadoopCredentialProvider() 
throws IOException {
+    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(SSLConfigurations.SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD,
 SAMPLE_PW3);
+    assertThat(sut.getClientTrustStorePassword(), is(SAMPLE_PW3));
+  }
+
+  @Test
+  public void testHadoopCredentialProviderPrioritySysPropAndEnvVars() throws 
IOException {
+    SSLConfigurations sut = 
getSutWithMockedHadoopCredentialProvider(KEY_STORE_PASSWORD, SAMPLE_PW3);
+    assertThat(sut.getKeyStorePassword(), is(SAMPLE_PW3));
+  }
+
+  private SSLConfigurations getSutWithMockedHadoopCredentialProvider(String 
key, String pw) throws IOException {
+    Configuration mockHadoopConfiguration = getMockHadoopConfiguration();
+    when(mockHadoopConfiguration.getPassword(key))
+        .then(invocationOnMock -> 
invocationOnMock.getArguments()[0].equals(key) ? pw.toCharArray() : null);
+    System.setProperty(CREDENTIAL_PROVIDER_PATH, "/some/path"); // enables HCP
+    return createSut(mockHadoopConfiguration);
+  }
+
+  private Configuration getMockHadoopConfiguration() {
+    SolrTestCaseJ4.assumeWorkingMockito();
+    return Mockito.mock(Configuration.class);
+  }
+}
diff --git 
a/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProviderTest.java
similarity index 95%
rename from 
solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
rename to 
solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProviderTest.java
index 3a554a3..e1d60ab 100644
--- 
a/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
+++ 
b/solr/modules/hadoop-auth/src/test/org/apache/solr/util/configuration/providers/hadoop/HadoopSSLCredentialProviderTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.util.configuration.providers;
+package org.apache.solr.util.configuration.providers.hadoop;
 
 import java.io.IOException;
 import java.util.Map;
@@ -33,7 +33,6 @@ import static 
org.apache.hadoop.security.alias.CredentialProviderFactory.CREDENT
 import static 
org.apache.solr.util.configuration.providers.AbstractSSLCredentialProvider.DEFAULT_CREDENTIAL_KEY_MAP;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
 
 /**
  */
@@ -61,7 +60,7 @@ public class HadoopSSLCredentialProviderTest {
 
   private Configuration getMockedHadoopCredentialProvider(String key, String 
pw) throws IOException {
     Configuration mockHadoopConfiguration = getMockHadoopConfiguration();
-    when(mockHadoopConfiguration.getPassword(key))
+    Mockito.when(mockHadoopConfiguration.getPassword(key))
         .then(invocationOnMock -> 
invocationOnMock.getArguments()[0].equals(key) ? pw.toCharArray() : null);
     System.setProperty(CREDENTIAL_PROVIDER_PATH, "/some/path"); // enables HCP
     return mockHadoopConfiguration;
diff --git a/solr/modules/hdfs/build.gradle b/solr/modules/hdfs/build.gradle
index a261f85..f88e7b3 100644
--- a/solr/modules/hdfs/build.gradle
+++ b/solr/modules/hdfs/build.gradle
@@ -46,7 +46,9 @@ dependencies {
   implementation 'com.google.guava:guava'
 
   // Caffeine cache to implement HDFS block caching  
-  implementation ('com.github.ben-manes.caffeine:caffeine')
+  implementation 'com.github.ben-manes.caffeine:caffeine'
+
+  implementation 'commons-cli:commons-cli'
 
   testImplementation project(':solr:test-framework')
   testImplementation 'org.apache.lucene:lucene-test-framework'
@@ -63,7 +65,7 @@ dependencies {
   testImplementation 'org.apache.logging.log4j:log4j-1.2-api'
 
   // classes like solr.ICUCollationField, used by NNFailoverTest for example.
-  testImplementation project(':solr:modules:analysis-extras')
+  testRuntimeOnly project(':solr:modules:analysis-extras')
 
   // required for instantiating a Zookeeper server in tests or embedded
   runtimeOnly ('org.xerial.snappy:snappy-java')
diff --git 
a/solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java 
b/solr/modules/hdfs/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java
similarity index 100%
rename from 
solr/core/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java
rename to 
solr/modules/hdfs/src/java/org/apache/solr/core/snapshots/SolrSnapshotsTool.java
diff --git a/solr/packaging/build.gradle b/solr/packaging/build.gradle
index da324d8..dc8eb4b 100644
--- a/solr/packaging/build.gradle
+++ b/solr/packaging/build.gradle
@@ -51,6 +51,7 @@ dependencies {
    ":solr:modules:extraction",
    ":solr:modules:clustering",
    ":solr:modules:gcs-repository",
+   ":solr:modules:hadoop-auth",
    ":solr:modules:hdfs",
    ":solr:modules:jaegertracer-configurator",
    ":solr:modules:jwt-auth",
diff --git 
a/solr/solr-ref-guide/modules/deployment-guide/pages/authentication-and-authorization-plugins.adoc
 
b/solr/solr-ref-guide/modules/deployment-guide/pages/authentication-and-authorization-plugins.adoc
index d6d5d93..c0940e3 100644
--- 
a/solr/solr-ref-guide/modules/deployment-guide/pages/authentication-and-authorization-plugins.adoc
+++ 
b/solr/solr-ref-guide/modules/deployment-guide/pages/authentication-and-authorization-plugins.adoc
@@ -87,7 +87,7 @@ Create the file `security.json` with the contents:
 
 [source,json]
 ----
-{"authentication": {"class": "org.apache.solr.security.KerberosPlugin"}}
+{"authentication": {"class": "solr.KerberosPlugin"}}
 ----
 
 Note that this example defines the `KerberosPlugin` for authentication.
diff --git 
a/solr/solr-ref-guide/modules/deployment-guide/pages/kerberos-authentication-plugin.adoc
 
b/solr/solr-ref-guide/modules/deployment-guide/pages/kerberos-authentication-plugin.adoc
index 5354f4a..d204fd8 100644
--- 
a/solr/solr-ref-guide/modules/deployment-guide/pages/kerberos-authentication-plugin.adoc
+++ 
b/solr/solr-ref-guide/modules/deployment-guide/pages/kerberos-authentication-plugin.adoc
@@ -191,7 +191,7 @@ Create the file `security.json` with the contents:
 
 [source,json]
 ----
-{"authentication": {"class": "org.apache.solr.security.KerberosPlugin"}}
+{"authentication": {"class": "solr.KerberosPlugin"}}
 ----
 
 Then use the `bin/solr zk` command to upload the file:
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
index a6fcd9e..a879b9b 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-9.adoc
@@ -125,6 +125,9 @@ This is only applicable for users returning information in 
JSON format, which is
 * SOLR-14660: HDFS storage support has been moved to a module. Existing Solr 
configurations do not need any HDFS-related
 changes, however the module needs to be installed - see the section 
xref:deployment-guide:solr-on-hdfs.adoc[].
 
+* SOLR-13989: Hadoop authentication support has been moved to the hadoop-auth 
module. Existing Solr configurations do not need any Hadoop authentication 
related
+changes, however the module needs to be installed - see the section 
xref:deployment-guide:hadoop-authentication-plugin.adoc[].
+
 * SOLR-15950: The folder $SOLR_HOME/userfiles, used by the "cat" streaming 
expression, is no longer created automatically on startup. The user must create 
this folder.
 
 * SOLR-15097: JWTAuthPlugin has been moved to a module. Users need to add the 
module to classpath. The plugin has also
diff --git a/solr/test-framework/build.gradle b/solr/test-framework/build.gradle
index 5bcb875..90e77a0 100644
--- a/solr/test-framework/build.gradle
+++ b/solr/test-framework/build.gradle
@@ -36,6 +36,7 @@ dependencies {
   api 'org.apache.lucene:lucene-test-framework'
   implementation 'org.apache.lucene:lucene-core'
   implementation 'org.apache.lucene:lucene-queries'
+  implementation "org.apache.lucene:lucene-suggest"
 
   implementation('org.apache.zookeeper:zookeeper', {
     exclude group: "org.apache.yetus", module: "audience-annotations"
diff --git 
a/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
 
b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractVMParamsZkACLAndCredentialsProvidersTestBase.java
similarity index 99%
copy from 
solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
copy to 
solr/test-framework/src/java/org/apache/solr/cloud/AbstractVMParamsZkACLAndCredentialsProvidersTestBase.java
index 3b441bf..415c2e9 100644
--- 
a/solr/core/src/test/org/apache/solr/cloud/VMParamsZkACLAndCredentialsProvidersTest.java
+++ 
b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractVMParamsZkACLAndCredentialsProvidersTestBase.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.cloud;
 
+import static org.apache.zookeeper.ZooDefs.Ids.OPEN_ACL_UNSAFE;
+
 import java.io.FileWriter;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -37,9 +39,7 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.zookeeper.ZooDefs.Ids.OPEN_ACL_UNSAFE;
-
-public class VMParamsZkACLAndCredentialsProvidersTest extends SolrTestCaseJ4 {
+public class AbstractVMParamsZkACLAndCredentialsProvidersTestBase extends 
SolrTestCaseJ4 {
   
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   
@@ -205,7 +205,7 @@ public class VMParamsZkACLAndCredentialsProvidersTest 
extends SolrTestCaseJ4 {
     }
   }
     
-  protected static void doTest(
+  public static void doTest(
       SolrZkClient zkClient,
       boolean getData, boolean list, boolean create, boolean setData, boolean 
delete,
       boolean secureGet, boolean secureList, boolean secureCreate, boolean 
secureSet, boolean secureDelete) throws Exception {
diff --git 
a/solr/core/src/test/org/apache/solr/core/MockQuerySenderListenerReqHandler.java
 
b/solr/test-framework/src/java/org/apache/solr/core/MockQuerySenderListenerReqHandler.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/core/MockQuerySenderListenerReqHandler.java
rename to 
solr/test-framework/src/java/org/apache/solr/core/MockQuerySenderListenerReqHandler.java
diff --git 
a/solr/core/src/test/org/apache/solr/handler/component/DummyCustomParamSpellChecker.java
 
b/solr/test-framework/src/java/org/apache/solr/handler/component/DummyCustomParamSpellChecker.java
similarity index 100%
rename from 
solr/core/src/test/org/apache/solr/handler/component/DummyCustomParamSpellChecker.java
rename to 
solr/test-framework/src/java/org/apache/solr/handler/component/DummyCustomParamSpellChecker.java
diff --git a/solr/core/src/test/org/apache/solr/search/FooQParserPlugin.java 
b/solr/test-framework/src/java/org/apache/solr/search/FooQParserPlugin.java
similarity index 100%
rename from solr/core/src/test/org/apache/solr/search/FooQParserPlugin.java
rename to 
solr/test-framework/src/java/org/apache/solr/search/FooQParserPlugin.java
diff --git a/solr/test-framework/src/java/org/apache/solr/search/package.html 
b/solr/test-framework/src/java/org/apache/solr/search/package.html
new file mode 100644
index 0000000..e0a971d
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/search/package.html
@@ -0,0 +1,23 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- not a package-info.java, because we already defined this package in core/ 
-->
+<html>
+<body>
+Mock classes for testing search.
+</body>
+</html>
diff --git a/solr/core/src/test/org/apache/solr/spelling/SampleComparator.java 
b/solr/test-framework/src/java/org/apache/solr/spelling/SampleComparator.java
similarity index 100%
rename from solr/core/src/test/org/apache/solr/spelling/SampleComparator.java
rename to 
solr/test-framework/src/java/org/apache/solr/spelling/SampleComparator.java
diff --git a/solr/test-framework/src/java/org/apache/solr/spelling/package.html 
b/solr/test-framework/src/java/org/apache/solr/spelling/package.html
new file mode 100644
index 0000000..bc191c5
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/spelling/package.html
@@ -0,0 +1,23 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- not a package-info.java, because we already defined this package in core/ 
-->
+<html>
+<body>
+Mock classes for testing spelling.
+</body>
+</html>

Reply via email to