DependencyTrack / DependencyTrack/dependency-track

Users search filter do not work correctly

Open
#5,266 3 comments 0 reactions 0 assignees View on GitHub
defect in triage
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.