SOLR-17279: consolidate security.json constants in tests (#2445)

* create SecurityJson class for holding simple security.json used by multiple tests
---------

Co-authored-by: Eric Pugh <epugh@opensourceconnections.com>
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index a507c10..a98bc9b 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -95,6 +95,8 @@
 
 * SOLR-17205: De-couple SolrJ required Java version from server Java version (janhoy)
 
+* SOLR-17279: Introduce SecurityJson.java file to Test Framework to consolidate setting up authentication in tests. (Rudy Seitz via Eric Pugh)
+
 ==================  9.7.0 ==================
 New Features
 ---------------------
diff --git a/solr/core/src/test/org/apache/solr/cli/CreateToolTest.java b/solr/core/src/test/org/apache/solr/cli/CreateToolTest.java
index a4801c9..4ff1028 100644
--- a/solr/core/src/test/org/apache/solr/cli/CreateToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/CreateToolTest.java
@@ -17,52 +17,24 @@
 
 package org.apache.solr.cli;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.cli.SolrCLI.findTool;
 import static org.apache.solr.cli.SolrCLI.parseCmdLine;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
-import java.util.Map;
 import org.apache.commons.cli.CommandLine;
 import org.apache.solr.cloud.SolrCloudTestCase;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class CreateToolTest extends SolrCloudTestCase {
 
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
   private static final String collectionName = "testCreateCollectionWithBasicAuth";
 
   @BeforeClass
   public static void setupClusterWithSecurityEnabled() throws Exception {
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
   }
 
@@ -78,7 +50,7 @@
       "-zkHost",
       cluster.getZkClient().getZkServerAddress(),
       "-credentials",
-      USER + ":" + PASS,
+      SecurityJson.USER_PASS,
       "-verbose"
     };
 
diff --git a/solr/core/src/test/org/apache/solr/cli/DeleteToolTest.java b/solr/core/src/test/org/apache/solr/cli/DeleteToolTest.java
index 808f617..7c781f2 100644
--- a/solr/core/src/test/org/apache/solr/cli/DeleteToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/DeleteToolTest.java
@@ -17,59 +17,30 @@
 
 package org.apache.solr.cli;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.cli.SolrCLI.findTool;
 import static org.apache.solr.cli.SolrCLI.parseCmdLine;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
-import java.util.Map;
 import org.apache.commons.cli.CommandLine;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrResponse;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.cloud.SolrCloudTestCase;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class DeleteToolTest extends SolrCloudTestCase {
 
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
-
   @BeforeClass
   public static void setupClusterWithSecurityEnabled() throws Exception {
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
   }
 
   private <T extends SolrRequest<? extends SolrResponse>> T withBasicAuth(T req) {
-    req.setBasicAuthCredentials(USER, PASS);
+    req.setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS);
     return req;
   }
 
@@ -94,7 +65,7 @@
       "-zkHost",
       cluster.getZkClient().getZkServerAddress(),
       "-credentials",
-      USER + ":" + PASS,
+      SecurityJson.USER_PASS,
       "-verbose"
     };
     assertEquals(0, runTool(args));
diff --git a/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java b/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
index dea8965..c638d98 100644
--- a/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/PackageToolTest.java
@@ -17,15 +17,10 @@
 
 package org.apache.solr.cli;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
-
 import java.io.StringReader;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrResponse;
@@ -34,9 +29,8 @@
 import org.apache.solr.common.LinkedHashMapWriter;
 import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
 import org.apache.solr.util.LogLevel;
+import org.apache.solr.util.SecurityJson;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
@@ -52,8 +46,6 @@
 
 @LogLevel("org.apache=INFO")
 public class PackageToolTest extends SolrCloudTestCase {
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
 
   // Note for those who want to modify the jar files used in the packages used in this test:
   // You need to re-sign the jars for install step, as follows:
@@ -71,32 +63,12 @@
   public static void setupClusterWithSecurityEnabled() throws Exception {
     System.setProperty("enable.packages", "true");
 
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig(
             "conf1", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
         .addConfig(
             "conf3", TEST_PATH().resolve("configsets").resolve("cloud-minimal").resolve("conf"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
 
     repositoryServer =
@@ -116,7 +88,7 @@
   }
 
   private <T extends SolrRequest<? extends SolrResponse>> T withBasicAuth(T req) {
-    req.setBasicAuthCredentials(USER, PASS);
+    req.setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS);
     return req;
   }
 
@@ -128,7 +100,9 @@
 
     run(
         tool,
-        new String[] {"-solrUrl", solrUrl, "list-installed", "-credentials", USER + ":" + PASS});
+        new String[] {
+          "-solrUrl", solrUrl, "list-installed", "-credentials", SecurityJson.USER_PASS
+        });
 
     run(
         tool,
@@ -136,27 +110,36 @@
           "-solrUrl",
           solrUrl,
           "-credentials",
-          USER + ":" + PASS,
+          SecurityJson.USER_PASS,
           "add-repo",
           "fullstory",
           "http://localhost:" + repositoryServer.getPort(),
           "-credentials",
-          USER + ":" + PASS
+          SecurityJson.USER_PASS
         });
 
     run(
         tool,
-        new String[] {"-solrUrl", solrUrl, "list-available", "-credentials", USER + ":" + PASS});
-
-    run(
-        tool,
         new String[] {
-          "-solrUrl", solrUrl, "install", "question-answer:1.0.0", "-credentials", USER + ":" + PASS
+          "-solrUrl", solrUrl, "list-available", "-credentials", SecurityJson.USER_PASS
         });
 
     run(
         tool,
-        new String[] {"-solrUrl", solrUrl, "list-installed", "-credentials", USER + ":" + PASS});
+        new String[] {
+          "-solrUrl",
+          solrUrl,
+          "install",
+          "question-answer:1.0.0",
+          "-credentials",
+          SecurityJson.USER_PASS
+        });
+
+    run(
+        tool,
+        new String[] {
+          "-solrUrl", solrUrl, "list-installed", "-credentials", SecurityJson.USER_PASS
+        });
 
     withBasicAuth(CollectionAdminRequest.createCollection("abc", "conf1", 1, 1))
         .processAndWait(cluster.getSolrClient(), 10);
@@ -168,7 +151,12 @@
     run(
         tool,
         new String[] {
-          "-solrUrl", solrUrl, "list-deployed", "question-answer", "-credentials", USER + ":" + PASS
+          "-solrUrl",
+          solrUrl,
+          "list-deployed",
+          "question-answer",
+          "-credentials",
+          SecurityJson.USER_PASS
         });
 
     run(
@@ -184,20 +172,26 @@
           "-p",
           "RH-HANDLER-PATH=" + rhPath,
           "-credentials",
-          USER + ":" + PASS
+          SecurityJson.USER_PASS
         });
-    assertPackageVersion("abc", "question-answer", "1.0.0", rhPath, "1.0.0", USER + ":" + PASS);
+    assertPackageVersion(
+        "abc", "question-answer", "1.0.0", rhPath, "1.0.0", SecurityJson.USER_PASS);
 
     run(
         tool,
         new String[] {
-          "-solrUrl", solrUrl, "list-deployed", "question-answer", "-credentials", USER + ":" + PASS
+          "-solrUrl",
+          solrUrl,
+          "list-deployed",
+          "question-answer",
+          "-credentials",
+          SecurityJson.USER_PASS
         });
 
     run(
         tool,
         new String[] {
-          "-solrUrl", solrUrl, "list-deployed", "-c", "abc", "-credentials", USER + ":" + PASS
+          "-solrUrl", solrUrl, "list-deployed", "-c", "abc", "-credentials", SecurityJson.USER_PASS
         });
 
     // Should we test the "auto-update to latest" functionality or the default explicit deploy
@@ -219,25 +213,38 @@
             "-collections",
             "abc",
             "-credentials",
-            USER + ":" + PASS
+            SecurityJson.USER_PASS
           });
-      assertPackageVersion("abc", "question-answer", "$LATEST", rhPath, "1.0.0", USER + ":" + PASS);
+      assertPackageVersion(
+          "abc", "question-answer", "$LATEST", rhPath, "1.0.0", SecurityJson.USER_PASS);
 
       run(
           tool,
           new String[] {
-            "-solrUrl", solrUrl, "install", "question-answer", "-credentials", USER + ":" + PASS
+            "-solrUrl",
+            solrUrl,
+            "install",
+            "question-answer",
+            "-credentials",
+            SecurityJson.USER_PASS
           });
-      assertPackageVersion("abc", "question-answer", "$LATEST", rhPath, "1.1.0", USER + ":" + PASS);
+      assertPackageVersion(
+          "abc", "question-answer", "$LATEST", rhPath, "1.1.0", SecurityJson.USER_PASS);
     } else {
       log.info("Testing explicit deployment to a different/newer version");
 
       run(
           tool,
           new String[] {
-            "-solrUrl", solrUrl, "install", "question-answer", "-credentials", USER + ":" + PASS
+            "-solrUrl",
+            solrUrl,
+            "install",
+            "question-answer",
+            "-credentials",
+            SecurityJson.USER_PASS
           });
-      assertPackageVersion("abc", "question-answer", "1.0.0", rhPath, "1.0.0", USER + ":" + PASS);
+      assertPackageVersion(
+          "abc", "question-answer", "1.0.0", rhPath, "1.0.0", SecurityJson.USER_PASS);
 
       // even if parameters are not passed in, they should be picked up from previous deployment
       if (random().nextBoolean()) {
@@ -255,7 +262,7 @@
               "-p",
               "RH-HANDLER-PATH=" + rhPath,
               "-credentials",
-              USER + ":" + PASS
+              SecurityJson.USER_PASS
             });
       } else {
         run(
@@ -270,10 +277,11 @@
               "-collections",
               "abc",
               "-credentials",
-              USER + ":" + PASS
+              SecurityJson.USER_PASS
             });
       }
-      assertPackageVersion("abc", "question-answer", "1.1.0", rhPath, "1.1.0", USER + ":" + PASS);
+      assertPackageVersion(
+          "abc", "question-answer", "1.1.0", rhPath, "1.1.0", SecurityJson.USER_PASS);
     }
 
     log.info("Running undeploy...");
@@ -287,13 +295,18 @@
           "-collections",
           "abc",
           "-credentials",
-          USER + ":" + PASS
+          SecurityJson.USER_PASS
         });
 
     run(
         tool,
         new String[] {
-          "-solrUrl", solrUrl, "list-deployed", "question-answer", "-credentials", USER + ":" + PASS
+          "-solrUrl",
+          solrUrl,
+          "list-deployed",
+          "question-answer",
+          "-credentials",
+          SecurityJson.USER_PASS
         });
   }
 
diff --git a/solr/core/src/test/org/apache/solr/cli/PostToolTest.java b/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
index c20249a..5d8b972 100644
--- a/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
+++ b/solr/core/src/test/org/apache/solr/cli/PostToolTest.java
@@ -17,11 +17,8 @@
 
 package org.apache.solr.cli;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.cli.SolrCLI.findTool;
 import static org.apache.solr.cli.SolrCLI.parseCmdLine;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -49,8 +46,7 @@
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.util.EnvUtils;
 import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
@@ -62,39 +58,16 @@
 @SolrTestCaseJ4.SuppressSSL
 public class PostToolTest extends SolrCloudTestCase {
 
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
-
   @BeforeClass
   public static void setupClusterWithSecurityEnabled() throws Exception {
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig("conf1", configset("cloud-minimal"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
   }
 
   private <T extends SolrRequest<? extends SolrResponse>> T withBasicAuth(T req) {
-    req.setBasicAuthCredentials(USER, PASS);
+    req.setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS);
     return req;
   }
 
@@ -116,7 +89,7 @@
       "--solr-update-url",
       cluster.getJettySolrRunner(0).getBaseUrl() + "/" + collection + "/update",
       "--credentials",
-      USER + ":" + PASS,
+      SecurityJson.USER_PASS,
       jsonDoc.getAbsolutePath()
     };
     assertEquals(0, runTool(args));
@@ -154,7 +127,7 @@
     fw.flush();
 
     String[] args = {
-      "post", "-c", collection, "-credentials", USER + ":" + PASS, jsonDoc.getAbsolutePath()
+      "post", "-c", collection, "-credentials", SecurityJson.USER_PASS, jsonDoc.getAbsolutePath()
     };
     assertEquals(0, runTool(args));
 
diff --git a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
index 88b4e4a..9ca2a36 100644
--- a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
+++ b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java
@@ -17,11 +17,8 @@
 
 package org.apache.solr.cli;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.cli.SolrCLI.findTool;
 import static org.apache.solr.cli.SolrCLI.parseCmdLine;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -50,9 +47,7 @@
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.util.FastInputStream;
 import org.apache.solr.common.util.JsonRecordReader;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.junit.Test;
 
 @SolrTestCaseJ4.SuppressSSL
@@ -233,36 +228,14 @@
   @Test
   public void testWithBasicAuth() throws Exception {
     String COLLECTION_NAME = "secureCollection";
-    String USER = "solr";
-    String PASS = "SolrRocksAgain";
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
 
     try {
       CollectionAdminRequest.createCollection(COLLECTION_NAME, "conf", 2, 1)
-          .setBasicAuthCredentials(USER, PASS)
+          .setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS)
           .process(cluster.getSolrClient());
       cluster.waitForActiveCollection(COLLECTION_NAME, 2, 2);
 
@@ -273,7 +246,7 @@
         "-url",
         cluster.getJettySolrRunner(0).getBaseUrl() + "/" + COLLECTION_NAME,
         "-credentials",
-        USER + ":" + PASS,
+        SecurityJson.USER_PASS,
         "-out",
         outFile.getAbsolutePath(),
         "-verbose"
diff --git a/solr/core/src/test/org/apache/solr/cloud/DistribDocExpirationUpdateProcessorTest.java b/solr/core/src/test/org/apache/solr/cloud/DistribDocExpirationUpdateProcessorTest.java
index 4780839..143f1f4d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/DistribDocExpirationUpdateProcessorTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/DistribDocExpirationUpdateProcessorTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.solr.cloud;
 
-import static java.util.Collections.singletonList;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
-
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.HashMap;
@@ -43,11 +40,9 @@
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.TimeSource;
-import org.apache.solr.common.util.Utils;
 import org.apache.solr.handler.ReplicationHandler;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
 import org.apache.solr.update.processor.DocExpirationUpdateProcessorFactory;
+import org.apache.solr.util.SecurityJson;
 import org.apache.solr.util.TimeOut;
 import org.junit.After;
 import org.junit.Test;
@@ -91,30 +86,11 @@
 
     COLLECTION = "expiring";
     if (security) {
-      USER = "solr";
-      PASS = "SolrRocksAgain";
+      USER = SecurityJson.USER;
+      PASS = SecurityJson.PASS;
       COLLECTION += "_secure";
 
-      final String SECURITY_JSON =
-          Utils.toJSONString(
-              Map.of(
-                  "authorization",
-                  Map.of(
-                      "class",
-                      RuleBasedAuthorizationPlugin.class.getName(),
-                      "user-role",
-                      Map.of(USER, "admin"),
-                      "permissions",
-                      singletonList(Map.of("name", "all", "role", "admin"))),
-                  "authentication",
-                  Map.of(
-                      "class",
-                      BasicAuthPlugin.class.getName(),
-                      "blockUnknown",
-                      true,
-                      "credentials",
-                      Map.of(USER, getSaltedHashedValue(PASS)))));
-      b.withSecurityJson(SECURITY_JSON);
+      b.withSecurityJson(SecurityJson.SIMPLE);
     }
     b.configure();
 
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestPullReplicaWithAuth.java b/solr/core/src/test/org/apache/solr/cloud/TestPullReplicaWithAuth.java
index 63ae804..902c9e2 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestPullReplicaWithAuth.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestPullReplicaWithAuth.java
@@ -16,13 +16,10 @@
  */
 package org.apache.solr.cloud;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.cloud.TestPullReplica.assertNumberOfReplicas;
 import static org.apache.solr.cloud.TestPullReplica.assertUlogPresence;
 import static org.apache.solr.cloud.TestPullReplica.waitForDeletion;
 import static org.apache.solr.cloud.TestPullReplica.waitForNumDocsInAllReplicas;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
 import java.io.IOException;
 import java.util.EnumSet;
@@ -43,48 +40,24 @@
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class TestPullReplicaWithAuth extends SolrCloudTestCase {
 
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
   private static final String collectionName = "testPullReplicaWithAuth";
 
   @BeforeClass
   public static void setupClusterWithSecurityEnabled() throws Exception {
-    final String SECURITY_JSON =
-        Utils.toJSONString(
-            Map.of(
-                "authorization",
-                Map.of(
-                    "class",
-                    RuleBasedAuthorizationPlugin.class.getName(),
-                    "user-role",
-                    singletonMap(USER, "admin"),
-                    "permissions",
-                    singletonList(Map.of("name", "all", "role", "admin"))),
-                "authentication",
-                Map.of(
-                    "class",
-                    BasicAuthPlugin.class.getName(),
-                    "blockUnknown",
-                    true,
-                    "credentials",
-                    singletonMap(USER, getSaltedHashedValue(PASS)))));
-
     configureCluster(2)
         .addConfig("conf", configset("cloud-minimal"))
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
   }
 
   private <T extends SolrRequest<? extends SolrResponse>> T withBasicAuth(T req) {
-    req.setBasicAuthCredentials(USER, PASS);
+    req.setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS);
     return req;
   }
 
@@ -124,7 +97,8 @@
       }
 
       List<Replica> pullReplicas = s.getReplicas(EnumSet.of(Replica.Type.PULL));
-      waitForNumDocsInAllReplicas(numDocs, pullReplicas, "*:*", USER, PASS);
+      waitForNumDocsInAllReplicas(
+          numDocs, pullReplicas, "*:*", SecurityJson.USER, SecurityJson.PASS);
 
       for (Replica r : pullReplicas) {
         try (SolrClient pullReplicaClient = getHttpSolrClient(r)) {
@@ -170,7 +144,7 @@
     s = docCollection.getSlices().iterator().next();
     pullReplicas = s.getReplicas(EnumSet.of(Replica.Type.PULL));
     assertEquals(numPullReplicas, pullReplicas.size());
-    waitForNumDocsInAllReplicas(numDocs, pullReplicas, "*:*", USER, PASS);
+    waitForNumDocsInAllReplicas(numDocs, pullReplicas, "*:*", SecurityJson.USER, SecurityJson.PASS);
 
     withBasicAuth(CollectionAdminRequest.deleteCollection(collectionName))
         .process(cluster.getSolrClient());
diff --git a/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/BasicAuthIntegrationTracingTest.java b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/BasicAuthIntegrationTracingTest.java
index cdbf9f2..797f46b 100644
--- a/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/BasicAuthIntegrationTracingTest.java
+++ b/solr/modules/opentelemetry/src/test/org/apache/solr/opentelemetry/BasicAuthIntegrationTracingTest.java
@@ -16,10 +16,7 @@
  */
 package org.apache.solr.opentelemetry;
 
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
 import static org.apache.solr.opentelemetry.TestDistributedTracing.getAndClearSpans;
-import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
 
 import io.opentelemetry.api.GlobalOpenTelemetry;
 import io.opentelemetry.api.trace.TracerProvider;
@@ -32,7 +29,7 @@
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.util.Utils;
 import org.apache.solr.security.BasicAuthPlugin;
-import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+import org.apache.solr.util.SecurityJson;
 import org.apache.solr.util.tracing.TraceUtils;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -41,27 +38,6 @@
 public class BasicAuthIntegrationTracingTest extends SolrCloudTestCase {
 
   private static final String COLLECTION = "collection1";
-  private static final String USER = "solr";
-  private static final String PASS = "SolrRocksAgain";
-  private static final String SECURITY_JSON =
-      Utils.toJSONString(
-          Map.of(
-              "authorization",
-              Map.of(
-                  "class",
-                  RuleBasedAuthorizationPlugin.class.getName(),
-                  "user-role",
-                  singletonMap(USER, "admin"),
-                  "permissions",
-                  singletonList(Map.of("name", "all", "role", "admin"))),
-              "authentication",
-              Map.of(
-                  "class",
-                  BasicAuthPlugin.class.getName(),
-                  "blockUnknown",
-                  true,
-                  "credentials",
-                  singletonMap(USER, getSaltedHashedValue(PASS)))));
 
   @BeforeClass
   public static void setupCluster() throws Exception {
@@ -72,7 +48,7 @@
         .addConfig("config", TEST_PATH().resolve("collection1").resolve("conf"))
         .withSolrXml(TEST_PATH().resolve("solr.xml"))
         .withTraceIdGenerationDisabled()
-        .withSecurityJson(SECURITY_JSON)
+        .withSecurityJson(SecurityJson.SIMPLE)
         .configure();
 
     assertNotEquals(
@@ -81,7 +57,7 @@
         GlobalOpenTelemetry.get().getTracerProvider());
 
     CollectionAdminRequest.createCollection(COLLECTION, "config", 2, 2)
-        .setBasicAuthCredentials(USER, PASS)
+        .setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS)
         .process(cluster.getSolrClient());
     cluster.waitForActiveCollection(COLLECTION, 2, 4);
   }
@@ -106,7 +82,7 @@
             .withMethod(SolrRequest.METHOD.POST)
             .withPayload(Utils.toJSONString(ops))
             .build();
-    req.setBasicAuthCredentials(USER, PASS);
+    req.setBasicAuthCredentials(SecurityJson.USER, SecurityJson.PASS);
     assertEquals(0, req.process(cloudClient, COLLECTION).getStatus());
 
     var finishedSpans = getAndClearSpans();
diff --git a/solr/test-framework/src/java/org/apache/solr/util/SecurityJson.java b/solr/test-framework/src/java/org/apache/solr/util/SecurityJson.java
new file mode 100644
index 0000000..2b73b8f
--- /dev/null
+++ b/solr/test-framework/src/java/org/apache/solr/util/SecurityJson.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
+import static org.apache.solr.security.Sha256AuthenticationProvider.getSaltedHashedValue;
+
+import java.util.Map;
+import org.apache.solr.common.util.Utils;
+import org.apache.solr.security.BasicAuthPlugin;
+import org.apache.solr.security.RuleBasedAuthorizationPlugin;
+
+/**
+ * Provides security.json constants for use in tests that enable security.
+ *
+ * <p>Many tests require a simple security.json with one admin user and the BasicAuthPlugin enabled;
+ * such a configuration is represented by the SIMPLE constant here. Other variants of security.json
+ * can be moved to this class if and when they are duplicated by two or more tests.
+ */
+public final class SecurityJson {
+
+  private SecurityJson() {}
+
+  public static final String USER = "solr";
+  public static final String PASS = "SolrRocksAgain";
+  public static final String USER_PASS = USER + ":" + PASS;
+
+  public static final String SIMPLE =
+      Utils.toJSONString(
+          Map.of(
+              "authorization",
+              Map.of(
+                  "class",
+                  RuleBasedAuthorizationPlugin.class.getName(),
+                  "user-role",
+                  singletonMap(USER, "admin"),
+                  "permissions",
+                  singletonList(Map.of("name", "all", "role", "admin"))),
+              "authentication",
+              Map.of(
+                  "class",
+                  BasicAuthPlugin.class.getName(),
+                  "blockUnknown",
+                  true,
+                  "credentials",
+                  singletonMap(USER, getSaltedHashedValue(PASS)))));
+}