From b857d9f7f2220a102c5e6447de7f15b87da1e76d Mon Sep 17 00:00:00 2001 From: Prarthona Paul Date: Tue, 17 Oct 2023 13:44:41 -0400 Subject: [PATCH] [WFLY-18466] ejb-security-context-propagation Quickstart Common Enhancements CY2023Q3 --- .github/workflows/quickstart_ci.yml | 4 + ...rt_ejb-security-context-propagation_ci.yml | 16 ++ ejb-security-context-propagation/README.adoc | 46 ++---- .../configure-elytron.cli | 2 +- .../configure-system-exception.cli | 2 +- ejb-security-context-propagation/pom.xml | 144 +++++++++++++----- .../EJBServlet.java | 56 +++++++ .../IntermediateEJB.java | 2 +- .../src/main/webapp/WEB-INF/beans.xml | 22 +++ .../src/main/webapp/index.html | 20 +++ .../BasicRuntimeIT.java | 58 +++++++ .../SecurityContextPropagationIT.java} | 43 +++--- .../add-application-and-management-users.adoc | 5 + shared-doc/add-application-user.adoc | 3 + ...he-quickstart-with-provisioned-server.adoc | 24 +++ ...gration-tests-with-provisioned-server.adoc | 23 ++- 16 files changed, 371 insertions(+), 99 deletions(-) create mode 100644 .github/workflows/quickstart_ejb-security-context-propagation_ci.yml create mode 100644 ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/EJBServlet.java create mode 100644 ejb-security-context-propagation/src/main/webapp/WEB-INF/beans.xml create mode 100644 ejb-security-context-propagation/src/main/webapp/index.html create mode 100644 ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/BasicRuntimeIT.java rename ejb-security-context-propagation/src/{main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/RemoteClient.java => test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/SecurityContextPropagationIT.java} (71%) diff --git a/.github/workflows/quickstart_ci.yml b/.github/workflows/quickstart_ci.yml index 4007ee0cf6..16e171828b 100644 --- a/.github/workflows/quickstart_ci.yml +++ b/.github/workflows/quickstart_ci.yml @@ -89,6 +89,10 @@ jobs: cd ${{ inputs.QUICKSTART_PATH }} echo "Building provisioned server..." mvn -U -B -fae clean package -Pprovisioned-server + echo "Add quickstartUser..." + target/server/bin/add-user.sh -a -u 'quickstartUser' -p 'quickstartPwd1!' -g 'guest,user,JBossAdmin,Users' + echo "Add quickstartAdmin..." + target/server/bin/add-user.sh -a -u 'quickstartAdmin' -p 'adminPwd1!' -g 'guest,user,admin' echo "Starting provisioned server..." mvn -U -B -fae wildfly:start -DjbossHome=target/server -Dstartup-timeout=120 echo "Testing provisioned server..." diff --git a/.github/workflows/quickstart_ejb-security-context-propagation_ci.yml b/.github/workflows/quickstart_ejb-security-context-propagation_ci.yml new file mode 100644 index 0000000000..f5e1038920 --- /dev/null +++ b/.github/workflows/quickstart_ejb-security-context-propagation_ci.yml @@ -0,0 +1,16 @@ +name: WildFly ejb-security-context-propagation Quickstart CI + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - 'ejb-security-context-propagation/**' + - '.github/workflows/quickstart_ci.yml' + +jobs: + call-quickstart_ci: + uses: ./.github/workflows/quickstart_ci.yml + with: + QUICKSTART_PATH: ejb-security-context-propagation + TEST_PROVISIONED_SERVER: true + TEST_OPENSHIFT: false \ No newline at end of file diff --git a/ejb-security-context-propagation/README.adoc b/ejb-security-context-propagation/README.adoc index ef5f414e11..6eeb9b5934 100644 --- a/ejb-security-context-propagation/README.adoc +++ b/ejb-security-context-propagation/README.adoc @@ -195,20 +195,12 @@ Note that the `http-connector` in the `remoting` subsystem uses this `applicatio // Build and Deploy the Quickstart JAR include::../shared-doc/build-and-deploy-the-quickstart.adoc[leveloffset=+1] -== Run the Client - -Before you run the client, make sure you have already successfully deployed the EJBs to the server in the previous step and that your terminal is still in the same folder. - -Type this command to execute the client: - -[source,options="nowrap"] ----- -$ mvn exec:exec ----- +// Server Distribution Testing +include::../shared-doc/run-integration-tests-with-server-distribution.adoc[leveloffset=+2] == Investigate the Console Output -When you run the `mvn exec:exec` command, you see the following output. Note there may be other log messages interspersed between these. +When you run the integration tests, you see the following output. Note there may be other log messages interspersed between these. [source,options="nowrap"] ---- @@ -279,6 +271,8 @@ ERROR [org.jboss.as.ejb3.invocation] (default task-57) WFLYEJB0034: EJB Invocati at java.lang.Thread.run(Thread.java:745) ---- +// Server Distribution Testing +include::../shared-doc/run-integration-tests-with-server-distribution.adoc[leveloffset=+2] // Undeploy the Quickstart include::../shared-doc/undeploy-the-quickstart.adoc[leveloffset=+1] // Restore the {productName} Standalone Server Configuration @@ -305,30 +299,10 @@ The batch executed successfully // Restore the {productName} Standalone Server Configuration Manually include::../shared-doc/restore-standalone-server-configuration-manual.adoc[leveloffset=+2] -// Run the Quickstart in Red Hat CodeReady Studio or Eclipse -include::../shared-doc/run-the-quickstart-in-jboss-developer-studio.adoc[leveloffset=+1] - -// Additional Red Hat CodeReady Studio instructions -This quickstart requires additional configuration and deploys and runs differently in {JBDSProductName} than the other quickstarts. - -. Make sure you xref:add_the_application_users[Add the Application Users] as described above. -. Follow the steps above to xref:configure_the_server[Configure the Server]. Stop the server at the end of that step. -. To deploy the application to the {productName} server, right-click on the *{artifactId}* project and choose *Run As* -> *Run on Server*. -. To access the application, right-click on the *{artifactId}* project and choose *Run As* -> *Java Application*. -. Choose *RemoteClient - org.jboss.as.quickstarts.ejb_security_context_propagation* and click *OK*. -. Review the output in the console window. -. To undeploy the project, right-click on the *{artifactId}* project and choose *Run As* -> *Maven build*. Enter `wildfly:undeploy` for the *Goals* and click *Run*. -. Make sure you xref:restore_the_server_configuration[restore the server configuration] when you have completed testing this quickstart. - -// Debug the Application -include::../shared-doc/debug-the-application.adoc[leveloffset=+1] - -//************************************************* -// Product Release content only -//************************************************* -ifdef::ProductRelease[] +// Build and run sections for other environments/builds +ifndef::ProductRelease,EAPXPRelease[] +include::../shared-doc/build-and-run-the-quickstart-with-provisioned-server.adoc[leveloffset=+1] +endif::[] // Quickstart not compatible with OpenShift -include::../shared-doc/openshift-incompatibility.adoc[leveloffset=+1] - -endif::[] \ No newline at end of file +include::../shared-doc/openshift-incompatibility.adoc[leveloffset=+1] \ No newline at end of file diff --git a/ejb-security-context-propagation/configure-elytron.cli b/ejb-security-context-propagation/configure-elytron.cli index dfaa6a8165..89b640fec6 100644 --- a/ejb-security-context-propagation/configure-elytron.cli +++ b/ejb-security-context-propagation/configure-elytron.cli @@ -24,6 +24,6 @@ batch run-batch # Reload the server configuration -reload +#reload diff --git a/ejb-security-context-propagation/configure-system-exception.cli b/ejb-security-context-propagation/configure-system-exception.cli index 994af5c5c4..3eacbff716 100644 --- a/ejb-security-context-propagation/configure-system-exception.cli +++ b/ejb-security-context-propagation/configure-system-exception.cli @@ -10,6 +10,6 @@ batch run-batch # Reload the server configuration -reload +#reload diff --git a/ejb-security-context-propagation/pom.xml b/ejb-security-context-propagation/pom.xml index 151676346f..5930e6b465 100644 --- a/ejb-security-context-propagation/pom.xml +++ b/ejb-security-context-propagation/pom.xml @@ -30,7 +30,7 @@ ejb-security-context-propagation 31.0.0.Beta1-SNAPSHOT - ejb + war Quickstart: ejb-security-context-propagation This project demonstrates the security context propagation between remote EJBs @@ -43,10 +43,12 @@ - - jdt_apt + + 30.0.0.Final - 30.0.0.Final + ${version.server} + 5.0.0.Final + 4.2.0.Final @@ -110,7 +112,7 @@ org.wildfly.bom wildfly-ee-with-tools - ${version.server.bom} + ${version.bom.ee} pom import @@ -144,44 +146,108 @@ jakarta.ejb-api + + + jakarta.servlet + jakarta.servlet-api + provided + + + + + junit + junit + test + ${project.artifactId} - - - - org.apache.maven.plugins - maven-ejb-plugin - - 3.2 - true - - - - - org.codehaus.mojo - exec-maven-plugin - - java - ${project.build.directory}/exec-working-directory - - - -classpath - - org.jboss.as.quickstarts.ejb_security_context_propagation.RemoteClient - - - - - - exec - - - - - + + + + org.apache.maven.plugins + maven-ejb-plugin + + 3.2 + true + + + + org.wildfly.plugins + wildfly-maven-plugin + ${version.plugin.wildfly} + + + + + + provisioned-server + + + + org.wildfly.plugins + wildfly-maven-plugin + + + + org.wildfly:wildfly-galleon-pack:${version.server} + + + + + cloud-server + ejb + + + + + + + + + false + + + + ROOT.war + + + + + package + + + + + + + + + integration-testing + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + **/*IT + + + + + + integration-test + verify + + + + + + + + diff --git a/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/EJBServlet.java b/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/EJBServlet.java new file mode 100644 index 0000000000..b7d4104c11 --- /dev/null +++ b/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/EJBServlet.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 JBoss by Red Hat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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.jboss.as.quickstarts.ejb_security_context_propagation; + +import java.io.IOException; +import java.io.PrintWriter; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +/** + *

+ * A simple servlet which indicates successful deployment of the quickstart. + *

+ * + *

+ * The servlet is registered and mapped to /ejb-security-context-propagation using the {@linkplain WebServlet + * @HttpServlet}. + *

+ * + * @author Prarthona Paul + * + */ + +@WebServlet("/ejb-security-context-propagation") +public class EJBServlet extends HttpServlet { + + static String PAGE_HEADER = "ejb-security-context-propagation"; + + static String PAGE_FOOTER = ""; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + resp.setContentType("text/html"); + PrintWriter writer = resp.getWriter(); + writer.println(PAGE_HEADER); + writer.println("ejb-security-context-propagation quickstart deployed successfully. You can find the available operations in the included README file."); + writer.println(PAGE_FOOTER); + writer.close(); + } +} \ No newline at end of file diff --git a/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/IntermediateEJB.java b/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/IntermediateEJB.java index e1dce496be..966b02e738 100644 --- a/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/IntermediateEJB.java +++ b/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/IntermediateEJB.java @@ -36,7 +36,7 @@ @PermitAll public class IntermediateEJB implements IntermediateEJBRemote { - @EJB(lookup="ejb:/ejb-security-context-propagation/SecuredEJB!org.jboss.as.quickstarts.ejb_security_context_propagation.SecuredEJBRemote") + @EJB private SecuredEJBRemote remote; @Resource diff --git a/ejb-security-context-propagation/src/main/webapp/WEB-INF/beans.xml b/ejb-security-context-propagation/src/main/webapp/WEB-INF/beans.xml new file mode 100644 index 0000000000..f418aba2f0 --- /dev/null +++ b/ejb-security-context-propagation/src/main/webapp/WEB-INF/beans.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/ejb-security-context-propagation/src/main/webapp/index.html b/ejb-security-context-propagation/src/main/webapp/index.html new file mode 100644 index 0000000000..09fa6ed02b --- /dev/null +++ b/ejb-security-context-propagation/src/main/webapp/index.html @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/BasicRuntimeIT.java b/ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/BasicRuntimeIT.java new file mode 100644 index 0000000000..1f87cdac82 --- /dev/null +++ b/ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/BasicRuntimeIT.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023 JBoss by Red Hat. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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.jboss.as.quickstarts.ejb_security_context_propagation; + +import org.junit.Test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + +import static org.junit.Assert.assertEquals; + +/** + * The very basic runtime integration testing. + * @author Prarthona Paul + * @author emartins + */ +public class BasicRuntimeIT { + private static final String DEFAULT_SERVER_HOST = "http://localhost:8080/ejb-security-context-propagation"; + + @Test + public void testHTTPEndpointIsAvailable() throws IOException, InterruptedException, URISyntaxException { + String serverHost = System.getenv("SERVER_HOST"); + if (serverHost == null) { + serverHost = System.getProperty("server.host"); + } + if (serverHost == null) { + serverHost = DEFAULT_SERVER_HOST; + } + final HttpRequest request = HttpRequest.newBuilder() + .uri(new URI(serverHost+"/")) + .GET() + .build(); + final HttpClient client = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.ALWAYS) + .connectTimeout(Duration.ofMinutes(1)) + .build(); + final HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, response.statusCode()); + } +} diff --git a/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/RemoteClient.java b/ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/SecurityContextPropagationIT.java similarity index 71% rename from ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/RemoteClient.java rename to ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/SecurityContextPropagationIT.java index 58a1bb0b6c..8e6ca12bd2 100644 --- a/ejb-security-context-propagation/src/main/java/org/jboss/as/quickstarts/ejb_security_context_propagation/RemoteClient.java +++ b/ejb-security-context-propagation/src/test/java/org/jboss/as/quickstarts/ejb_security_context_propagation/SecurityContextPropagationIT.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source - * Copyright 2017, Red Hat, Inc. and/or its affiliates, and individual - * contributors by the @authors tag. See the copyright.txt in the - * distribution for a full listing of individual contributors. + * Copyright 2023 JBoss by Red Hat. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. @@ -16,43 +15,47 @@ */ package org.jboss.as.quickstarts.ejb_security_context_propagation; -import java.util.Hashtable; - -import javax.naming.Context; -import javax.naming.InitialContext; - +import org.junit.Test; import org.wildfly.security.auth.client.AuthenticationConfiguration; import org.wildfly.security.auth.client.AuthenticationContext; import org.wildfly.security.auth.client.MatchRule; import org.wildfly.security.sasl.SaslMechanismSelector; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.util.Hashtable; + /** - * The remote client responsible for making invoking the intermediate bean to demonstrate security context propagation - * in EJB to remote EJB calls. - * + * The functional integration testing. + * @author emartins * @author Stefan Guilhen + * */ -public class RemoteClient { +public class SecurityContextPropagationIT { - public static void main(String[] args) throws Exception { + @Test + public void testSecurityContextPropagation() throws NamingException { + // we assume standard dist, where EJBs are at ejb:/ejb-security-context-propagation/, if no SERVER_HOST or server.host in env/system props + final boolean standardDist = System.getenv("SERVER_HOST") == null && System.getProperty("server.host") == null; + System.out.println("standardDist: "+standardDist); // invoke the intermediate bean using the identity configured in wildfly-config.xml - invokeIntermediateBean(); - + invokeIntermediateBean(standardDist); // now lets programmatically setup an authentication context to switch users before invoking the intermediate bean AuthenticationConfiguration superUser = AuthenticationConfiguration.empty().setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("PLAIN")). useName("quickstartAdmin").usePassword("adminPwd1!"); final AuthenticationContext authCtx = AuthenticationContext.empty().with(MatchRule.ALL, superUser); AuthenticationContext.getContextManager().setThreadDefault(authCtx); - invokeIntermediateBean(); + invokeIntermediateBean(standardDist); } - private static void invokeIntermediateBean() throws Exception { + private static void invokeIntermediateBean(boolean standardDist) throws NamingException { final Hashtable jndiProperties = new Hashtable<>(); jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); jndiProperties.put(Context.PROVIDER_URL, "remote+http://localhost:8080"); final Context context = new InitialContext(jndiProperties); - IntermediateEJBRemote intermediate = (IntermediateEJBRemote) context.lookup("ejb:/ejb-security-context-propagation/IntermediateEJB!" + IntermediateEJBRemote intermediate = (IntermediateEJBRemote) context.lookup("ejb:/"+(standardDist?"ejb-security-context-propagation":"ROOT")+"/IntermediateEJB!" + IntermediateEJBRemote.class.getName()); System.out.println("\n\n* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n"); System.out.println(intermediate.makeRemoteCalls()); diff --git a/shared-doc/add-application-and-management-users.adoc b/shared-doc/add-application-and-management-users.adoc index e99c11d6f0..cf911acf79 100644 --- a/shared-doc/add-application-and-management-users.adoc +++ b/shared-doc/add-application-and-management-users.adoc @@ -27,6 +27,11 @@ ifndef::admin-user-groups[] :admin-group-list: :admin-group-command: endif::admin-user-groups[] + +// attr which other sections may check (ifdef) to know if users needs to be added +:addQuickstartUser: true +:addQuickstartAdmin: true + This quickstart uses secured management interfaces and requires that you create the following application user to access the running application. [cols="20%,20%,20%,40%",options="headers"] diff --git a/shared-doc/add-application-user.adoc b/shared-doc/add-application-user.adoc index 87988ab46f..406fc7e1d8 100644 --- a/shared-doc/add-application-user.adoc +++ b/shared-doc/add-application-user.adoc @@ -17,6 +17,9 @@ ifndef::app-user-groups[] :app-group-command: endif::app-user-groups[] +// attr which other sections may check (ifdef) to know if users needs to be added +:addQuickstartUser: true + This quickstart uses secured application interfaces and requires that you create the following application user to access the running application. [cols="20%,20%,20%,40%",options="headers"] diff --git a/shared-doc/build-and-run-the-quickstart-with-provisioned-server.adoc b/shared-doc/build-and-run-the-quickstart-with-provisioned-server.adoc index ffa7f03a1f..82119b6dbf 100644 --- a/shared-doc/build-and-run-the-quickstart-with-provisioned-server.adoc +++ b/shared-doc/build-and-run-the-quickstart-with-provisioned-server.adoc @@ -23,6 +23,30 @@ $ mvn {mavenServerProvisioningCommand} -Pprovisioned-server The provisioned {productName} server, with the quickstart deployed, can then be found in the `target/server` directory, and its usage is similar to a standard server distribution, with the simplification that there is never the need to specify the server configuration to be started. +ifdef::addQuickstartUser[] +The quickstart user should be added before running the provisioned server: +[source,subs="+quotes,attributes+",options="nowrap"] +---- +$ target/server/bin/add-user.sh -a -u 'quickstartUser' -p 'quickstartPwd1!' {app-group-command} +---- +[NOTE] +==== +For Windows, use the `__{jbossHomeName}__\bin\add-user.bat` script. +==== +endif::[] + +ifdef::addQuickstartAdmin[] +The quickstart admin should be added before running the provisioned server: +[source,subs="+quotes,attributes+",options="nowrap"] +---- +$ target/server/bin/add-user.sh -a -u 'quickstartAdmin' -p 'adminPwd1!' {admin-group-command} +---- +[NOTE] +==== +For Windows, use the `__{jbossHomeName}__\bin\add-user.bat` script. +==== +endif::[] + The server provisioning functionality is provided by the WildFly Maven Plugin, and you may find its configuration in the quickstart `pom.xml`: [source,xml,subs="attributes+"] diff --git a/shared-doc/run-integration-tests-with-provisioned-server.adoc b/shared-doc/run-integration-tests-with-provisioned-server.adoc index 574eae2319..2aaa9082b3 100644 --- a/shared-doc/run-integration-tests-with-provisioned-server.adoc +++ b/shared-doc/run-integration-tests-with-provisioned-server.adoc @@ -14,7 +14,28 @@ Follow these steps to run the integration tests. $ mvn clean package -Pprovisioned-server ---- -. Start the {productName} provisioned server, this time using the {productName} Maven Plugin, which is recommend for testing due to simpler automation. The path to the provisioned server should be specified using the `server.host` system property. +ifdef::addQuickstartUser[] +Add the quickstart user: +[source,subs="+quotes,attributes+",options="nowrap"] +---- +$ target/server/bin/add-user.sh -a -u 'quickstartUser' -p 'quickstartPwd1!' {app-group-command} +---- +endif::[] + +ifdef::addQuickstartAdmin[] +Add the quickstart admin: +[source,subs="+quotes,attributes+",options="nowrap"] +---- +$ target/server/bin/add-user.sh -a -u 'quickstartAdmin' -p 'adminPwd1!' {admin-group-command} +---- +[NOTE] +==== +For Windows, use the `__{jbossHomeName}__\bin\add-user.bat` script. +==== +endif::[] + + +. Start the {productName} provisioned server, this time using the {productName} Maven Plugin, which is recommended for testing due to simpler automation. The path to the provisioned server should be specified using the `server.host` system property. + [source,subs="attributes+",options="nowrap"] ----