Wildfly – Elytron – LDAP SecurityDomains for Active Directory

In one of my last blog posts I explained how to setup a Security Domain in Wildfy Elytron – the new security module. In this blog post I explain how to setup a LDAP security domain for the Active Directory:

The ldap-realm

As explained in my last blog you have to define a security-domain and a security-realm in two separate sections. The following example shows the LDAP configuration to resolve users and roles form an Active Directory. I have reduced the non relevant parts:

       <subsystem xmlns="urn:wildfly:elytron:14.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
            .....
            <security-domains>
                .....                
              	<!-- My LDAP domain   -->
		<security-domain name="mydomain" default-realm="cached-ldap" permission-mapper="default-permission-mapper">
		   <realm name="cached-ldap"/>
		</security-domain>				                
            </security-domains>
            <security-realms>
                .....                
                <!-- my LDAP realm -->
		<ldap-realm name="ldap-realm" dir-context="ldap-connection" direct-verification="true">
			<identity-mapping rdn-identifier="sAMAccountName" use-recursive-search="false" search-base-dn="CN=users,DC=intern,DC=foo,DC=de" >
			  <attribute-mapping>
			   <attribute from="CN" to="Roles" filter="(member={1})" filter-base-dn="CN=users,DC=intern,DC=foo,DC=de"/>
			  </attribute-mapping>
			</identity-mapping>
		</ldap-realm>
		<caching-realm  name="cached-ldap" realm="ldap-realm"/>			    
            </security-realms>
            
            <!-- LDAP Dir Contexts -->
            <dir-contexts>
		<dir-context name="ldap-connection" url="ldap://my-ldap:389" principal="CN=bind_user,CN=users,DC=intern,DC=foo,DC=de">
		     <credential-reference clear-text="YOUR-PASSWORD"/>
		</dir-context>
    	    </dir-contexts>
.....
       

You have to tweak the dir-context and the base-dn in the example above to your LDAP settings. The setup searches for the sAMAccountName as the UserID and searches the roles in the ‘members’ attribute of the user entry.

The cached-ldap

The important part is the ‘cached-ldap‘ security realm. In older versions of Wildfly the ldap realm uses a cache per default. In the new version you need to define a cache by yourself. This is what the cached-ldap is good for. Your security domain points to the cached-ldap and the cached-ldap points to the ldap realm. If you don’t use this, you will see a lot of ldap requests against your directory.

You can also add attributes to setup the default caching like:

<caching-realm name="cached-ldap" realm="ldap-realm" maximum-age="300000" />

Find details here.

Logging

For debugging it is helpful if you change the loglevel for org.wildfly.security. For this you simply add the following logger into the subsystem logging:

        <logger category="org.wildfly.security">
	    <level name="DEBUG"/>
	</logger>

And also set the log level from “INFO” to “DEBUG” for your console handler. This setting will give you more insights of what is happening in the background.

From a server bash you can ‘tail’ the security messages like this:

$ tail -f /opt/jboss/wildfly/standalone/log/server.log  | grep "security"

Role Mapping

In some cases it maybe necessary to map LDAP Group names to specific role names within your application. There for you can use the mappers. See the following example which maps the LDAP Group name ‘imixs_users’ to the application role ‘org.imixs.ACCESSLEVEL.AUTHORACCESS’:

            <security-domains>
               ....
		<security-domain name="imixsrealm" default-realm="cached-ldap" permission-mapper="default-permission-mapper">
		 <realm name="cached-ldap" role-mapper="imixs-user-rolemapper" />
		</security-domain>	                
            </security-domains>
.....
            <mappers>
                .....              
                <regex-role-mapper name="imixs-user-rolemapper" pattern="imixs_user" replacement="org.imixs.ACCESSLEVEL.AUTHORACCESS" keep-non-mapped="true"/>
            </mappers>
....

The mapper is referred in the security-domain. I am using a regex role mapper to replace the role name. You will find more background about this role mapping here.

7 Replies to “Wildfly – Elytron – LDAP SecurityDomains for Active Directory”

  1. Hi
    Thanks for this great blog, it helped me a lot to get started.
    I realized that authorization to ldap happend really often, so TOTP as used by freeIPA: pass+token
    is not possible, due “token reusage watermark”
    Have you ever seen a possibility which uses the ldap-bind only once for username?
    Have a good time

  2. Hi Ralph,
    Thanks for this. The ldap cache is a great tip. I just have a doubt. On dir-context you are providing credentials to connect to ldap, but on ldap-realm you are enabling direct-verification=”true”. Is this right? Isn’t direct-verification suppose to use the user (who is trying to log in) credentials to connect to ldap? If not, what’s the purpose of direct-verification? Thank you.

  3. Yes, you might be right here. I’ve never tried it myself. But isn’t it always the case that the user confirms his credential by attempting to log in?

  4. Ralph, after checking the code, elytron needs another user credentials (specified on dir-context) to search the user who’s trying to login on ldap. I was expecting, with direct-verification=true, that all connections to ldap use the supplied user credentials (who is trying to login). This way, i avoid having another user/password on the configuration file.

  5. Hi , Thanks a lot.. you saved my day ….. was having issues with role mappings and scratching my head for a day….

  6. Hi Ralph thanks for this very usefull article.
    But when i change the user password on the ldap server, the cache already created in elytron doesn’t get refreshed and so i cannot login with the new password.
    How is it possibile to solve thsi problem ?

    thanks

Leave a Reply to Daniel Novo Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.