DependencyTrack / dependency-track

Dependency-Track is an intelligent Component Analysis platform that allows organizations to identify and reduce risk in the software supply chain.
https://dependencytrack.org/
Apache License 2.0
2.7k stars 578 forks source link

Apiserver gives 500 error with PingFederate/Google OpenID #3453

Closed mikesindieiev closed 8 months ago

mikesindieiev commented 9 months ago

Current Behavior

I am trying to tune up an OpenID SSO with Ping Pederate but apiserver gives me 500 HTTP error with the following entry in the logs:

2024-02-08 11:23:40,070 ERROR [GlobalExceptionHandler] Uncaught internal server error
java.lang.IllegalArgumentException: The value must not be null or empty string                                                                                                                                          at com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:94)
    at com.nimbusds.oauth2.sdk.id.ClientID.<init>(ClientID.java:54)                                                                                                                                                     at alpine.server.auth.OidcIdTokenAuthenticator.authenticate(OidcIdTokenAuthenticator.java:72)
    at alpine.server.auth.OidcAuthenticationService.authenticate(OidcAuthenticationService.java:139)                                                                                                                    at org.dependencytrack.resources.v1.UserResource.validateOidcAccessToken(UserResource.java:141)
    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:256)                                                                                                                                          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:265)                                                                                                                             at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)                                                                                                                               at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)                                                                                                                                         at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)                                                                                                                                 at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
    at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1419)                                                                                                                                at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)                                                                                                                             at alpine.server.filters.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:225)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)                                                                                                                                           at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at alpine.server.filters.ClickjackingFilter.doFilter(ClickjackingFilter.java:93)                                                                                                                                    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)                                                                                                                                at alpine.server.filters.WhitelistUrlFilter.doFilter(WhitelistUrlFilter.java:166)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)                                                                                                                                           at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)                                                                                                                                       at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)                                                                                                                                      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)                                                                                                                                at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)                                                                                                                                at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)                                                                                                                                 
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)                                                                                                                                 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)                                                                                                                                    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
    at org.eclipse.jetty.server.Server.handle(Server.java:563)                                                                                                                                                          at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)                                                                                                                                              at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)                                                                                                                                      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)                                                                                                                                                at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)                                                                                                     at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)                                                                                                  at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)                                                                                                         at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)                                                                                                                       at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
    at java.base/java.lang.Thread.run(Unknown Source)

On the frontend everything seems fine:

[08/Feb/2024:11:23:40 +0000] "GET /static/oidc-callback.html?code=YtQtKg2Z6MIcOXLqPOcZLrHcpD3PIX3PsnMAAAwh&state=74b4f66f9a5343c59eb27d3039953c5c HTTP/1.1" 200 2296 "https://<mydd_url.example>/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36" "192.168.0.247"

I am running a vanilla helm chart chart in EKS 1.29 Here is my values.yaml:

frontend:
  replicaCount: 1
  image:
    tag: 4.10.0
  env:
  - name: API_BASE_URL
    value: "https://<mydd_url.example>"
  - name: OIDC_CLIENT_ID
    value: "MyClientID"
  - name: OIDC_ISSUER
    value: "https://<pingfederate.sso.endpoint>"
  - name: OIDC_SCOPE
    value: "openid profile email"
  - name: OIDC_LOGIN_BUTTON_TEXT
    value: "Login with SSO"

apiserver:
  image:
    tag: 4.10.1
  env:
  - name: ALPINE_OIDC_ENABLED
    value: "true"
  - name: ALPINE_OIDC_CLIENT_ID
    value: "MyClientID"
  - name: ALPINE_OIDC_ISSUER
    value: "https://<pingfederate.sso.endpoint>"
  - name: ALPINE_OIDC_USERNAME_CLAIM
    value: "email"
  - name: ALPINE_OIDC_USER_PROVISIONING
    value: "true"
  - name: ALPINE_CORS_ENABLED
    value: "false"

ingress:
  enabled: true
  annotations:
    alb.ingress.kubernetes.io/load-balancer-name: dependency-track-alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/certificate-arn: |
      arn:aws:acm:us-east-1:AWS_ACCOUNT:certificate/CERT_ID
    alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06
    alb.ingress.kubernetes.io/ssl-redirect: '443'

  ingressClassName: alb
  host: <mydd_url.example>

postgresql:
  enabled: true

In the Web Console the error 500 occurs during the post method on https://<mydd_url.example>/api/v1/user/oidc/login: image

But the Payload is correct and has the JWT tokens: image

Here is what I have from decoded accessToken in Payload section:

{
  "scope": "openid profile email",
  "client_id": "MyClientID",
  "User id": "myUserID",
  "firstname": "myName",
  "email": "myemail@corp.com",
  "group": [
    "myGroup1",
    "myGroup2",
    "myGroup3"
  ],
  "lastname": "myLastName",
  "exp": 1707398940
}

And here is what I have from decoded idToken in Payload section:

{
  "sub": "myUserID",
  "aud": "MyClientID",
  "jti": "osVmnPX1UpQSVjSlGdMDSq",
  "iss": "https://<pingfederate.sso.endpoint>",
  "iat": 1707391739,
  "exp": 1707392039,
  "acr": "urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient",
  "auth_time": 1707391417,
  "firstname": "myName",
  "email": "myemail@corp.com",
  "group": [
    "myGroup1",
    "myGroup2",
    "myGroup3"
  ],
  "lastname": "myLastName"
}

In addition to above, I have tried enabling/disabling groups provisioning but it seem like it does not affect the flow at this stage

What could cause that error, which field Dependency-Track tries to parse and how to make SSO work?

Steps to Reproduce

  1. Deploy vanilla Dependency-Track helm chart and connect it to Ping Federate OpenID SSO

Expected Behavior

OpenID SSO works

Dependency-Track Version

4.10.1

Dependency-Track Distribution

Container Image

Database Server

PostgreSQL

Database Server Version

11.13

Browser

Google Chrome

Checklist

mikesindieiev commented 9 months ago

Tried to tune OpenID with Google and got the same result

2024-02-09 12:22:17,768 [] ERROR [alpine.server.resources.GlobalExceptionHandler] Uncaught internal server error
java.lang.IllegalArgumentException: The value must not be null or empty string
    at com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:94)
    at com.nimbusds.oauth2.sdk.id.ClientID.<init>(ClientID.java:54)
    at alpine.server.auth.OidcIdTokenAuthenticator.authenticate(OidcIdTokenAuthenticator.java:72)
    at alpine.server.auth.OidcAuthenticationService.authenticate(OidcAuthenticationService.java:139)
    at org.dependencytrack.resources.v1.UserResource.validateOidcAccessToken(UserResource.java:141)
    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:256)
    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:265)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
    at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
    at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1419)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
    at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
    at alpine.server.filters.ContentSecurityPolicyFilter.doFilter(ContentSecurityPolicyFilter.java:225)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at alpine.server.filters.ClickjackingFilter.doFilter(ClickjackingFilter.java:93)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at alpine.server.filters.WhitelistUrlFilter.doFilter(WhitelistUrlFilter.java:166)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:598)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1570)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1543)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
    at org.eclipse.jetty.server.Server.handle(Server.java:563)
    at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
    at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
    at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
    at java.base/java.lang.Thread.run(Unknown Source)
github-actions[bot] commented 7 months ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.