dependency-track icon indicating copy to clipboard operation
dependency-track copied to clipboard

OIDC configuration not available when connecting behind corporate proxy with authentication

Open RenoV8-tls opened this issue 2 months ago • 4 comments

Current Behavior

I am trying to deploy Dependency-Track behind a corporate proxy that requires authentication. Dependency-Track is able to download CVE data from https://nvd.nist.gov/ successfully through the proxy, using the ALPINE_HTTP_PROXY_<ADDRESS | PORT | USERNAME | PASSWORD> environment variables.

However, when it tries to fetch the OIDC configuration, I encounter a 407 Proxy Authentication Required error.

I found a similar issue (https://github.com/DependencyTrack/dependency-track/issues/1940) but it doesn't specifically mention proxy authentication.

------- Downloading from https://nvd.nist.gov using proxy authentication is OK ------- 

2025-09-30 08:41:46,591 INFO [NistMirrorTask] Starting NIST mirroring task
2025-09-30 08:41:46,592 INFO [NistMirrorTask] Mirrored data directory created successfully
2025-09-30 08:41:46,599 INFO [NistMirrorTask] Downloading files at Tue Sep 30 08:41:46 UTC 2025
2025-09-30 08:41:46,601 INFO [NistMirrorTask] Initiating download of https://nvd.nist.gov/feeds/json/cve/2.0/nvdcve-2.0-2025.json.gz
2025-09-30 08:41:47,379 INFO [NistMirrorTask] Downloading...
2025-09-30 08:41:47,962 INFO [NistMirrorTask] Uncompressing nvdcve-2.0-2025.json.gz
2025-09-30 08:41:48,320 INFO [NvdParser] Parsing nvdcve-2.0-2025.json

------- Unable to fetch OIDC - Error 407 "Proxy Authentication Required" ------- 

2025-09-30 08:42:39,317 ERROR [OidcConfigurationResolver] Failed to fetch OIDC configuration from issuer https://oidc-config.com [requestId=xxxxx, requestMethod=GET, requestUri=/v1/oidc/available]
java.io.IOException: Couldn't download OpenID Provider metadata from https://oidc-config.com/.well-known/openid-configuration: 
**Status code 407**
        at alpine.server.auth.OidcConfigurationResolver.resolve(OidcConfigurationResolver.java:100)
        at alpine.server.util.OidcUtil.isOidcAvailable(OidcUtil.java:44)
        at org.dependencytrack.resources.v1.OidcResource.isAvailable(OidcResource.java:85)
        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.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)

Then when i get "https://my-dtrack-url.com/api/v1/oidc/available" endpoint :

Image

I have checked on alpine repository in url bellow, it seems that the OidcConfigurationResolver is getting the proxy configuration with credentials to send the http request :

https://github.com/stevespringett/Alpine/blob/master/alpine-server/src/main/java/alpine/server/auth/OidcConfigurationResolver.java

https://github.com/stevespringett/Alpine/blob/master/alpine-common/src/main/java/alpine/common/util/ProxyUtil.java https://github.com/stevespringett/Alpine/blob/master/alpine-common/src/main/java/alpine/common/util/ProxyConfig.java

But still dont understand the 407. Do you have any idea if the proxy is really passing credentials to proxy to fetch OIDC ?

Steps to Reproduce

  • Set as environment variables
    • Proxy properties : ALPINE_HTTP_PROXY_<ADDRESS | PORT | USERNAME | PASSWORD>
    • OIDC properties dtrack-api : ALPINE_OIDC_ENABLED | ALPINE_OIDC_CLIENT_ID | ALPINE_OIDC_ISSUER | ALPINE_OIDC_USERNAME_CLAIM | ALPINE_OIDC_TEAMS_CLAIM | ALPINE_OIDC_USER_PROVISIONING | ALPINE_OIDC_TEAM_SYNCHRONIZATION
    • OIDC properties dtrack-frontend : OIDC_ISSUER | OIDC_CLIENT_ID
  • Enable basic authentication scheme in /opt/java/openjdk/conf/net.properties (which is disabled by default)
jdk.http.auth.tunneling.disabledSchemes=Basic

To :

jdk.http.auth.tunneling.disabledSchemes=
  • Comment the nltm properties
  • Try to use an external OIDC provider when inside a corporate environment that needs a proxy with authentication to fetch oidc-configuration

Expected Behavior

Authenticated proxy is supported to reach the OIDC provider

Dependency-Track Version

4.13.5

Dependency-Track Distribution

Container Image

Database Server

PostgreSQL

Database Server Version

15

Browser

Microsoft Edge

Checklist

RenoV8-tls avatar Sep 30 '25 10:09 RenoV8-tls

Hello, No one have an idea if i am making something wrong or if it's truly a defect ? @nscuro @stevespringett

RenoV8-tls avatar Oct 24 '25 06:10 RenoV8-tls

What happens when you set the http_proxy and / or https_proxy env vars to http://username:[email protected] instead?

From what I can see your config looks fine, although I don't think modifying any JDK configs should be necessary. FWIW, we have a test that verifies that the proxy is picked up from environment variables:

https://github.com/stevespringett/Alpine/blob/0a52714eccf8ba31867bf10ea3f7586e781d0143/alpine-server/src/test/java/alpine/server/auth/OidcConfigurationResolverTest.java#L114-L128

nscuro avatar Oct 24 '25 08:10 nscuro

Hello @nscuro, sorry for the delay,

I have set the environment variables : http_proxy / https_proxy / HTTP_PROXY / HTTPS_PROXY
with my proxy values : http://username:[email protected]:<port_number>

2025-11-20 09:52:09,361 INFO [NistMirrorTask] Initiating download 
of https://nvd.nist.gov/feeds/json/cve/2.0/nvdcve-2.0-2025.json.gz
2025-11-20 09:52:10,186 INFO [NistMirrorTask] Downloading...
2025-11-20 09:52:11,052 INFO [NistMirrorTask] Uncompressing nvdcve-2.0-2025.json.gz
2025-11-20 09:52:11,760 INFO [NvdParser] Parsing nvdcve-2.0-2025.json

2025-11-20 09:52:18,416 ERROR [OidcConfigurationResolver] Failed to fetch OIDC configuration 
from issuer https://oidc-config.com [requestId=xxx, requestMethod=GET, requestUri=/v1/oidc/available]
java.io.IOException: Couldn't download OpenID Provider metadata 
from https://oidc-config.com/.well-known/openid-configuration: **Status code 407**
 at alpine.server.auth.OidcConfigurationResolver.resolve(OidcConfigurationResolver.java:100)
        at alpine.server.util.OidcUtil.isOidcAvailable(OidcUtil.java:44)
        at org.dependencytrack.resources.v1.OidcResource.isAvailable(OidcResource.java:85)
        ...

As you can see it still works for downloading packages but not fetching OIDC configuration

RenoV8-tls avatar Nov 20 '25 10:11 RenoV8-tls

Hello, Is there other things that explains why the OIDC, isn't passing credentials to the request ?

Because the only thing it was normally able to get was http://username:[email protected]/:<port_number> wich includes credentials .

RenoV8-tls avatar Nov 28 '25 10:11 RenoV8-tls