Configuring HTTP Basic Authentication with WildFly

In this tutorial we will learn how to configure HTTP basic authentication with WildFly.

Basic authentication is a simple authentication policy built into the HTTP protocol. The client sends an HTTP request with the Authorization header that contains the word Basic word followed by a space and a base64-encoded string username:password.

wildfly basic authentication wildfly basic authentication

As an example, in order to authorize as demo / p@55w0rd the client would send

Authorization: Basic ZGVtbzpwQDU1dzByZA==

Note: Because base64 is easily decoded, Basic authentication should only be used together with other security mechanisms such as HTTPS/SSL.

Example: enabling HTTP Basic Authentication in WildFly

In order to enable HTTP Basic Authentication in WildFly we will define a Security Realm with Elytron. The most basic example of a security realm is the FileSystem Realm, which stores the identity information on a filesystem, by paging each identity in an XML file containing credentials and Roles. Start the application server and connect to it from a CLI (jboss-cli.sh). Then execute the following commands:

# add a Simple Role Decoder which maps the application Roles from the attribute Roles in the File system.

if (outcome != success) of /subsystem=elytron/simple-role-decoder=from-roles-attribute:read-resource
     /subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
end-if

batch

# Let’s define a new filesystem-realm named fsRealm and its respective path on the file system:
/subsystem=elytron/filesystem-realm=demoFsRealm:add(path=demofs-realm-users,relative-to=jboss.server.config.dir)

# Next, we add some identities to the Realm:
/subsystem=elytron/filesystem-realm=demoFsRealm:add-identity(identity=frank)
/subsystem=elytron/filesystem-realm=demoFsRealm:set-password(identity=frank,clear={password="password123"})
/subsystem=elytron/filesystem-realm=demoFsRealm:add-identity-attribute(identity=frank,name=Roles, value=["Admin","Guest"])

# Create a new Security Domain which maps our Realm:
/subsystem=elytron/security-domain=fsSD:add(realms=[{realm=demoFsRealm,role-decoder=from-roles-attribute}],default-realm=demoFsRealm,permission-mapper=default-permission-mapper)

# We need an Http Authentication Factory which references our Security Domain:
/subsystem=elytron/http-authentication-factory=example-fs-http-auth:add(http-server-mechanism-factory=global,security-domain=fsSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=RealmUsersRoles}]}])

# Finally, a Security Domain in the undertow’s subsystem will be associated with our Http Authentication Factory:
/subsystem=undertow/application-security-domain=FSSecurityDomain:add(http-authentication-factory=example-fs-http-auth)

run-batch

reload

Then set the security domain in “jboss-web.xml“:

<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.jboss.org/schema/jbossas
    http://www.jboss.org/schema/jbossas/jboss-web_7_2.xsd">
   <security-domain>FSSecurityDomain</security-domain>
</jboss-web>

And configure th auth-method in your web.xml:

<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

   <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>RealmUsersRoles</realm-name>
   </login-config>
</web-app>

Our application defines a single endpoint, which has an HttpConstraint allowing access only to “Admin” users:

@WebServlet("/secure")
@ServletSecurity(@HttpConstraint(rolesAllowed = { "Admin" }))
public class SecuredServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        Principal principal = null;
        String authType = null;
        String remoteUser = null;

        principal = req.getUserPrincipal();

        remoteUser = req.getRemoteUser();

        authType = req.getAuthType();

        writer.println("servlet-security");
        writer.println("Successfully called Secured Servlet");
        writer.println("Principal : " + principal.getName() + ");
        writer.println("Remote User : " + remoteUser + ");
        writer.println("Authentication Type : " + authType + ");
        writer.println("");
        writer.close();
    }

}

Let’s send a request to the secured endpoint:

curl -u frank:password123 http://localhost:8080/http-basic/secure
Successfully called Secured Servlet 
Principal  : frank
Remote User : frank
Authentication Type : BASIC

You can find the souce code for this example here: https://github.com/fmarchioni/mastertheboss/tree/master/security/http-basic

Setting HTTP Basic authentication for Web Services

In case you are using EJB-based Web Services the configuration is slightly different; because the security domain is not specified into the web descriptors, we have to provide it by means of annotations:

@Stateless
@WebService(targetNamespace = "/",
serviceName = "SecureService")
@WebContext(authMethod = "BASIC",
secureWSDLAccess = false)
@SecurityDomain(value = "other")
public class SecureEJB { }

As you can see, the @WebContext annotation basically reflects the same configuration options of POJO-based Web Services, with BASIC authentication and unrestricted WSDL access.

Basic authentication using Database

If you want to learn how to configure authentication using a Database instead of a property file, check this tutorial: Configure an Elytron JDBC Realm on WildFly


Recommended Articles

Set Up WildFly Elytron LDAP Realm Tutorial

Learn how to set up an LDAP realm using WildFly Elytron security subsystem. Includes Docker setup and user authentication.

Elytron Security Framework Overview & File System Realm Tutorial - WildFly

Learn how to secure applications using Elytron's unified security solution in WildFly. Create a sample File System Realm and encrypt identity content.

Optimize WildFly Authentication Performance with Elytron Caching Realms

Boost your WildFly applications' performance by configuring an Elytron caching realm to cache user credentials from a security realm like LDAP.

Create a Custom Elytron Realm in WildFly 31: A Step-by-Step Guide

Learn how to create a custom realm in Elytron, a modern replacement for legacy Login Modules, with this comprehensive tutorial. Get started with creating a custom realm using WildFly 31 and configuring it to store user credentials.