You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2017/09/18 16:24:39 UTC

[05/50] lucene-solr:feature/autoscaling_72: SOLR-10783 Add support for Hadoop Credential Provider as SSL/TLS store password source.

SOLR-10783 Add support for Hadoop Credential Provider as SSL/TLS store password source.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b4d280f3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b4d280f3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b4d280f3

Branch: refs/heads/feature/autoscaling_72
Commit: b4d280f369023a179e98154535ed4b06ea096f5f
Parents: ba9504d
Author: Mark Miller <ma...@apache.org>
Authored: Wed Sep 6 22:33:12 2017 -0500
Committer: Mark Miller <ma...@apache.org>
Committed: Wed Sep 6 22:33:12 2017 -0500

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   2 +
 solr/bin/solr                                   |   6 +
 solr/bin/solr.cmd                               |  15 +-
 solr/bin/solr.in.cmd                            |  11 ++
 solr/bin/solr.in.sh                             |  11 ++
 .../util/configuration/SSLConfigurations.java   | 102 +++++++---
 .../configuration/SSLConfigurationsFactory.java |   2 +-
 .../configuration/SSLCredentialProvider.java    |  36 ++++
 .../SSLCredentialProviderFactory.java           |  93 +++++++++
 .../AbstractSSLCredentialProvider.java          |  56 ++++++
 .../providers/EnvSSLCredentialProvider.java     |  68 +++++++
 .../providers/HadoopSSLCredentialProvider.java  |  66 +++++++
 .../providers/SysPropSSLCredentialProvider.java |  38 ++++
 .../configuration/SSLConfigurationsTest.java    | 193 ++++++++++++++++---
 .../SSLCredentialProviderFactoryTest.java       |  90 +++++++++
 .../providers/EnvSSLCredentialProviderTest.java |  52 +++++
 .../HadoopSSLCredentialProviderTest.java        |  72 +++++++
 .../SysPropSSLCredentialProviderTest.java       |  55 ++++++
 solr/server/etc/jetty-ssl.xml                   |   8 +-
 19 files changed, 920 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index be89fb1..dcfb15e 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -89,6 +89,8 @@ New Features
 * SOLR-11316: JSON Facet API: min/max aggregations are now supported on single-valued date fields.
   (yonik)
 
+* SOLR-10783 Add support for Hadoop Credential Provider as SSL/TLS store password source.
+  (Mano Kovacs via Mark Miller)
 
 Bug Fixes
 ----------------------

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/bin/solr
----------------------------------------------------------------------
diff --git a/solr/bin/solr b/solr/bin/solr
index bc2abca..29af3f4 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -163,6 +163,11 @@ fi
 SOLR_URL_SCHEME=http
 SOLR_JETTY_CONFIG=()
 SOLR_SSL_OPTS=""
+
+if [ -n "$SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH" ]; then
+  SOLR_SSL_OPTS+=" -Dhadoop.security.credential.provider.path=$SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH"
+fi
+
 if [ -z "$SOLR_SSL_ENABLED" ]; then
   if [ -n "$SOLR_SSL_KEY_STORE" ]; then
     SOLR_SSL_ENABLED="true" # implicitly from earlier behaviour
@@ -172,6 +177,7 @@ if [ -z "$SOLR_SSL_ENABLED" ]; then
 fi
 if [ "$SOLR_SSL_ENABLED" == "true" ]; then
   SOLR_JETTY_CONFIG+=("--module=https")
+  SOLR_JETTY_CONFIG+=("--lib=$DEFAULT_SERVER_DIR/solr-webapp/webapp/WEB-INF/lib/*")
   SOLR_URL_SCHEME=https
   if [ -n "$SOLR_SSL_KEY_STORE" ]; then
     SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/bin/solr.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index 57e2e62..b5b1d78 100644
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -38,11 +38,17 @@ REM command line args
 IF "%SOLR_INCLUDE%"=="" set "SOLR_INCLUDE=%SOLR_TIP%\bin\solr.in.cmd"
 IF EXIST "%SOLR_INCLUDE%" CALL "%SOLR_INCLUDE%"
 
+set "DEFAULT_SERVER_DIR=%SOLR_TIP%\server"
+
 REM Select HTTP OR HTTPS related configurations
 set SOLR_URL_SCHEME=http
 set "SOLR_JETTY_CONFIG=--module=http"
 set "SOLR_SSL_OPTS= "
 
+IF DEFINED SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH (
+  set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dhadoop.security.credential.provider.path=%SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH%"
+)
+
 IF NOT DEFINED SOLR_SSL_ENABLED (
   IF DEFINED SOLR_SSL_KEY_STORE (
     set "SOLR_SSL_ENABLED=true"
@@ -50,8 +56,9 @@ IF NOT DEFINED SOLR_SSL_ENABLED (
     set "SOLR_SSL_ENABLED=false"
   )
 )
+
 IF "%SOLR_SSL_ENABLED%"=="true" (
-  set "SOLR_JETTY_CONFIG=--module=https"
+  set "SOLR_JETTY_CONFIG=--lib="%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*" --module=https"
   set SOLR_URL_SCHEME=https
   IF DEFINED SOLR_SSL_KEY_STORE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
@@ -182,8 +189,6 @@ IF !JAVA_MAJOR_VERSION! LSS 8 (
   goto err
 )
 
-set "DEFAULT_SERVER_DIR=%SOLR_TIP%\server"
-
 set FIRST_ARG=%1
 
 IF [%1]==[] goto usage
@@ -995,7 +1000,7 @@ IF "%SCRIPT_CMD%"=="stop" (
           set found_it=1
           @echo Stopping Solr process %%N running on port %SOLR_PORT%
           set /A STOP_PORT=%SOLR_PORT% - 1000
-          "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" "%SOLR_JETTY_CONFIG%" STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
+          "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" %SOLR_JETTY_CONFIG% STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
           del "%SOLR_TIP%"\bin\solr-%SOLR_PORT%.port
           timeout /T 5
           REM Kill it if it is still running after the graceful shutdown
@@ -1243,7 +1248,7 @@ IF "%FG%"=="1" (
     -Dlog4j.configuration="%LOG4J_CONFIG%" -DSTOP.PORT=!STOP_PORT! -DSTOP.KEY=%STOP_KEY% ^
     -Dsolr.solr.home="%SOLR_HOME%" -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%" ^
     -Djetty.host=%SOLR_JETTY_HOST% -Djetty.port=%SOLR_PORT% -Djetty.home="%SOLR_SERVER_DIR%" ^
-    -Djava.io.tmpdir="%SOLR_SERVER_DIR%\tmp" -jar start.jar "%SOLR_JETTY_CONFIG%" "%SOLR_JETTY_ADDL_CONFIG%"
+    -Djava.io.tmpdir="%SOLR_SERVER_DIR%\tmp" -jar start.jar %SOLR_JETTY_CONFIG% "%SOLR_JETTY_ADDL_CONFIG%"
 ) ELSE (
   START /B "Solr-%SOLR_PORT%" /D "%SOLR_SERVER_DIR%" ^
     "%JAVA%" %SERVEROPT% %SOLR_JAVA_MEM% %START_OPTS% ^

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/bin/solr.in.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd
index afba4f7..99a6d79 100644
--- a/solr/bin/solr.in.cmd
+++ b/solr/bin/solr.in.cmd
@@ -116,6 +116,17 @@ REM set SOLR_SSL_CLIENT_TRUST_STORE=
 REM set SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
 REM set SOLR_SSL_CLIENT_TRUST_STORE_TYPE=
 
+REM Sets path of Hadoop credential provider (hadoop.security.credential.provider.path property) and
+REM enables usage of credential store.
+REM Credential provider should store the following keys:
+REM * solr.jetty.keystore.password
+REM * solr.jetty.truststore.password
+REM Set the two below if you want to set specific store passwords for HTTP client
+REM * javax.net.ssl.keyStorePassword
+REM * javax.net.ssl.trustStorePassword
+REM More info: https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html
+REM set SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
+
 REM Settings for authentication
 REM Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters
 REM set SOLR_AUTHENTICATION_CLIENT_BUILDER=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/bin/solr.in.sh
----------------------------------------------------------------------
diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh
index 514efb1..22c5bf7 100644
--- a/solr/bin/solr.in.sh
+++ b/solr/bin/solr.in.sh
@@ -133,6 +133,17 @@
 #SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
 #SOLR_SSL_CLIENT_TRUST_STORE_TYPE=
 
+# Sets path of Hadoop credential provider (hadoop.security.credential.provider.path property) and
+# enables usage of credential store.
+# Credential provider should store the following keys:
+# * solr.jetty.keystore.password
+# * solr.jetty.truststore.password
+# Set the two below if you want to set specific store passwords for HTTP client
+# * javax.net.ssl.keyStorePassword
+# * javax.net.ssl.trustStorePassword
+# More info: https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html
+#SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
+
 # Settings for authentication
 # Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters
 #SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
index bfa5186..30edf57 100644
--- a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
@@ -18,7 +18,7 @@
 package org.apache.solr.util.configuration;
 
 import java.lang.invoke.MethodHandles;
-import java.util.Map;
+import java.util.List;
 
 import org.apache.solr.common.StringUtils;
 import org.slf4j.Logger;
@@ -28,48 +28,102 @@ import org.slf4j.LoggerFactory;
  * Dedicated object to handle Solr configurations
  */
 public class SSLConfigurations {
-  private final Map<String, String> envVars;
-
+  public static final String DEFAULT_STORE_PASSWORD = "secret";
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  protected final List<SSLCredentialProvider> credentialProviders;
+
   public static class SysProps {
-    public static final String SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
-    public static final String SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
+    public static final String SSL_KEY_STORE_PASSWORD = "solr.jetty.keystore.password";
+    public static final String SSL_TRUST_STORE_PASSWORD = "solr.jetty.truststore.password";
+    public static final String SSL_CLIENT_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
+    public static final String SSL_CLIENT_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
   }
 
-  public static class EnvVars {
-    public static final String SOLR_SSL_CLIENT_KEY_STORE_PASSWORD = "SOLR_SSL_CLIENT_KEY_STORE_PASSWORD";
-    public static final String SOLR_SSL_KEY_STORE_PASSWORD = "SOLR_SSL_KEY_STORE_PASSWORD";
-    public static final String SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD = "SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD";
-    public static final String SOLR_SSL_TRUST_STORE_PASSWORD = "SOLR_SSL_TRUST_STORE_PASSWORD";
+  /**
+   * @param sslCredentialProviderFactory Credential provider factory to use for providers
+   */
+  public SSLConfigurations(SSLCredentialProviderFactory sslCredentialProviderFactory) {
+    credentialProviders = sslCredentialProviderFactory.getProviders();
   }
 
   /**
-   * @param envVars Map of environment variables to use
+   * @param credentialProviders Explicit list of credential providers to use
    */
-  public SSLConfigurations(Map<String, String> envVars) {
-    this.envVars = envVars;
+  public SSLConfigurations(List<SSLCredentialProvider> credentialProviders) {
+    this.credentialProviders = credentialProviders;
   }
 
-  /** Initiates javax.net.ssl.* system properties from the proper sources. */
+  /**
+   * Initiates javax.net.ssl.* system properties from the proper sources.
+   */
   public void init() {
 
-    String clientKeystorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD);
-    String keystorePassword = envVars.get(EnvVars.SOLR_SSL_KEY_STORE_PASSWORD);
+    String clientKeystorePassword = getClientKeyStorePassword();
+    String keystorePassword = getKeyStorePassword();
 
-    String clientTruststorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD);
-    String truststorePassword = envVars.get(EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD);
+    String clientTruststorePassword = getClientTrustStorePassword();
+    String truststorePassword = getTrustStorePassword();
 
-    if (isEmpty(System.getProperty(SysProps.SSL_KEY_STORE_PASSWORD))
+    if (isEmpty(System.getProperty(SysProps.SSL_CLIENT_KEY_STORE_PASSWORD))
         && !(isEmpty(clientKeystorePassword) && isEmpty(keystorePassword))) {
-      log.debug("Setting {} based on env var", SysProps.SSL_KEY_STORE_PASSWORD);
-      System.setProperty(SysProps.SSL_KEY_STORE_PASSWORD, clientKeystorePassword != null ? clientKeystorePassword : keystorePassword);
+      log.info("Setting {}", SysProps.SSL_CLIENT_KEY_STORE_PASSWORD);
+      System.setProperty(SysProps.SSL_CLIENT_KEY_STORE_PASSWORD, clientKeystorePassword != null ? clientKeystorePassword : keystorePassword);
     }
-    if (isEmpty(System.getProperty(SysProps.SSL_TRUST_STORE_PASSWORD))
+    if (isEmpty(System.getProperty(SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD))
         && !(isEmpty(clientTruststorePassword) && isEmpty(truststorePassword))) {
-      log.debug("Setting {} based on env var", SysProps.SSL_TRUST_STORE_PASSWORD);
-      System.setProperty(SysProps.SSL_TRUST_STORE_PASSWORD, clientTruststorePassword != null ? clientTruststorePassword : truststorePassword);
+      log.info("Setting {}", SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD);
+      System.setProperty(SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD, clientTruststorePassword != null ? clientTruststorePassword : truststorePassword);
+    }
+
+  }
+
+  /**
+   * @return password for keystore used for SSL connections
+   */
+  public String getKeyStorePassword() {
+    String keyStorePassword = getPassword(SSLCredentialProvider.CredentialType.SSL_KEY_STORE_PASSWORD);
+    if (isEmpty(keyStorePassword)) {
+      log.warn("No keystore password found, using default.");
+      keyStorePassword = DEFAULT_STORE_PASSWORD; // default value
+    }
+    return keyStorePassword;
+  }
+
+  /**
+   * @return password for truststore used for SSL connections
+   */
+  public String getTrustStorePassword() {
+    String trustStorePassword = getPassword(SSLCredentialProvider.CredentialType.SSL_TRUST_STORE_PASSWORD);
+    if (isEmpty(trustStorePassword)) {
+      log.warn("No truststore password found, using default.");
+      trustStorePassword = DEFAULT_STORE_PASSWORD; // default value
+    }
+    return trustStorePassword;
+  }
+
+  /**
+   * @return password for keystore used for SSL client connections
+   */
+  public String getClientKeyStorePassword() {
+    String keyStorePassword = getPassword(SSLCredentialProvider.CredentialType.SSL_CLIENT_KEY_STORE_PASSWORD);
+    return keyStorePassword;
+  }
+
+  /**
+   * @return password for truststore used for SSL client connections
+   */
+  public String getClientTrustStorePassword() {
+    String trustStorePassword = getPassword(SSLCredentialProvider.CredentialType.SSL_CLIENT_TRUST_STORE_PASSWORD);
+    return trustStorePassword;
+  }
+
+  protected String getPassword(SSLCredentialProvider.CredentialType type) {
+    for(SSLCredentialProvider provider: credentialProviders){
+      String credential = provider.getCredential(type);
+      if(credential != null) return credential;
     }
+    return null;
   }
 
   private boolean isEmpty(String str) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
index 1da7c01..80571ef 100644
--- a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
@@ -39,7 +39,7 @@ public class SSLConfigurationsFactory {
   }
 
   private static SSLConfigurations getInstance() {
-    return new SSLConfigurations(System.getenv());
+    return new SSLConfigurations(new SSLCredentialProviderFactory());
   }
 
   @VisibleForTesting

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProvider.java
new file mode 100644
index 0000000..f714d28
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * Interface for different source of SSL configurations.
+ */
+public interface SSLCredentialProvider {
+  enum CredentialType {
+    SSL_KEY_STORE_PASSWORD,
+    SSL_TRUST_STORE_PASSWORD,
+    SSL_CLIENT_KEY_STORE_PASSWORD,
+    SSL_CLIENT_TRUST_STORE_PASSWORD
+  }
+
+  /**
+   * @return Credential for the given credential type
+   */
+  String getCredential(CredentialType type);
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..1fcfd96
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLCredentialProviderFactory.java
@@ -0,0 +1,93 @@
+/*
+ * 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 java.lang.invoke.MethodHandles;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+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;
+
+/**
+ * Class responsible to build SSL credential providers
+ */
+public class SSLCredentialProviderFactory {
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  public static final String DEFAULT_PROVIDER_CHAIN = "env;sysprop";
+  public static final String PROVIDER_CHAIN_KEY = "solr.ssl.credential.provider.chain";
+
+  private final static ImmutableMap<String, Class> defaultProviders = ImmutableMap.of(
+      "env", EnvSSLCredentialProvider.class,
+      "sysprop", SysPropSSLCredentialProvider.class,
+      "hadoop", HadoopSSLCredentialProvider.class
+  );
+
+  private String providerChain;
+
+  public SSLCredentialProviderFactory() {
+    this.providerChain = System.getProperty(PROVIDER_CHAIN_KEY, DEFAULT_PROVIDER_CHAIN);
+  }
+
+  public SSLCredentialProviderFactory(String providerChain) {
+    this.providerChain = providerChain;
+  }
+
+  public List<SSLCredentialProvider> getProviders() {
+    ArrayList<SSLCredentialProvider> providers = new ArrayList<>();
+    log.info(String.format(Locale.ROOT, "Processing SSL Credential Provider chain: %s", providerChain));
+    String classPrefix = "class://";
+    for (String provider : providerChain.split(";")) {
+      if (defaultProviders.containsKey(provider)) {
+        providers.add(getDefaultProvider(defaultProviders.get(provider)));
+      } else if (provider.startsWith(classPrefix)) {
+        providers.add(getProviderByClassName(provider.substring(classPrefix.length())));
+      } else {
+        throw new RuntimeException("Unable to parse credential provider: " + provider);
+      }
+    }
+    return providers;
+  }
+
+  private SSLCredentialProvider getProviderByClassName(String clazzName) {
+    try {
+      return (SSLCredentialProvider) Class.forName(clazzName).getConstructor().newInstance();
+    } catch (InstantiationException | ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+      String msg = String.format(Locale.ROOT, "Could not instantiate %s credential provider", clazzName);
+      log.error(msg);
+      throw new RuntimeException(msg, e);
+    }
+  }
+
+  private SSLCredentialProvider getDefaultProvider(Class aClass) {
+    try {
+      return (SSLCredentialProvider) aClass.getConstructor().newInstance();
+    } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
+      String msg = String.format(Locale.ROOT, "Could not instantiate %s credential provider", aClass.getName());
+      log.error(msg);
+      throw new RuntimeException(msg, e);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/providers/AbstractSSLCredentialProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/providers/AbstractSSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/providers/AbstractSSLCredentialProvider.java
new file mode 100644
index 0000000..9825154
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/providers/AbstractSSLCredentialProvider.java
@@ -0,0 +1,56 @@
+/*
+ * 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.providers;
+
+import java.util.EnumMap;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.apache.solr.util.configuration.SSLCredentialProvider;
+
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_CLIENT_KEY_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_CLIENT_TRUST_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_KEY_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_TRUST_STORE_PASSWORD;
+
+/**
+ * Abstract provider with default implementation
+ */
+abstract public class AbstractSSLCredentialProvider implements SSLCredentialProvider {
+  public static final EnumMap<CredentialType, String> DEFAULT_CREDENTIAL_KEY_MAP = Maps.newEnumMap(ImmutableMap.of(
+      SSL_KEY_STORE_PASSWORD, "solr.jetty.keystore.password",
+      SSL_TRUST_STORE_PASSWORD, "solr.jetty.truststore.password",
+      SSL_CLIENT_KEY_STORE_PASSWORD, "javax.net.ssl.keyStorePassword",
+      SSL_CLIENT_TRUST_STORE_PASSWORD, "javax.net.ssl.trustStorePassword"
+  ));
+  private final EnumMap<CredentialType, String> credentialKeyMap;
+
+  public AbstractSSLCredentialProvider() {
+    credentialKeyMap = getCredentialKeyMap();
+  }
+
+  abstract protected String getCredential(String key);
+
+  abstract protected EnumMap<CredentialType, String> getCredentialKeyMap();
+
+  @Override
+  public String getCredential(CredentialType type) {
+    return getCredential(credentialKeyMap.get(type));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/providers/EnvSSLCredentialProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/providers/EnvSSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/providers/EnvSSLCredentialProvider.java
new file mode 100644
index 0000000..ccfd807
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/providers/EnvSSLCredentialProvider.java
@@ -0,0 +1,68 @@
+/*
+ * 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.providers;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_CLIENT_KEY_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_CLIENT_TRUST_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_KEY_STORE_PASSWORD;
+import static org.apache.solr.util.configuration.SSLCredentialProvider.CredentialType.SSL_TRUST_STORE_PASSWORD;
+
+
+/**
+ * Environment variable based SSL configuration provider
+ */
+public class EnvSSLCredentialProvider extends AbstractSSLCredentialProvider {
+
+  public static class EnvVars {
+    public static final String SOLR_SSL_CLIENT_KEY_STORE_PASSWORD = "SOLR_SSL_CLIENT_KEY_STORE_PASSWORD";
+    public static final String SOLR_SSL_KEY_STORE_PASSWORD = "SOLR_SSL_KEY_STORE_PASSWORD";
+    public static final String SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD = "SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD";
+    public static final String SOLR_SSL_TRUST_STORE_PASSWORD = "SOLR_SSL_TRUST_STORE_PASSWORD";
+  }
+
+  private Map<String, String> envVars;
+
+  protected EnumMap<CredentialType, String> getCredentialKeyMap() {
+    return Maps.newEnumMap(ImmutableMap.of(
+        SSL_KEY_STORE_PASSWORD, EnvVars.SOLR_SSL_KEY_STORE_PASSWORD,
+        SSL_TRUST_STORE_PASSWORD, EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD,
+        SSL_CLIENT_KEY_STORE_PASSWORD, EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD,
+        SSL_CLIENT_TRUST_STORE_PASSWORD, EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD
+    ));
+  }
+
+  protected String getCredential(String envKey) {
+    if (envVars.containsKey(envKey)) {
+      return envVars.get(envKey);
+    } else {
+      return null;
+    }
+  }
+
+  @VisibleForTesting
+  public void setEnvVars(Map<String, String> envVars) {
+    this.envVars = envVars;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
new file mode 100644
index 0000000..37eb432
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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.providers;
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.EnumMap;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.solr.common.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.hadoop.security.alias.CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH;
+
+/**
+ * System property based SSL configuration provider
+ */
+public class HadoopSSLCredentialProvider extends AbstractSSLCredentialProvider {
+
+  private Configuration hadoopConfigurationProvider;
+
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public HadoopSSLCredentialProvider() {
+    this(new Configuration());
+  }
+
+  public HadoopSSLCredentialProvider(Configuration hadoopConfigurationProvider) {
+    if (StringUtils.isEmpty(System.getProperty(CREDENTIAL_PROVIDER_PATH))) {
+      throw new RuntimeException("Cannot initialize Hadoop configuration provider without credential provider path. Use " + CREDENTIAL_PROVIDER_PATH + " system property to configure.");
+    }
+    this.hadoopConfigurationProvider = hadoopConfigurationProvider;
+    hadoopConfigurationProvider.set(CREDENTIAL_PROVIDER_PATH, System.getProperty(CREDENTIAL_PROVIDER_PATH));
+  }
+
+  @Override
+  protected EnumMap<CredentialType, String> getCredentialKeyMap() {
+    return DEFAULT_CREDENTIAL_KEY_MAP;
+  }
+
+  protected String getCredential(String keystoreKey) {
+    try {
+      char[] password = hadoopConfigurationProvider.getPassword(keystoreKey);
+      return password == null ? null : String.valueOf(password);
+    } catch (IOException e) {
+      log.error("Could not read password from Hadoop Credential Store: " + keystoreKey, e);
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java b/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
new file mode 100644
index 0000000..0a15a69
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.providers;
+
+import java.util.EnumMap;
+
+/**
+ * System property based SSL configuration provider
+ */
+public class SysPropSSLCredentialProvider extends AbstractSSLCredentialProvider {
+  @Override
+  protected EnumMap<CredentialType, String> getCredentialKeyMap() {
+    return DEFAULT_CREDENTIAL_KEY_MAP;
+  }
+
+  protected String getCredential(String syspropKey) {
+    if (System.getProperty(syspropKey) != null) {
+      return System.getProperty(syspropKey);
+    } else {
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
----------------------------------------------------------------------
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 a1d4696..8629e2c 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
@@ -17,17 +17,26 @@
 
 package org.apache.solr.util.configuration;
 
+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.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;
@@ -38,11 +47,16 @@ public class SSLConfigurationsTest {
   public static final String SAMPLE_PW3 = "pw789";
   public static final String KEY_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD;
   public static final String TRUST_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD;
+  public static final String CLIENT_KEY_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_CLIENT_KEY_STORE_PASSWORD;
+  public static final String CLIENT_TRUST_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_CLIENT_TRUST_STORE_PASSWORD;
 
   @Rule
   public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
       SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
-      SSLConfigurations.SysProps.SSL_TRUST_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
   );
 
   @Before
@@ -50,72 +64,203 @@ 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() {
-    sut = new SSLConfigurations(envs);
+    EnvSSLCredentialProvider envSSLCredentialProvider = new EnvSSLCredentialProvider();
+    envSSLCredentialProvider.setEnvVars(envs);
+    sut = new SSLConfigurations(Arrays.asList(envSSLCredentialProvider, new SysPropSSLCredentialProvider()));
     return sut;
   }
 
   @Test
   public void testSslConfigKeystorePwFromKeystoreEnvVar() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
     createSut().init();
-    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW1));
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW1));
   }
 
   @Test
   public void testSslConfigKeystorePwFromClientKeystoreEnvVar() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW2));
   }
 
   @Test
   public void testSslConfigKeystorePwFromBothEnvVars() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @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(KEY_STORE_PASSWORD, SAMPLE_PW3);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    System.setProperty(CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW3);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
+    assertThat(System.getProperty(CLIENT_KEY_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
   }
 
 
   @Test
   public void testSslConfigTruststorePwFromKeystoreEnvVar() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
     createSut().init();
-    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW1));
+    assertThat(System.getProperty(CLIENT_TRUST_STORE_PASSWORD), is(SAMPLE_PW1));
   }
 
   @Test
   public void testSslConfigTruststorePwFromClientKeystoreEnvVar() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
+    assertThat(System.getProperty(CLIENT_TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
   }
 
   @Test
   public void testSslConfigTruststorePwFromBothEnvVars() {
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
+    assertThat(System.getProperty(CLIENT_TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
   }
 
   @Test
   public void testSslConfigTruststorePwNotOverwrittenIfExists() {
-    System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW3);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
-    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    System.setProperty(CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW3);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
     createSut().init();
-    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
+    assertThat(System.getProperty(CLIENT_TRUST_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
+  }
+
+  @Test
+  public void testGetKeyStorePasswordFromProperty() {
+    System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW1);
+    assertThat(createSut().getKeyStorePassword(), is(SAMPLE_PW1));
+  }
+
+  @Test
+  public void testGetKeyStorePasswordFromEnv() {
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    assertThat(createSut().getKeyStorePassword(), 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 testGetTrustStorePasswordFromProperty() {
+    System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    assertThat(createSut().getTrustStorePassword(), is(SAMPLE_PW1));
+  }
+
+  @Test
+  public void testGetTrustStorePasswordFromEnv() {
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    assertThat(createSut().getTrustStorePassword(), is(SAMPLE_PW2));
+  }
+
+  @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));
+  }
+
+  @Test
+  public void testGetClientKeyStorePasswordFromEnv() {
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    assertThat(createSut().getClientKeyStorePassword(), is(SAMPLE_PW2));
+  }
+
+  @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));
+  }
+
+  @Test
+  public void testGetClientTrustStorePasswordFromEnv() {
+    envs.put(EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    assertThat(createSut().getClientTrustStorePassword(), is(SAMPLE_PW2));
+  }
+
+  @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() {
+    return Mockito.mock(Configuration.class);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/test/org/apache/solr/util/configuration/SSLCredentialProviderFactoryTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/configuration/SSLCredentialProviderFactoryTest.java b/solr/core/src/test/org/apache/solr/util/configuration/SSLCredentialProviderFactoryTest.java
new file mode 100644
index 0000000..21e7f8a
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/configuration/SSLCredentialProviderFactoryTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.util.configuration;
+
+import java.util.List;
+
+import org.apache.lucene.util.TestRuleRestoreSystemProperties;
+import org.apache.solr.util.configuration.providers.EnvSSLCredentialProvider;
+import org.apache.solr.util.configuration.providers.SysPropSSLCredentialProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ */
+public class SSLCredentialProviderFactoryTest {
+
+  @Rule
+  public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
+      SSLCredentialProviderFactory.PROVIDER_CHAIN_KEY
+  );
+
+  @Test
+  public void testGetProvidersOrder() {
+    SSLCredentialProviderFactory sut = getSut("sysprop;env");
+    List<SSLCredentialProvider> providers = sut.getProviders();
+    assertThat(providers.get(0), is(SysPropSSLCredentialProvider.class));
+    assertThat(providers.get(1), is(EnvSSLCredentialProvider.class));
+
+    sut = getSut("env;sysprop");
+    providers = sut.getProviders();
+    assertThat(providers.get(0), is(EnvSSLCredentialProvider.class));
+    assertThat(providers.get(1), is(SysPropSSLCredentialProvider.class));
+  }
+
+  @Test
+  public void testGetProvidersWithCustomProvider() {
+    SSLCredentialProviderFactory sut = getSut("sysprop;class://" + CustomSSLCredentialProvider.class.getName() + ";env");
+    List<SSLCredentialProvider> providers = sut.getProviders();
+    assertThat(providers.get(0), is(SysPropSSLCredentialProvider.class));
+    assertThat(providers.get(1), is(CustomSSLCredentialProvider.class));
+    assertThat(providers.get(2), is(EnvSSLCredentialProvider.class));
+  }
+
+  @Test(expected = RuntimeException.class)
+  public void testGetProvidersInvalidProvider() {
+    getSut("sysprop;DoesNotExists").getProviders();
+  }
+
+  @Test
+  public void testGetProvidersBySysprop() {
+    String chain = "sysprop;class://" + CustomSSLCredentialProvider.class.getName() + ";env";
+    System.setProperty(SSLCredentialProviderFactory.PROVIDER_CHAIN_KEY, chain);
+    SSLCredentialProviderFactory sut = new SSLCredentialProviderFactory();
+    List<SSLCredentialProvider> providers = sut.getProviders();
+    assertThat(providers.get(0), is(SysPropSSLCredentialProvider.class));
+    assertThat(providers.get(1), is(CustomSSLCredentialProvider.class));
+    assertThat(providers.get(2), is(EnvSSLCredentialProvider.class));
+  }
+
+  private SSLCredentialProviderFactory getSut(String providerChain) {
+    return new SSLCredentialProviderFactory(providerChain);
+  }
+
+  static public class CustomSSLCredentialProvider implements SSLCredentialProvider {
+    @Override
+    public String getCredential(CredentialType type) {
+      return null;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/test/org/apache/solr/util/configuration/providers/EnvSSLCredentialProviderTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/configuration/providers/EnvSSLCredentialProviderTest.java b/solr/core/src/test/org/apache/solr/util/configuration/providers/EnvSSLCredentialProviderTest.java
new file mode 100644
index 0000000..c355dce
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/configuration/providers/EnvSSLCredentialProviderTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.providers;
+
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.solr.util.configuration.SSLCredentialProvider;
+import org.junit.Test;
+
+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;
+
+/**
+ */
+public class EnvSSLCredentialProviderTest {
+
+  @Test
+  public void testGetCredentials() throws Exception {
+    int cnt = 0;
+    Map<String, String> envvars = ImmutableMap.of(
+        EnvSSLCredentialProvider.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, "pw" + ++cnt,
+        EnvSSLCredentialProvider.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, "pw" + ++cnt,
+        EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, "pw" + ++cnt,
+        EnvSSLCredentialProvider.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, "pw" + ++cnt
+    );
+    EnvSSLCredentialProvider sut = new EnvSSLCredentialProvider();
+    sut.setEnvVars(envvars);
+    cnt = 0;
+    for (Map.Entry<SSLCredentialProvider.CredentialType, String> set : DEFAULT_CREDENTIAL_KEY_MAP.entrySet()) {
+      String expectedpw = "pw" + ++cnt;
+      assertThat(sut.getCredential(set.getKey()), is(expectedpw));
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java b/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
new file mode 100644
index 0000000..bc0a1f4
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/configuration/providers/HadoopSSLCredentialProviderTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.providers;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.lucene.util.TestRuleRestoreSystemProperties;
+import org.apache.solr.util.configuration.SSLCredentialProvider;
+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.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;
+
+/**
+ */
+public class HadoopSSLCredentialProviderTest {
+
+  @Rule
+  public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
+      CREDENTIAL_PROVIDER_PATH
+  );
+
+  @Test(expected = RuntimeException.class)
+  public void testConstructorRequiresCredPath() {
+    new HadoopSSLCredentialProvider(getMockHadoopConfiguration());
+  }
+
+  @Test
+  public void testGetCredentials() throws Exception {
+    int cnt = 0;
+    for (Map.Entry<SSLCredentialProvider.CredentialType, String> set : DEFAULT_CREDENTIAL_KEY_MAP.entrySet()) {
+      String pw = "pw" + ++cnt;
+      HadoopSSLCredentialProvider sut = new HadoopSSLCredentialProvider(getMockedHadoopCredentialProvider(set.getValue(), pw));
+      assertThat(sut.getCredential(set.getKey()), is(pw));
+    }
+  }
+
+  private Configuration getMockedHadoopCredentialProvider(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 mockHadoopConfiguration;
+  }
+
+  private Configuration getMockHadoopConfiguration() {
+    return Mockito.mock(Configuration.class);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/core/src/test/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProviderTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProviderTest.java b/solr/core/src/test/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProviderTest.java
new file mode 100644
index 0000000..e278cb5
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/configuration/providers/SysPropSSLCredentialProviderTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.providers;
+
+import java.util.Map;
+
+import org.apache.lucene.util.TestRuleRestoreSystemProperties;
+import org.apache.solr.util.configuration.SSLConfigurations;
+import org.apache.solr.util.configuration.SSLCredentialProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+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;
+
+/**
+ */
+public class SysPropSSLCredentialProviderTest {
+
+  @Rule
+  public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
+      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
+  );
+
+  @Test
+  public void testGetCredentials() throws Exception {
+    int cnt = 0;
+    SysPropSSLCredentialProvider sut = new SysPropSSLCredentialProvider();
+    for (Map.Entry<SSLCredentialProvider.CredentialType, String> set : DEFAULT_CREDENTIAL_KEY_MAP.entrySet()) {
+      String pw = "pw" + ++cnt;
+      System.setProperty(set.getValue(), pw);
+      assertThat(sut.getCredential(set.getKey()), is(pw));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b4d280f3/solr/server/etc/jetty-ssl.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty-ssl.xml b/solr/server/etc/jetty-ssl.xml
index 741ac48..cdbf57e 100644
--- a/solr/server/etc/jetty-ssl.xml
+++ b/solr/server/etc/jetty-ssl.xml
@@ -7,10 +7,14 @@
 <!-- and either jetty-https.xml or jetty-spdy.xml (but not both)   -->
 <!-- ============================================================= -->
 <Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
+  <Call class="org.apache.solr.util.configuration.SSLConfigurationsFactory" name="current">
+    <Get name="keyStorePassword" id="keyStorePassword"/>
+    <Get name="trustStorePassword" id="trustStorePassword"/>
+  </Call>
   <Set name="KeyStorePath"><Property name="solr.jetty.keystore" default="./etc/solr-ssl.keystore.jks"/></Set>
-  <Set name="KeyStorePassword"><Env name="SOLR_SSL_KEY_STORE_PASSWORD" default="secret"/></Set>
+  <Set name="KeyStorePassword"><Ref refid="keyStorePassword"/></Set>
   <Set name="TrustStorePath"><Property name="solr.jetty.truststore" default="./etc/solr-ssl.keystore.jks"/></Set>
-  <Set name="TrustStorePassword"><Env name="SOLR_SSL_TRUST_STORE_PASSWORD" default="secret"/></Set>
+  <Set name="TrustStorePassword"><Ref refid="trustStorePassword"/></Set>
   <Set name="NeedClientAuth"><Property name="solr.jetty.ssl.needClientAuth" default="false"/></Set>
   <Set name="WantClientAuth"><Property name="solr.jetty.ssl.wantClientAuth" default="false"/></Set>
   <Set name="KeyStoreType"><Property name="solr.jetty.keystore.type" default="JKS"/></Set>