This tutorial guides you through setting up an LDAP realm using the WildFly Elytron security subsystem for user authentication. We will learn how to bootstrap a sample LDAP Server with docker and create an LDAP Realm on WildFly
Hard requirements
- WildFly application server
- A LDAP Server or a Docker deamon to start an LDAP Server in a Container
For the sake of simplicity, we will start a Containerised version of OpenLdap, which is available in the DockerHub, using as BASE DN wildfly.org:
$ docker run -p 389:389 --env LDAP_ORGANISATION="wildfly" --env LDAP_DOMAIN="wildfly.org" --env LDAP_ADMIN_PASSWORD="admin" osixia/openldap:1.5.0
As an alternative, you can set the BASE DN in your slapf.conf and set the default admin password.
The LDAP Server will start and bind to all available IP Addresses:
$ docker ps 7403a4730be6 osixia/openldap:1.5.0 "/container/tool/run" 8 seconds ago Up 7 seconds 0.0.0.0:389->389/tcp, :::389->389/tcp, 636/tcp hopeful_archimedes
You can verify the connectivity through any LDAP Browser. For example, to connect with the default Docker IP Address (172.17.0.2):

Since the LDAP Server binds on all IP Addresses, you should be able to connect through the localhost loopback address as well.
Then, we will upload a sample ldif file which will contain one user named “frank” which is granted the Role “Admin”:
dn: ou=Users,dc=wildfly,dc=org objectclass: top objectclass: organizationalUnit ou: Users dn: ou=Roles,dc=wildfly,dc=org objectclass: top objectclass: organizationalUnit ou: Roles dn: uid=frank,ou=Users,dc=wildfly,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson uid: frank cn: Frank sn: White mail: [email protected] postalCode: 88441 userPassword: secret123 dn: cn=Admin,ou=Roles,dc=wildfly,dc=org objectclass: top objectclass: groupOfNames cn: Admin member: uid=frank,ou=Users,dc=wildfly,dc=org
You can upload the LDIF file with the ldapadd command. For example:
ldapadd -x -D "cn=admin,dc=wildfly,dc=org" -w admin -H ldap://localhost:389 -f example.ldif
Then, you should be able to see the updated Directory from your LDAP Browser:

Configuring the Elytron LDAP Realm
Firstly, start WildFly and connect to the Command Line Interface.
The first thing we will need to do is configuring a Directory Context with the URL of the LDAP Server and the information related to the Principal:
/subsystem=elytron/dir-context=exampleDC:add(url="ldap://localhost:389",principal="cn=admin,dc=wildfly,dc=org",credential-reference={clear-text="admin"})
Next, it’s time to create an LDAP Realm which references the Directory Context, specifying the Search Base DN, how and Users are mapped:
/subsystem=elytron/ldap-realm=demoLdapRealm:add(dir-context=exampleDC,identity-mapping={search-base-dn="ou=Users,dc=wildfly,dc=org",rdn-identifier="uid",user-password-mapper={from="userPassword"},attribute-mapping=[{filter-base-dn="ou=Roles,dc=wildfly,dc=org",filter="(&(objectClass=groupOfNames)(member={1}))",from="cn",to="Roles"}]})
Next, you will need creating a Role Decoder which, in its simplest form, takes a single attribute and maps it directly to roles.
/subsystem=elytron/simple-role-decoder=from-roles-attribute:add(attribute=Roles)
Ok, we have the LDAP Realm, the Role Decoder so we will create a Security Domain which uses this information:
/subsystem=elytron/security-domain=ldapSD:add(realms=[{realm=demoLdapRealm,role-decoder=from-roles-attribute}],default-realm=demoLdapRealm,permission-mapper=default-permission-mapper)
As the Security Domain will be used to authenticate users through HTTP, we will need to add an Http Authentication Factory which is configured to use the above defined Security Domain and LDAP Realm:
/subsystem=elytron/http-authentication-factory=example-ldap-http-auth:add(http-server-mechanism-factory=global,security-domain=ldapSD,mechanism-configurations=[{mechanism-name=BASIC,mechanism-realm-configurations=[{realm-name=RealmUsersRoles}]}])
We are finished with Elytron. The last piece of the puzzle will be the Http Authentication Factory into Undertow, so that incoming request will be handled by the Security Domain:
/subsystem=undertow/application-security-domain=httpLdapSD:add(http-authentication-factory=example-ldap-http-auth)
LDAP Configuration updates
The CLI commands should reflect in the following elytron configuration:
<subsystem xmlns="urn:wildfly:elytron:community:18.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
<!-- ....... -->
<security-domains>
<security-domain name="ldapSD" default-realm="demoLdapRealm" permission-mapper="default-permission-mapper">
<realm name="demoLdapRealm" role-decoder="from-roles-attribute"/>
</security-domain>
</security-domains>
<!-- ....... -->
<security-realms>
<ldap-realm name="demoLdapRealm" dir-context="exampleDC">
<identity-mapping rdn-identifier="uid" search-base-dn="ou=Users,dc=wildfly,dc=org">
<attribute-mapping>
<attribute from="cn" to="Roles" filter="(&(objectClass=groupOfNames)(member={1}))" filter-base-dn="ou=Roles,dc=wildfly,dc=org"/>
</attribute-mapping>
<user-password-mapper from="userPassword"/>
</identity-mapping>
</ldap-realm>
</security-realms>
<!-- ....... -->
<http>
<http-authentication-factory name="example-ldap-http-auth" security-domain="ldapSD" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="BASIC">
<mechanism-realm realm-name="RealmUsersRoles"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
</http>
<!-- ....... -->
<dir-contexts>
<dir-context name="exampleDC" url="ldap://localhost:389" principal="cn=admin,dc=wildfly,dc=org">
<credential-reference clear-text="admin"/>
</dir-context>
</dir-contexts>
</subsystem>
Application Configuration
In order to test your application, include the Security bindings in your jboss-web.xml and web.xml.
Here is the jboss-web.xml :
<jboss-web>
<security-domain>httpLdapSD</security-domain>
</jboss-web>
And this is a sample 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>
You should be able to login to your application using the above configuration with the LDAP user id available:
curl http://localhost:8080/demo-security/secure -u "frank:secret123"
Conclusion
This tutorial provided a step-by-step guide to configuring an LDAP realm using WildFly’s Elytron subsystem. By following these steps and customizing the connection details and attribute mapping to match your specific LDAP server configuration, you can establish a secure authentication mechanism for your WildFly applications.