OHDSI / WebAPI

OHDSI WebAPI contains all OHDSI services that can be called from OHDSI applications
Apache License 2.0
126 stars 156 forks source link

Configuring OpenID Authentication #2304

Closed wtroddy closed 9 months ago

wtroddy commented 10 months ago

Expected behavior

We're currently trying to configure an OpenID auth provider (Okta) and are using the latest version of Broadsea (https://github.com/OHDSI/Broadsea/commit/86b77d580aecdd2cdb5768646dcfbc8a003abba1). We're expecting that configuring the environment variables for OpenID should redirect the user to Okta for sign in.

Actual behavior

After setting the environment variables, when clicking the button for the OpenID connection in Atlas, we are redirected to : http://127.0.0.1/WebAPI/user/login/openid?redirectUrl=/home and receive a HTTP status 500.

This also raises this error in the WebAPI container:

2023-08-22 19:30:12.249 ERROR http-nio-8080-exec-6 org.ohdsi.webapi.shiro.filters.ExceptionHandlerFilter - [] - Error during filtering
javax.servlet.ServletException: org.pac4j.core.exception.TechnicalException: java.io.IOException: HTTP 302: Moved Temporarily
    at org.apache.shiro.web.servlet.AdviceFilter.cleanup(AdviceFilter.java:196) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:148) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.ohdsi.webapi.shiro.filters.ResponseNoCacheFilter.doFilter(ResponseNoCacheFilter.java:26) ~[classes/:?]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:147) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:458) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:373) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) ~[shiro-core-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) ~[shiro-core-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387) ~[shiro-core-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:370) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:154) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.ohdsi.webapi.shiro.filters.CacheFilter.doFilter(CacheFilter.java:35) ~[classes/:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.ohdsi.webapi.shiro.filters.ExceptionHandlerFilter.doFilter(ExceptionHandlerFilter.java:28) [classes/:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.25.RELEASE.jar!/:4.3.25.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:808) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_342]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_342]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.43.jar!/:8.5.43]
    at java.lang.Thread.run(Thread.java:750) [?:1.8.0_342]
Caused by: org.pac4j.core.exception.TechnicalException: java.io.IOException: HTTP 302: Moved Temporarily
    at org.pac4j.oidc.config.OidcConfiguration.internalInit(OidcConfiguration.java:148) ~[pac4j-oidc-4.0.0.jar!/:?]
    at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:20) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.oidc.client.OidcClient.clientInit(OidcClient.java:50) ~[pac4j-oidc-4.0.0.jar!/:?]
    at org.pac4j.core.client.IndirectClient.internalInit(IndirectClient.java:63) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:20) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.client.IndirectClient.getRedirectionAction(IndirectClient.java:91) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.engine.DefaultSecurityLogic.redirectToIdentityProvider(DefaultSecurityLogic.java:224) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.engine.DefaultSecurityLogic.perform(DefaultSecurityLogic.java:157) ~[pac4j-core-4.0.1.jar!/:?]
    at io.buji.pac4j.filter.SecurityFilter.doFilter(SecurityFilter.java:82) ~[buji-pac4j-5.0.1.jar!/:?]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    ... 70 more
Caused by: java.io.IOException: HTTP 302: Moved Temporarily
    at com.nimbusds.jose.util.DefaultResourceRetriever.retrieveResource(DefaultResourceRetriever.java:211) ~[nimbus-jose-jwt-8.11.jar!/:8.11]
    at org.pac4j.oidc.config.OidcConfiguration.internalInit(OidcConfiguration.java:145) ~[pac4j-oidc-4.0.0.jar!/:?]
    at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:20) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.oidc.client.OidcClient.clientInit(OidcClient.java:50) ~[pac4j-oidc-4.0.0.jar!/:?]
    at org.pac4j.core.client.IndirectClient.internalInit(IndirectClient.java:63) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:20) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.client.IndirectClient.getRedirectionAction(IndirectClient.java:91) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.engine.DefaultSecurityLogic.redirectToIdentityProvider(DefaultSecurityLogic.java:224) ~[pac4j-core-4.0.1.jar!/:?]
    at org.pac4j.core.engine.DefaultSecurityLogic.perform(DefaultSecurityLogic.java:157) ~[pac4j-core-4.0.1.jar!/:?]
    at io.buji.pac4j.filter.SecurityFilter.doFilter(SecurityFilter.java:82) ~[buji-pac4j-5.0.1.jar!/:?]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108) ~[shiro-web-1.10.1.jar!/:1.10.1]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137) ~[shiro-web-1.10.1.jar!/:1.10.1]
    ... 70 more
2023-08-22 19:30:12.252 ERROR http-nio-8080-exec-6 org.apache.juli.logging.DirectJDKLog - [] - Servlet.service() for servlet [org.ohdsi.webapi.JerseyConfig] in context with path [/WebAPI] threw exception

Steps to reproduce behavior

We're currently configuring the connection via these environment variable settings:

# Atlas GUI configuration
ATLAS_USER_AUTH_ENABLED="true" 

# Atlas security provider configuration 
ATLAS_SECURITY_PROVIDER_TYPE="openid"    
ATLAS_SECURITY_PROVIDER_NAME="Okta OIDC" 
ATLAS_SECURITY_ICON="fa-cubes"           
ATLAS_SECURITY_USE_FORM="false"          
ATLAS_SECURITY_USE_AJAX="false"          

# WebAPI security configuration
WEBAPI_SECURITY_PROVIDER="AtlasRegularSecurity"

SECURITY_OAUTH_CALLBACK_UI="http://localhost/Atlas/"
SECURITY_OAUTH_CALLBACK_API="http://localhost:8080/WebAPI/user/oauth/callback/OidcClient"
SECURITY_OAUTH_CALLBACK_URLRESOLVER="query"

SECURITY_AUTH_OPENID_ENABLED="true"
SECURITY_OID_CLIENTID="{CLIENTID}"
SECURITY_OID_APISECRET="{APISECRET}"
SECURITY_OID_URL="http://{host.okta.com}/oauth2/default/v1/authorize/"
SECURITY_OID_LOGOUTURL="http://localhost/Atlas/"
SECURITY_OID_EXTRASCOPES="openid email"
SECURITY_OID_REDIRECTURL="http://localhost/Atlas/"

Is there any obvious issues with our setup or configuration? Is there anyone in the community actively using OpenID that has experience configuring this?

Thanks!

davidhcar commented 10 months ago

@wtroddy Try updating these variables,

SECURITY_OAUTH_CALLBACK_UI="http://localhost/atlas/#/welcome"
SECURITY_OAUTH_CALLBACK_API="http://localhost:8080/WebAPI/user/oauth/callback"
SECURITY_OAUTH_CALLBACK_URLRESOLVER="path"

SECURITY_OID_REDIRECTURL="http://localhost/atlas/index.html#/welcome"

The SECURITY_OID_URL should be .well-known/openid-configuration not authorize endpoint, something like,

SECURITY_OID_URL="http://{host.okta.com}/oauth2/default/v1/.well-known/openid-configuration you might want to check Oakta for exact URL.

wtroddy commented 10 months ago

Hi @davidhcar - thanks for the feedback. I tried those updates and am unfortunately getting the same error still. Do you know if there are any other configuration pieces that might be misaligned?

davidhcar commented 10 months ago

What is this URL http://127.0.0.1/WebAPI/user/login/openid?redirectUrl=/home looks like after the changes,

wtroddy commented 10 months ago

I'm getting redirected to this URL: http://127.0.0.1/WebAPI/user/login/openid?redirectUrl=/home and it's displaying the HTTP Status 500 Internal Server Error.

chrisknoll commented 10 months ago

If you get a 500 response, you should check your WebAPI logs, you'll probably find an exception there.

wtroddy commented 10 months ago

Ah, yes - I see the WebAPI log error has updated since my first post. Here's the log with the relevant error webapi_oidc_error.log , but it looks like the errors are related to this: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext). Further downstream I'm seeing references to a problem accessing the trust store caused by a EOF Exception.

Any ideas where to go from here?

chrisknoll commented 10 months ago

Can you confirm which JDK you are running WebAPI under? I'm not entierly familiar with setting up keystores, but it sounds like it has something to do with that. hopefully there's someone with more knowledge to help here.

Can you also confirm your OS? Maybe it's a Linux vs. Windows setup issue.

Edit: Nevermind, I see you're running on Broadsea, and probably using a Linux container.

@alondhe , any insights here?

Edit 2: I found this stack overflow article that talks about this error. Is there anything related to keystore in the Broadsea configuration?

wtroddy commented 10 months ago

Yeah, I'm using Broadsea and Linux containers.

It looks like Broadsea expects some key files to setup SSL with Traefik to enable HTTPS, secure LDAP or SAML; however, it isn't immediately clear from the docs if that would have any impact on the Open ID auth method? I'm not sure why I'd need SSL to get the OID URL redirect to work, though. But I guess that stack overflow article seems to hint that maybe there's some other setting that could be complicating matters here.

@alondhe - if you have any input it'd be appreciated!

wtroddy commented 9 months ago

I was able to get OIDC working with Broadsea. The issue was related to a portion of configuration in the Broadsea setup and not something on WebAPI's end. I realize these are details related specifically to Broadsea and not WebAPI generally, but I'm going to go ahead and add some details on how I resolved this here in case future users stumble on this issue.

Changes to ohdsi-webapi.yml

This seems to be what ultimately fixed my error from above. I had to comment out the "volumes" portion of the docker file (lines 14-15). Once I removed the ./cacerts reference it seemed to resolve the problems I was having with SSL, etc. above. I'm not sure if that's intended or if ./cacerts is something that should always be provided if using security, but it at least resolved the issue here.

WebAPI / .env Values

In Broadsea's .env file, I made these updates and changes:

# section 2 
ATLAS_USER_AUTH_ENABLED="true"

# section 4
ATLAS_SECURITY_PROVIDER_TYPE="openid"
ATLAS_SECURITY_PROVIDER_NAME="Okta OIDC"
ATLAS_SECURITY_ICON="fa-cubes"
ATLAS_SECURITY_USE_FORM="false"
ATLAS_SECURITY_USE_AJAX="false"

# section 5
WEBAPI_SECURITY_PROVIDER="AtlasRegularSecurity"

# OAuth
SECURITY_OAUTH_CALLBACK_UI="http://127.0.0.1/atlas/#/welcome"
SECURITY_OAUTH_CALLBACK_API="http://127.0.0.1/WebAPI/user/oauth/callback"
SECURITY_OAUTH_CALLBACK_URLRESOLVER="path"

# OpenID
SECURITY_AUTH_OPENID_ENABLED="true"
SECURITY_OID_CLIENTID="MY_CLIENT"
SECURITY_OID_APISECRET="MY_SECRET"
SECURITY_OID_URL="https://{MY_PREFIX}.okta.com/oauth2/default/.well-known/openid-configuration"
SECURITY_OID_LOGOUTURL="http://localhost/Atlas/"
SECURITY_OID_EXTRASCOPES="openid email"
SECURITY_OID_REDIRECTURL="http://localhost/atlas/index.html#/welcome"

Granting Permissions to new User

The final piece to getting auth to work was that I needed to approve this new user (and elevate them to admin). Depending on your specific use case this is going to vary a bit, but broadsea only supports one security mechanism at a time by default. I ended up manually adding a second entry to atlas/config-local-template.js so that I could enable "basic"/"database" authentication in order to login as an admin and then elevate my new OIDC user.

It's also worth noting that this raised a SQL error when trying to login:

ERROR:  relation "ohdsi.users_data" does not exist at character 22
STATEMENT:  select password from ohdsi.users_data where lower(email) = lower($1)

It seems that the Broadsea-AtlasDb was configured to use webapi_security.security instead of the default above. The current image .env file has a variable that sets the schema but it doesn't have one to set the authentication query. Initially I resolved this by creating a view (e.g., create view ohdsi.users_data as (select * from webapi_security."security");) but later discovered that I can just set the query as an environment variable. That required two updates:

In .env I added

SECURITY_DB_DATASOURCE_AUTHENTICATIONQUERY="select password from webapi_security.security where lower(email) = lower(?);"

And in ohdsi-webapi.yml I added:

SECURITY_DB_DATASOURCE_AUTHENTICATIONQUERY: ${SECURITY_DB_DATASOURCE_AUTHENTICATIONQUERY}

This seems worth updating in Broadsea, so I'll create an issue in that repo.

Thanks all for your help on this! I'll go ahead and close the issue.

chrisknoll commented 9 months ago

Thank you so much for documenting your journey explaining the issues and how you resolved. This is extremely helpful to other users who have the same problem, and to the maintainers to help improve documentation.