Problem Description:
Upon authentication such an error is encountered:
curl -u USER:APIKEY $ARTIFACTORY_URL/artifactory/api/ping { "errors" : [ { "status" : 500, "message" : "CacheLoader returned null for key org.artifactory.descriptor.security.ldap.LdapSetting@e3223eb9." } ]
Analysis:
As part of the changes implemented in RTFACT-19889, during LDAP user search Artifactory is fetching these user attributes: "pwdAccountLockedTime", "lockoutTime".
(1) If "pwdAccountLockedTime" is null
(2) if the condition below returns false:
if (lockoutTime == null || lockoutTime.size() == 0 || "0".equals(lockoutTime.get(0)))
If both (1) & (2) occur, we trigger a search with "objectClass=domain" in order to get the domain settings to check specifically for the "lockoutDuration" attribute.
Problems in the current flow:
1. In case the search with "objectClass=domain" returns null, we are getting the "CacheLoader returned null for key" error.
2. In case there is a search base configured for the LDAP setting, we are searching for the "objectClass=domain" with the search base. In this case, it will always return null as this has to be searched against the root of the directory (based on my personal test).
3. Not sure if "objectClass=domain" is something that exists on all AD servers.
2020-09-15T09:58:33.963Z [jfrt ] [INFO ] [c53a21d6848ce16c] [o.a.s.l.LdapServiceImpl:148 ] [http-nio-8081-exec-8] - Couldn't find user: 'objectClass=domain' in ldap 2020-09-15T09:58:33.963Z [jfrt ] [ERROR] [c53a21d6848ce16c] [LdapAuthenticationProvider:227] [http-nio-8081-exec-8] - Unexpected exception in LDAP authentication: com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key org.artifactory.descriptor.security.ldap.LdapSetting@329ba7. at com.google.common.cache.LocalCache$Segment.getAndRecordStats(LocalCache.java:2315) at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2279) at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) at com.google.common.cache.LocalCache.get(LocalCache.java:3951) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958) at org.artifactory.security.ldap.LdapServiceImpl.getUserWithAttributesFromDomainWithCustomFiler(LdapServiceImpl.java:170) at org.artifactory.security.ldap.LdapUtils.isActiveDirectoryLockout(LdapUtils.java:188) at org.artifactory.security.ldap.LdapUtils.findSettingsForActiveUser(LdapUtils.java:153) at org.artifactory.security.ldap.ArtifactoryLdapAuthenticationProvider.authenticate(ArtifactoryLdapAuthenticationProvider.java:186) at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175) at org.artifactory.security.RealmAwareAuthenticationManager.authenticate(RealmAwareAuthenticationManager.java:68) at org.artifactory.security.PasswordDecryptingManager.authenticate(PasswordDecryptingManager.java:156) at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:180) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.artifactory.webapp.servlet.authentication.ArtifactoryBasicAuthenticationFilter.doFilter(ArtifactoryBasicAuthenticationFilter.java:103) at org.artifactory.webapp.servlet.authentication.ArtifactoryAuthenticationFilterChain.doFilter(ArtifactoryAuthenticationFilterChain.java:183) at org.artifactory.webapp.servlet.AccessFilter.authenticateAndExecute(AccessFilter.java:312) at org.artifactory.webapp.servlet.AccessFilter.doFilterInternal(AccessFilter.java:177) at org.artifactory.webapp.servlet.AccessFilter.doFilter(AccessFilter.java:127) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.artifactory.webapp.servlet.RequestFilter.doFilter(RequestFilter.java:82) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.artifactory.webapp.servlet.ArtifactoryCsrfFilter.doFilter(ArtifactoryCsrfFilter.java:83) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:164) at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) at org.artifactory.webapp.servlet.SessionFilter.doFilter(SessionFilter.java:68) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.artifactory.webapp.servlet.ArtifactoryTracingFilter.doFilter(ArtifactoryTracingFilter.java:32) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.artifactory.webapp.servlet.ArtifactoryFilter.doFilter(ArtifactoryFilter.java:138) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543) at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:305) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:571) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1626) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:834)