DependencyTrack / DependencyTrack/dependency-track
Users search filter do not work correctly
- Dominant language
- Java
- Stars
- 4.2k
- Forks
- 811
- Avg merge
- 8h 39m
- Merged PRs (30d)
- 237
Description
### Current Behavior
Hello,
I was trying to configure user login via FreeIPA LDAP, and here are the settings I applied:
```
ALPINE_LDAP_SECURITY_AUTH: "simple"
ALPINE_LDAP_BIND_USERNAME: "uid=dtrack,cn=users,cn=accounts,dc=example,dc=com"
ALPINE_LDAP_BIND_PASSWORD: "password"
ALPINE_LDAP_BASEDN: "dc=example,dc=com"
ALPINE_LDAP_AUTH_USERNAME_FORMAT: "%s"
ALPINE_LDAP_USERS_SEARCH_FILTER: "(&(objectClass=inetOrgPerson)(objectClass=person)(uid={USERNAME}))"
LOGGING_LEVEL: "DEBUG"
ALPINE_LDAP_ATTRIBUTE_NAME: "uid"
ALPINE_LDAP_ATTRIBUTE_MAIL: "mail"
ALPINE_LDAP_GROUPS_FILTER: "(&(objectClass=posixGroup)(cn=*))"
ALPINE_LDAP_USER_GROUPS_FILTER: "(&(objectClass=posixGroup)(memberUid={USERNAME}))"
ALPINE_LDAP_GROUPS_SEARCH_FILTER: "(&(objectClass=posixGroup)(cn=*{SEARCH_TERM}*))"
```
With this configuration, LDAP groups are detected correctly, but users are not. The Java application throws an error
`DEBUG [LdapAuthenticationService] Attempting to authenticate user: user [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] 2025-09-01 13:00:14,900 DEBUG [LdapAuthenticationService] Validating credentials for: user [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] 2025-09-01 13:00:14,904 DEBUG [LdapConnectionWrapper] Creating directory service context (DirContext) [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] 2025-09-01 13:00:15,043 DEBUG [LdapConnectionWrapper] Performing a directory search for: user [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] 2025-09-01 13:00:15,043 DEBUG [LdapConnectionWrapper] Searching for: uid=user [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] 2025-09-01 13:00:15,051 DEBUG [LdapAuthenticationService] An error occurred while attempting to validate credentials [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login] javax.naming.NamingException: Multiple entries in the directory contain the same username. This scenario is not supported at alpine.server.auth.LdapConnectionWrapper.searchForSingleUsername(LdapConnectionWrapper.java:266) at alpine.server.auth.LdapAuthenticationService.validateCredentials(LdapAuthenticationService.java:160) at alpine.server.auth.LdapAuthenticationService.authenticate(LdapAuthenticationService.java:81) at alpine.server.auth.Authenticator.authenticate(Authenticator.java:80) at org.dependencytrack.resources.v1.UserResource.validateCredentials(UserResource.java:109) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81) at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:274) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:253) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:696) at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:397) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:349) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:312) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) at org.eclipse.jetty.ee10.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1379) at org.eclipse.jetty.ee10.servlet.ServletHolder.handle(ServletHolder.java:736) at org.eclipse.jetty.ee10.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1621) at alpine.server.filters.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:225) at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205) at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1593) at alpine.server.filters.ClickjackingFilter.doFilter(ClickjackingFilter.java:93) at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:205) at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1593) at alpine.server.filters.WhitelistUrlFilter.doFilter(WhitelistUrlFilter.java:166) at org.eclipse.jetty.ee10.servlet.FilterHolder.doFilter(FilterHolder.java:208) at org.eclipse.jetty.ee10.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1593) at org.eclipse.jetty.ee10.servlet.ServletHandler$MappedServlet.handle(ServletHandler.java:1554) at org.eclipse.jetty.ee10.servlet.ServletChannel.dispatch(ServletChannel.java:819) at org.eclipse.jetty.ee10.servlet.ServletChannel.handle(ServletChannel.java:436) at org.eclipse.jetty.ee10.servlet.ServletHandler.handle(ServletHandler.java:469) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:575) at org.eclipse.jetty.ee10.servlet.SessionHandler.handle(SessionHandler.java:717) at org.eclipse.jetty.server.handler.ContextHandler.handle(ContextHandler.java:1064) at org.eclipse.jetty.server.Server.handle(Server.java:182) at org.eclipse.jetty.server.internal.HttpChannelState$HandlerInvoker.run(HttpChannelState.java:662) at org.eclipse.jetty.server.internal.HttpConnection.onFillable(HttpConnection.java:416) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:99) at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:480) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:443) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293) at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:195) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:979) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1209) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1164) at java.base/java.lang.Thread.run(Unknown Source) 2025-09-01 13:00:15,053 INFO [UserResource] Unauthorized login attempt / invalid credentials / username: user / IP Address: 172.25.12.16 / User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 [requestId=8dcc58a9-a9dd-4a40-acdc-a96b6d919631, requestMethod=POST, requestUri=/v1/user/login]`
because it finds two entries in FreeIPA, even though I have limited the search using filters. It seems that the user filters do not work correctly.
If I perform a search using ldapsearch:
```
ldapsearch -x \
-H ldap://ipa.example.com:389 \
-D "uid=user,cn=users,cn=accounts,dc=example,dc=com" \
-W \
-b "dc=example,dc=com" \
"(&(objectClass=inetOrgPerson)(objectClass=person)(uid=user))"
```
then only one entry is returned.
It seems that the application does not correctly handle the case where multiple entries exist in different OUs, even if they do not match the user filter.
### Steps to Reproduce
1. Deploy FreeIPA.
2. Perform an ldapsearch on FreeIPA.
3. Configure Dependency-Track for user login via FreeIPA as in my example and verify that, according to the filter, the search returns a single user, while Java does not filter according to the query.
### Expected Behavior
The ALPINE_LDAP_USERS_SEARCH_FILTER should work correctly according to the query.
### Dependency-Track Version
4.13.4
### Dependency-Track Distribution
Container Image
### Database Server
PostgreSQL
### Database Server Version
16.10
### Browser
Mozilla Firefox
### Checklist
- [x] I have read and understand the [contributing guidelines](https://github.com/DependencyTrack/dependency-track/blob/master/CONTRIBUTING.md#filing-issues)
- [x] I have checked the [existing issues](https://github.com/DependencyTrack/dependency-track/issues) for whether this defect was already reported
Contributor guide
Assessment
This issue has not been assessed yet.