With OpenID Connect + LDAP, "Each issuer can only be specified once" error is seen in TIBCO Spotfire Server

With OpenID Connect + LDAP, "Each issuer can only be specified once" error is seen in TIBCO Spotfire Server

book

Article ID: KB0072290

calendar_today

Updated On:

Products Versions
Spotfire Server All Versions

Description

You may notice the following error in server.log when two providers with same discovery document URL is configured in Spotfire OIDC configuration. 

The reason why we wouldn't allow such configuration is because same user will be able to log in using both configurations (and end up in different domains depending on which they choose)

ERROR 2022-05-13T09:46:51,363-0400 [*Initialization*] web.context.ContextLoader: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauth2ClientManager' defined in class path resource [applicationContext.xml]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.spotfire.server.security.auth.oidc.OAuth2ClientManager]: Constructor threw exception; nested exception is com.spotfire.server.security.auth.oidc.OidcException: Each issuer can only be specified once, duplicate: https://login.microsoftonline.com/a5c5a766-129a-47bb-924c-43805e856501/v2.0
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans.jar:5.3.14]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context.jar:5.3.14]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context.jar:5.3.14]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) ~[spring-web.jar:5.3.14]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) ~[spring-web.jar:5.3.14]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) ~[spring-web.jar:5.3.14]
    at com.spotfire.server.lifecycle.SpotfireServerInitializer.contextInitialized(SpotfireServerInitializer.java:58) ~[spotfire-server.jar:?]
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4766) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5230) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:698) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:696) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:690) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1889) ~[catalina.jar:9.0.56]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[?:?]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-util.jar:9.0.56]
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) ~[?:?]
    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:583) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:473) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1618) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:319) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:946) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[catalina.jar:9.0.56]
    at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-util.jar:9.0.56]
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[?:?]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.56]
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927) ~[catalina.jar:9.0.56]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[catalina.jar:9.0.56]
    at org.apache.catalina.startup.Catalina.start(Catalina.java:772) ~[catalina.jar:9.0.56]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) ~[bootstrap.jar:9.0.56]
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) ~[bootstrap.jar:9.0.56]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.spotfire.server.security.auth.oidc.OAuth2ClientManager]: Constructor threw exception; nested exception is com.spotfire.server.security.auth.oidc.OidcException: Each issuer can only be specified once, duplicate: https://login.microsoftonline.com/a5c5a766-129a-47bb-924c-43805e856501/v2.0
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) ~[spring-beans.jar:5.3.14]
    ... 57 more
Caused by: com.spotfire.server.security.auth.oidc.OidcException: Each issuer can only be specified once, duplicate: https://login.microsoftonline.com/a5c5a766-129a-47bb-924c-43805e856501/v2.0
    at com.spotfire.server.security.auth.oidc.OAuth2ClientManager.createProvider(OAuth2ClientManager.java:507) ~[spotfire-server.jar:?]
    at com.spotfire.server.security.auth.oidc.OAuth2ClientManager.createProviders(OAuth2ClientManager.java:384) ~[spotfire-server.jar:?]
    at com.spotfire.server.security.auth.oidc.OAuth2ClientManager.<init>(OAuth2ClientManager.java:121) ~[spotfire-server.jar:?]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[?:?]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans.jar:5.3.14]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) ~[spring-beans.jar:5.3.14]
    ... 57 more
INFO 2022-05-13T09:46:51,378-0400 [*Shutdown*] spotfire.logging.LoggerContextListener: Shutting down the LogManager

Issue/Introduction

This article provides you an explanation as to why you cannot use same discovery document url more than once and how to handle different set of users.

Resolution

The best possible solution would be using a dynamic domain value (either by parsing the username claim or by using a dedicated domain claim). Something like below helps:
<provider>
          <name>Azure OpenID</name>
          <enabled>true</enabled>
          <discovery-url>https://login.microsoftonline.com-id/v2.0/.well-known/openid-configuration</discovery-url>
          <client-id>8888-8888-888888-8888888</client-id>
          <client-secret>REDACTED</client-secret>
          <domain-claim>some_claim_containing_the_domain_name</domain-name>
          <username-claim>sAMAccountName</username-claim>
          <id-token-signature-verification-disabled>true</id-token-signature-verification-disabled>
          <display-properties />
          <domain-option>use_domain_claim</domain-option>
        </provider>


or perhaps (if the value of UserPrincipalName, or a similar claim, is something like username@domain):
 
<provider>
          <name>Azure OpenID</name>
          <enabled>true</enabled>
          <discovery-url>https://login.microsoftonline.com-id//v2.0/.well-known/openid-configuration</discovery-url>
          <client-id>9999-9999-9999999-9999</client-id>
          <client-secret>REDACTED</client-secret>
          <username-claim>UserPrincipalName</username-claim>
          <id-token-signature-verification-disabled>true</id-token-signature-verification-disabled>
          <display-properties />
          <domain-option>parse_username_claim</domain-option>
        </provider>

 

Additional Information

Doc: Advanced OpenID Connect settings