Chapter 2. Securing management interfaces and applications 2.1. Adding authentication and authorization to management interfaces You can add authentication and authorization for management interfaces to secure them by using a security domain. To access the management interfaces after you add authentication and authorization, users must enter login credentials. You can secure JBoss EAP management interfaces as follows: Management CLI By configuring a sasl-authentication-factory . Management console By configuring an http-authentication-factory . Prerequisites You have created a security domain referencing a security realm. JBoss EAP is running. Procedure Create an http-authentication-factory , or a sasl-authentication-factory . Create an http-authentication-factory . Syntax Example Create a sasl-authentication-factory . Syntax Example Update the management interfaces. Use the http-authentication-factory to secure the management console. Syntax Example Use the sasl-authentication-factory to secure the management CLI. Syntax Example Reload the server. Verification To verify that the management console requires authentication and authorization, navigate to the management console at http://127.0.0.1:9990/console/index.html . You are prompted to enter user name and password. To verify that the management CLI requires authentication and authorization, start the management CLI using the following command: You are prompted to enter user name and password. Additional resources http-authentication-factory attributes sasl-authentication-factory attributes 2.2. Using a security domain to authenticate and authorize application users Use a security domain that references a security realm to authenticate and authorize application users. The procedures for developing an application are provided only as an example. 2.2.1. Developing a simple web application for aggregate-realm You can create a simple web application to follow along with the configuring security realms examples. Note The following procedures are provided as an example only. If you already have an application that you want to secure, you can skip these and go directly to Adding authentication and authorization to applications . 2.2.1.1. Creating a maven project for web-application development For creating a web-application, create a Maven project with the required dependencies and the directory structure. Prerequisites You have installed Maven. For more information, see Downloading Apache Maven . Procedure Set up a Maven project using the mvn command. The command creates the directory structure for the project and the pom.xml configuration file. Syntax Example Navigate to the application root directory: Syntax Example Replace the content of the generated pom.xml file with the following text: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.app</groupId> <artifactId>simple-webapp-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>simple-webapp-example Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.wildfly.security</groupId> <artifactId>wildfly-elytron-auth-server</artifactId> <version>1.19.0.Final</version> </dependency> </dependencies> <build> <finalName>USD{project.artifactId}</finalName> <plugins> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>2.1.0.Final</version> </plugin> </plugins> </build> </project> Verification In the application root directory, enter the following command: You get an output similar to the following: You can now create a web-application. 2.2.1.2. Creating a web application Create a web application containing a servlet that returns the user name obtained from the logged-in user's principal and attributes. If there is no logged-in user, the servlet returns the text "NO AUTHENTICATED USER". Prerequisites You have created a Maven project. JBoss EAP is running. Procedure Create a directory to store the Java files. Syntax Example Navigate to the new directory. Syntax Example Create a file SecuredServlet.java with the following content: package com.example.app; import java.io.IOException; import java.io.PrintWriter; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.authz.Attributes; import org.wildfly.security.authz.Attributes.Entry; /** * A simple secured HTTP servlet. It returns the user name and * attributes obtained from the logged-in user's Principal. If * there is no logged-in user, it returns the text * "NO AUTHENTICATED USER". */ @WebServlet("/secured") public class SecuredServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (PrintWriter writer = resp.getWriter()) { Principal user = req.getUserPrincipal(); SecurityIdentity identity = SecurityDomain.getCurrent().getCurrentSecurityIdentity(); Attributes identityAttributes = identity.getAttributes(); Set <String> keys = identityAttributes.keySet(); String attributes = "<ul>"; for (String attr : keys) { attributes += "<li> " + attr + " : " + identityAttributes.get(attr).toString() + "</li>"; } attributes+="</ul>"; writer.println("<html>"); writer.println(" <head><title>Secured Servlet</title></head>"); writer.println(" <body>"); writer.println(" <h1>Secured Servlet</h1>"); writer.println(" <p>"); writer.print(" Current Principal '"); writer.print(user != null ? user.getName() : "NO AUTHENTICATED USER"); writer.print("'"); writer.print(user != null ? "\n" + attributes : ""); writer.println(" </p>"); writer.println(" </body>"); writer.println("</html>"); } } } In the application root directory, compile your application with the following command: Deploy the application. Verification In a browser, navigate to http://localhost:8080/simple-webapp-example/secured . You get the following message: Because no authentication mechanism is added, you can access the application. You can now secure this application by using a security domain so that only authenticated users can access it. 2.2.2. Adding authentication and authorization to applications You can add authentication and authorization to web applications to secure them by using a security domain. To access the web applications after you add authentication and authorization, users must enter login credentials. Prerequisites You have created a security domain referencing a security realm. You have deployed applications on JBoss EAP. JBoss EAP is running. Procedure Configure an application-security-domain in the undertow subsystem : Syntax Example Configure the application's web.xml to protect the application resources. Syntax <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- Define the security constraints for the application resources. Specify the URL pattern for which a challenge is --> <security-constraint> <web-resource-collection> <web-resource-name><!-- Name of the resources to protect --></web-resource-name> <url-pattern> <!-- The URL to protect --></url-pattern> </web-resource-collection> <!-- Define the role that can access the protected resource --> <auth-constraint> <role-name> <!-- Role name as defined in the security domain --></role-name> <!-- To disable authentication you can use the wildcard * To authenticate but allow any role, use the wildcard **. --> </auth-constraint> </security-constraint> <login-config> <auth-method> <!-- The authentication method to use. Can be: BASIC CLIENT-CERT DIGEST FORM SPNEGO --> </auth-method> <realm-name><!-- The name of realm to send in the challenge --></realm-name> </login-config> </web-app> Example <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- Define the security constraints for the application resources. Specify the URL pattern for which a challenge is --> <security-constraint> <web-resource-collection> <web-resource-name>all</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <!-- Define the role that can access the protected resource --> <auth-constraint> <role-name>Admin</role-name> <!-- To disable authentication you can use the wildcard * To authenticate but allow any role, use the wildcard **. --> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>exampleSecurityRealm</realm-name> </login-config> </web-app> Note You can use a different auth-method . Configure your application to use a security domain by either creating a jboss-web.xml file in your application or setting the default security domain in the undertow subsystem. Create jboss-web.xml file in the your application's WEB-INF directory referencing the application-security-domain . Syntax <jboss-web> <security-domain> <!-- The security domain to associate with the application --></security-domain> </jboss-web> Example <jboss-web> <security-domain>exampleApplicationSecurityDomain</security-domain> </jboss-web> Set the default security domain in the undertow subsystem for applications. Syntax Example Reload the server. Verification In the application root directory, compile your application with the following command: Deploy the application. In a browser, navigate to http://localhost:8080/simple-webapp-example/secured . You get a login prompt confirming that authentication is now required to access the application. Your application is now secured with a security domain and users can log in only after authenticating. Additionally, only users with specified roles can access the application.

Commands:
/subsystem=elytron/http-authentication-factory= <authentication_factory_name> :add(http-server-mechanism-factory=global, security-domain= <security_domain_name> , mechanism-configurations=[{mechanism-name= <mechanism-name> , mechanism-realm-configurations=[{realm-name= <realm_name> }]}])
/subsystem=elytron/http-authentication-factory=exampleAuthenticationFactory:add(http-server-mechanism-factory=global, security-domain=exampleSecurityDomain, mechanism-configurations=[{mechanism-name=BASIC, mechanism-realm-configurations=[{realm-name=exampleSecurityRealm}]}]) {"outcome" => "success"}
/subsystem=elytron/sasl-authentication-factory= <sasl_authentication_factory_name> :add(security-domain= <security_domain> ,sasl-server-factory=configured,mechanism-configurations=[{mechanism-name= <mechanism-name> ,mechanism-realm-configurations=[{realm-name= <realm_name> }]}])
/subsystem=elytron/sasl-authentication-factory=exampleSaslAuthenticationFactory:add(security-domain=exampleSecurityDomain,sasl-server-factory=configured,mechanism-configurations=[{mechanism-name=PLAIN,mechanism-realm-configurations=[{realm-name=exampleSecurityRealm}]}]) {"outcome" => "success"}
/core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value= <authentication_factory_name> )
/core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=exampleAuthenticationFactory) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade,value={enabled=true,sasl-authentication-factory= <sasl_authentication_factory> })
/core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade,value={enabled=true,sasl-authentication-factory=exampleSaslAuthenticationFactory}) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
reload
bin/jboss-cli.sh --connect
mvn archetype:generate -DgroupId= USD{group-to-which-your-application-belongs} -DartifactId= USD{name-of-your-application} -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
mvn archetype:generate -DgroupId=com.example.app -DartifactId=simple-webapp-example -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
cd <name-of-your-application>
cd simple-webapp-example
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example.app</groupId> <artifactId>simple-webapp-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>simple-webapp-example Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.wildfly.security</groupId> <artifactId>wildfly-elytron-auth-server</artifactId> <version>1.19.0.Final</version> </dependency> </dependencies> <build> <finalName>USD{project.artifactId}</finalName> <plugins> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>2.1.0.Final</version> </plugin> </plugins> </build> </project>
mvn install
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.795 s [INFO] Finished at: 2022-04-28T17:39:48+05:30 [INFO] ------------------------------------------------------------------------
mkdir -p src/main/java/<path_based_on_artifactID>
mkdir -p src/main/java/com/example/app
cd src/main/java/<path_based_on_artifactID>
cd src/main/java/com/example/app
package com.example.app; import java.io.IOException; import java.io.PrintWriter; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.authz.Attributes; import org.wildfly.security.authz.Attributes.Entry; /** * A simple secured HTTP servlet. It returns the user name and * attributes obtained from the logged-in user's Principal. If * there is no logged-in user, it returns the text * "NO AUTHENTICATED USER". */ @WebServlet("/secured") public class SecuredServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (PrintWriter writer = resp.getWriter()) { Principal user = req.getUserPrincipal(); SecurityIdentity identity = SecurityDomain.getCurrent().getCurrentSecurityIdentity(); Attributes identityAttributes = identity.getAttributes(); Set <String> keys = identityAttributes.keySet(); String attributes = "<ul>"; for (String attr : keys) { attributes += "<li> " + attr + " : " + identityAttributes.get(attr).toString() + "</li>"; } attributes+="</ul>"; writer.println("<html>"); writer.println(" <head><title>Secured Servlet</title></head>"); writer.println(" <body>"); writer.println(" <h1>Secured Servlet</h1>"); writer.println(" <p>"); writer.print(" Current Principal '"); writer.print(user != null ? user.getName() : "NO AUTHENTICATED USER"); writer.print("'"); writer.print(user != null ? "\n" + attributes : ""); writer.println(" </p>"); writer.println(" </body>"); writer.println("</html>"); } } }
mvn package [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.015 s [INFO] Finished at: 2022-04-28T17:48:53+05:30 [INFO] ------------------------------------------------------------------------
mvn wildfly:deploy
Secured Servlet Current Principal 'NO AUTHENTICATED USER'
/subsystem=undertow/application-security-domain= <application_security_domain_name> :add(security-domain= <security_domain_name> )
/subsystem=undertow/application-security-domain=exampleApplicationSecurityDomain:add(security-domain=exampleSecurityDomain) {"outcome" => "success"}
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- Define the security constraints for the application resources. Specify the URL pattern for which a challenge is --> <security-constraint> <web-resource-collection> <web-resource-name><!-- Name of the resources to protect --></web-resource-name> <url-pattern> <!-- The URL to protect --></url-pattern> </web-resource-collection> <!-- Define the role that can access the protected resource --> <auth-constraint> <role-name> <!-- Role name as defined in the security domain --></role-name> <!-- To disable authentication you can use the wildcard * To authenticate but allow any role, use the wildcard **. --> </auth-constraint> </security-constraint> <login-config> <auth-method> <!-- The authentication method to use. Can be: BASIC CLIENT-CERT DIGEST FORM SPNEGO --> </auth-method> <realm-name><!-- The name of realm to send in the challenge --></realm-name> </login-config> </web-app>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- Define the security constraints for the application resources. Specify the URL pattern for which a challenge is --> <security-constraint> <web-resource-collection> <web-resource-name>all</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <!-- Define the role that can access the protected resource --> <auth-constraint> <role-name>Admin</role-name> <!-- To disable authentication you can use the wildcard * To authenticate but allow any role, use the wildcard **. --> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>exampleSecurityRealm</realm-name> </login-config> </web-app>
<jboss-web> <security-domain> <!-- The security domain to associate with the application --></security-domain> </jboss-web>
<jboss-web> <security-domain>exampleApplicationSecurityDomain</security-domain> </jboss-web>
/subsystem=undertow:write-attribute(name=default-security-domain,value= <application_security_domain_to_use> )
/subsystem=undertow:write-attribute(name=default-security-domain,value=exampleApplicationSecurityDomain) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
reload
mvn package [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.015 s [INFO] Finished at: 2022-04-28T17:48:53+05:30 [INFO] ------------------------------------------------------------------------
mvn wildfly:deploy