How does LDAP/AD group sync/mapping work?

Overview

Here are the steps and explanation (via links) on how a LDAP (or Active Directory) user gets mapped to a Artifactory LDAP group.

  1. Setup LDAP filter (or Active Directory)
  2. Setup and Import LDAP Groups
  3. Create permission rules to the LDAP Groups (also refer to Best Practice for setting Permission Target - requires Support Portal login)
  4. Login to Artifactory using a LDAP user.  

Here is a video on how the LDAP group mapping is done (showing on 3.x version, but the concept is the same):https://www.youtube.com/watch?v=IdZz0R6laxA

 

How does it work?

Once a ldap group is mapped to Artifactory, Artifactory examines each ldap group to see if a user belongs to the group or not by contacting LDAP server. Once Artifactory finds that the user belongs to the group, then it lets the user to have the permissions that have been given to the group by an Artifactory administrator. 

 

What's the advantage of using LDAP Group?

The Artifactory administrator does not have to manage permissions for each user. Instead, the Artifactory administrator needs only to manage the permissions given to each ldap group, while maintaining LDAP group at the LDAP server.

 

Where does it search (how the Search Base is used)?

LDAP Group settings make the LDAP queries relative to the "LDAP Setting" that is selected. Thus, the Search Base at the LDAP Group Settings page should be set relative to LDAP URL plus Search Base of LDAP Settings pageFor example, if LDAP Settings has LDAP URL as ldap://abc and Search Base as ou=users, then LDAP Group's searches will be made relative to ldap://abc/ou=users . 

 

If you add Search base at the LDAP Group Setting, then the search will be made relative to the combination of the search bases set at LDAP Setting and the LDAP Group Setting. For example, if LDAP Group has ou=groups as a Search Filter and LDAP has ou=users as a Search Filter then Artifactory will search for groups under ou=groups,ou=users

 

Example of using Static Mapping Strategy

The following example shows that the group has two members, kwinters and trigden, as the group's uniqueMember attribute. Once this group is imported, any users who are part of this group's uniqueMember attribute, and meets conditions set at the LDAP setting will automatically join the group. If the group is given any permissions to it, then the users will automatically inherit the permissions. Since this is Static mapping, "PD Managers" group is aware of its members; however, the users are not aware of the groups they belong to.

 

 

 

 

Example of using Dynamic Mapping Strategy

The following example shows that the member has one group, Domain Guests, as one of the user's ldap attributes. Once this group is imported, anyone users who have the an LDAP attribute as "memberOf" Domain Guests, and meets conditions set at the LDAP setting will automatically join the group. If the group is given any permissions to it, then the users will automatically inherit the permissions. Since this is Dynamic mapping, the user, joshua, is aware of what groups it belongs to, but the group object, Domain Guest, is not aware of their members (;although, Windows have cross-reference at the group also by using 'member' attribute, it is not required).

 

 

Example of assigning permission targets to imported LDAP groups

After the groups have been imported, you can go to Admin => Security => Groups to confirm that those ldap groups show up there. Since it is not Artifactory's internal groups, it will have "External" checked. As you can see in the screenshot below, it does not have any permission targets associated with it yet.

 

 

Now, let's create Read permission to domain guests and Read, Annotate, Cache permissions to pd managers at Admin => Security => Permissions. After selecting repositories, go to Groups and assign permissions as you wanted. 

Example of verifying the permission targets

After saving it. You can login using a ldap user who belongs to pd managers ldap group, and the user will be able to cache any remote repositories as well as reading from any remote and local that the permission target was associated with. For another ldap user who only belongs to the domain guests group, it will not be able to cache any artifacts that have not been cached by others, but the user can still download any artifacts that have already been cached or exist in a local repository if the repository belongs to the permission target's repository list.

 

Once the user logs into Artifactory, an Artifactory administrator can verify the user's groups and permissions at Admin => Security => Users => find the user ID

 

Additional Q & A

Q: Does LDAP group's "Import" button sync members of a ldap group?

A: No, it just maps the group to Artifactory. Members of the group can only be added if you have "Auto Create Artifactory Users" enabled at LDAP Setting AND the user logs into Artifactory at least once. Also, Artifactory never saves the ldap user's password.

 

Q: Which mapping strategy should I choose?

A: It depends on how your LDAP is structured. For example, you may find Static method giving you a faster login experience if the ldap query returns smaller results by using it. The end goal is to find the most efficient search. Please consult your LDAP administrator for advise.

 

TROUBLESHOOTING TIPS

  • See LDAP attributes found for the user (e.g. run "ldapsearch joshua") and compare it with the group filter
  • In Artifactory, go to Admin => Security => LDAP Settings => Select and Edit your LDAP setting => Enter a test username and password => Click on Test Connection 
  • Enable more logs by adding the below debug loggers at the end of the $ARTIFACTORY_HOME/etc/logback.xml file. Enabling the debug logs does not require restarting Artifactory.
    <logger name="org.springframework">
    <level value="debug"/>
    </logger>
    <logger name="org.artifactory.addon.ldap">
    <level value="trace"/>
    </logger>
    <logger name="org.artifactory.security.ldap">
    <level value="trace"/>
    </logger>
    <logger name="org.artifactory.webapp.servlet.AccessFilter">
    <level value="trace"/>

    </logger>