LDAP Debugging Guide

AuthorFullName__c
Patrick Russell
articleNumber
000004524
FirstPublishedDate
2019-08-14T23:20:34Z
lastModifiedDate
2025-05-15

LDAP Debugging Guide

LDAP Debugging Guide

The Lightweight Directory Access Protocol (LDAP) offers a REST API-style method to authenticate users. In Artifactory, this means that every time a user uses their LDAP credentials, the application will check the LDAP server for authentication. This is useful because it allows for dynamic group synchronization. For example, if a user changes LDAP groups, Artifactory will automatically update its group list to reflect that change. More information on LDAP group synchronization and mapping is available HERE.

LDAP Setup Requirements:

All LDAP connections must operate according to specified parameters, whose exact values are usually stored within the LDAP server configuration.

The LDAP URL (e.g., ldap://example.com/dc=jfrog,dc=org) uses the ldap or ldaps protocol (where the "s" stands for "secure" and uses SSL encryption). The dc or Directory Components section maps to an organization's top-level LDAP coordinates. In the example above, this translates as jfrog.org.

The search filter (e.g., samAccountName={0}) or user DN pattern (uid={0},ou=people) is how Artifactory searches for users in the LDAP system. The {0} is filled in with the username submitted. Either the search filter or the user DN pattern can be used, but at least one needs to be configured.

Although LDAP manager credentials (e.g., cn=admin,dc=example,dc=com) are not strictly required, they can be handy as most LDAP servers require authentication to look up directory information. In LDAP, this takes the form of LDAP coordinates, which are mapped to a username and a password.

Troubleshooting LDAP problems

Search base problems: Frequently, when the Artifactory system is being set up for the first time, the search base field is used incorrectly. The search base limits the LDAP directories that Artifactory will use to look for users. If the search base is too broad, the search will take a long time and cause timeouts. If it is too narrow, users with LDAP coordinates outside of the search base will not be able to log in.

The LDAP debug loggers record users’ LDAP coordinates when they log in. You can use this information to fine tune the parameter, accordingly. If there are specific LDAP directories where users are located, you can try to use multiple LDAP settings in Artifactory. These settings can share the same LDAP URL and other information, but have completely different search bases. 

Networking issues: If the LDAP connection test button fails and returns a networking error, this is usually being caused by the LDAP URL. And the ldaps protocol can be particularly tricky. As it uses SSL encryption, the URL in use needs to match the certificate's common name. The LDAP debug loggers will register any additional networking issues or information to the ldap.log file.

Another common issue occurs when networking failures cause a login to time out. This can trigger an intermittent build failure problem. One solution to this problem is to increase login cache times so Artifactory does not check the LDAP server as often.

The cache settings can be updated in the $JFROG_HOME/etc/access/access.config.import.yml file in Artifactory 7.71 and up:

# To change the configuration in an Access service, follow these instructions:
# 1. Find the value you want to update
# 2. Set the value in the access.config.latest.yml file under [$JFROG_HOME]/artifactory/var/etc/access
# 3. Change access.config.latest.yml to access.config.import.yml
# 4. Restart Access
---
security:
  authentication:
    users:
      cache:
        # Number of seconds Access waits before deleting an entry from the cache
        # Suggestion: Set to 3000 to see if the issue is resolved
        expire-after-write-seconds: 300 
        maximum-size: 10000              # maximum number of entries allows in the cache
    groups:
      cache:
        expire-after-write-seconds: 300 # number of seconds Access waits before deleting an entry from the cache
    jfrog-client-login:
      cache:
        expire-after-write-seconds: 300 # number of seconds Access waits before deleting an entry from the cache
        maximum-size: 10000              # maximum number of entries allows in the cache

There are other LDAP settings you can adjust in this file, they are documented on our wiki here.


## Old (7.70 and below) artifactory.system.property value
## Number of seconds for authentications to idle in the cache
artifactory.security.authentication.cache.idleTimeSecs=300


Locked user issues: When an account is locked, there can be two possible states. The first is triggered when a user is attempting to log in and fails to do so, which then causes their LDAP account to be locked. The second occurs when the LDAP manager's account becomes locked.

To run an LDAP search, Artifactory uses the credentials of an LDAP manager. These can sometimes be misconfigured or change, and thereby cause the manager’s account to become locked from the LDAP side. If this happens, the "DEBUG" error will be printed fully when the LDAP debug logger is used, rather than a truncated "ERROR" line. If a manager account lockout has occurred, an LDAP administrator will typically need to be called upon to unlock either the user account or the manager account.

LDAP Debug loggers - 7.71 and Up

In nearly all circumstances, Artifactory’s LDAP debug loggers can help to determine the cause of a problem. This XML snippet goes in the $ARTIFACTORY_HOME/etc/access/logback.xml file and does not require a restart to take effect.

Please keep in mind that with the loggers in place, security information (such as LDAP coordinates, but not passwords) is logged in plaintext. There will also be a slight performance hit while this extra information is being logged. After debugging is complete, you should remove the logger.

This XML snippet should be placed in the logback.xml file near the end, before the "</configuration>" line:
 

<appender name="ldap" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <File>${log.dir}/access-ldap.log</File>
  <rollingPolicy class="org.jfrog.common.logging.logback.rolling.FixedWindowWithDateRollingPolicy">
    <FileNamePattern>${log.dir.archived}/artifactory-ldap.%i.log.gz</FileNamePattern>
    <maxIndex>10</maxIndex>
  </rollingPolicy>
  <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <MaxFileSize>25MB</MaxFileSize>
  </triggeringPolicy>
  <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
    <layout class="org.jfrog.common.logging.logback.layout.BackTracePatternLayout">
      <pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSS, UTC}Z [jfrt ] [%-5p] [%-16X{uber-trace-id}] [%-30.30(%c{3}:%L)] [%-20.20thread] - %m%n</pattern>
    </layout>
  </encoder>
</appender>

<logger name="org.jfrog.access.server.security" additivity="false">
  <level value="trace"/>
  <appender-ref ref="ldap"/>
</logger>
<logger name="org.jfrog.access.server.service.auth.ldap" additivity="false">
  <level value="trace"/>
  <appender-ref ref="ldap"/>
</logger>
<logger name="org.springframework.ldap" additivity="false">
  <level value="trace"/>
  <appender-ref ref="ldap"/>
</logger>
<logger name="org.springframework.security.ldap" additivity="false">
  <level value="trace"/>
  <appender-ref ref="ldap"/>
</logger>



When applied, an "access-ldap.log" file will appear in the $ARTIFACTORY_HOME/log/ folder. 

LDAP Debug loggers - 7.70 and Below

These debug loggers go in the $JFROG_HOME/etc/artifactory/logback.xml file, to create an "artifactory-ldap.log" debug log. In these lower versions, the Artifactory microservice handled the LDAP integration.
 

 <appender name="ldap" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <File>${log.dir}/artifactory-ldap.log</File>
    <rollingPolicy class="org.jfrog.common.logging.logback.rolling.FixedWindowWithDateRollingPolicy">
      <FileNamePattern>${log.dir.archived}/artifactory-ldap.%i.log.gz</FileNamePattern>
      <maxIndex>10</maxIndex>
    </rollingPolicy>
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
      <MaxFileSize>25MB</MaxFileSize>
    </triggeringPolicy>
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
      <layout class="org.jfrog.common.logging.logback.layout.BackTracePatternLayout">
        <pattern>%date{yyyy-MM-dd'T'HH:mm:ss.SSS, UTC}Z [jfrt ] [%-5p] [%-16X{uber-trace-id}] [%-30.30(%c{3}:%L)] [%-20.20thread] - %m%n</pattern>
      </layout>
    </encoder>
  </appender>
  <logger name="org.springframework.security.ldap" additivity="false">
    <level value="trace"/>
    <appender-ref ref="ldap"/>
  </logger>
  <logger name="org.artifactory.addon.ldap" additivity="false">
    <level value="trace"/>
    <appender-ref ref="ldap"/>
  </logger>
  <logger name="org.artifactory.security.ldap" additivity="false">
    <level value="trace"/>
    <appender-ref ref="ldap"/>
  </logger>
  <logger name="org.artifactory.webapp.servlet.AccessFilter" additivity="false">
    <level value="trace"/>
    <appender-ref ref="ldap"/>
  </logger>