Jupyter interactive app with Shibboleth SSO

Hi folks,

I’m working on implementing a Jupyter Notebook interactive app in our setup, from the bc_example_jupyter repo (GitHub - OSC/bc_example_jupyter: Batch Connect - Example Jupyter Notebook Server).

We use Shibboleth for auth, which has worked well so far, but I’m having an issue with the Shibboleth session cookie when connecting to the interactive app. Once the interactive session is created and I try to connect to it via the Connect to Jupyter button, the shib session cookie is cleared, and the session tab fails to load properly. The cookie clearing looks like expected behavior based on the ood-portal.conf that is generated from our ood-portal.yml:

[ood-portal.yml]

auth:
  - "AuthType shibboleth"
  - "ShibRequestSetting requireSession 1"
  - "RequestHeader edit* Cookie \"(^_shibsession_[^;]*(;\\s*)?|;\\s*_shibsession_[^;]*)\" \"\""
  - "RequestHeader unset Cookie \"expr=-z %{req:Cookie}\""
  - "Require valid-user"

# Use Shibboleth logout
logout_redirect: https://login.emory.edu/idp/profile/Logout

# Capture system user name from authenticated user name
user_map_match: '([^@]+)'
              
# turn on proxy for interactive desktop apps
port: 443
logroot: "/var/log/httpd"
use_rewrites: true
use_maintenance: true
maintenance_ip_allowlist: []
lua_root: "/opt/ood/mod_ood_proxy/lib"
lua_log_level: "info"
#user_map_cmd: '/etc/ood/add_user.sh'
pun_stage_cmd: "sudo /opt/ood/nginx_stage/sbin/nginx_stage"
root_uri: /pun/sys/dashboard
public_uri: "/public"
public_root: "/var/www/ood/public"
logout_uri: "/logout"
host_regex: 'ip-10-66-\d+-\d+\.ec2\.internal'
node_uri: /node
rnode_uri: /rnode
nginx_uri: /nginx
pun_uri: "/pun"
pun_socket_root: "/var/run/ondemand-nginx"
pun_max_retries: 5
security_strict_transport: true
oidc_session_inactivity_timeout: 900
oidc_session_max_duration: 900
oidc_state_max_number_of_cookies: "10 true"
oidc_cookie_same_site: 'On'
oidc_settings:
  OIDCPassIDTokenAs: serialized
  OIDCPassRefreshToken: 'On' 

[location blocks for /node and /rnode in ood-portal.conf]

  <LocationMatch "^/node/(?<host>ip-10-66-\d+-\d+\.ec2\.internal)/(?<port>\d+)">
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    RequestHeader edit* Cookie "(^_shibsession_[^;]*(;\s*)?|;\s*_shibsession_[^;]*)" ""
    RequestHeader unset Cookie "expr=-z %{req:Cookie}"
    Require valid-user


    # ProxyPassReverse implementation
    Header edit Location "^[^/]+//[^/]+" ""

    # ProxyPassReverseCookieDomain implemenation
    Header edit* Set-Cookie ";\s*(?i)Domain[^;]*" ""

    # ProxyPassReverseCookiePath implementation
    Header edit* Set-Cookie ";\s*(?i)Path[^;]*" ""
    Header edit  Set-Cookie "^([^;]+)" "$1; Path=/node/%{MATCH_HOST}e/%{MATCH_PORT}e"

    LuaHookFixups node_proxy.lua node_proxy_handler
  </LocationMatch>

  # Reverse "relative" proxy traffic to backend webserver through IP sockets:
  #
  #     https://ondemand-dev.it.emory.edu:443/rnode/HOST/PORT/index.html
  #     #=> http://HOST:PORT/index.html
  #
  <LocationMatch "^/rnode/(?<host>ip-10-66-\d+-\d+\.ec2\.internal)/(?<port>\d+)(?<uri>/.*|)">
    AuthType shibboleth
    ShibRequestSetting requireSession 1
    RequestHeader edit* Cookie "(^_shibsession_[^;]*(;\s*)?|;\s*_shibsession_[^;]*)" ""
    RequestHeader unset Cookie "expr=-z %{req:Cookie}"
    Require valid-user


    # ProxyPassReverse implementation
    Header edit Location "^([^/]+//[^/]+)|(?=/)|^([\./]{1,}(?<!/))" "/rnode/%{MATCH_HOST}e/%{MATCH_PORT}e"

    # ProxyPassReverseCookieDomain implemenation
    Header edit* Set-Cookie ";\s*(?i)Domain[^;]*" ""

    # ProxyPassReverseCookiePath implementation
    Header edit* Set-Cookie ";\s*(?i)Path[^;]*" ""
    Header edit  Set-Cookie "^([^;]+)" "$1; Path=/rnode/%{MATCH_HOST}e/%{MATCH_PORT}e"

    LuaHookFixups node_proxy.lua node_proxy_handler
  </LocationMatch>

Wondering if anyone else has encountered this behavior or had success implementing a Jupyter interactive app while using Shibboleth for SSO.

We’re not super well versed in Shibboleth, but I’d imagine folks have gotten this to work, because, well without it, OnDemand is a bit useless.

Looking at the documentation you need a shib_auth.conf that holds

ShibCompatValidUser On

I just want to verify that you’ve got that configuration.

Beyond that, I’m not really sure what that edit cookie directive is supposed to do. I’d have to search through the git and/or this forum to see how we came up with that. I’d imagine this is largely community driven, which is to say, someone gives us this as it worked for them and we take it on face value that it’s correct.

Thanks for the input, Jeff. Indeed, we have ShibCompatValidUser On in shib_auth.conf

OK then we can look into the session tab fails to load properly. Are you sure it’s an issue with authentication? I mean are you getting 403 forbidden errors from apache?

If so, maybe you can turn on debug or trace level logging to see what’s going on specifically with the cookie edits to find out if those edits are what’s causing the issue.

It actually manifests as a CORS block:

notebook_core.4799ce7e762b693682b6.js?v=4799ce7e762b693682b6:114683 WebSocket connection to ‘wss://ondemand-dev.it.emory.edu/node/ip-10-66-251-136.ec2.internal/6071/api/events/subscribe’ failed

Access to fetch at ‘``https://login.emory.edu/idp/profile/SAML2/Redirect/SSO?SAMLRequest=hZLLUsIwFIZfpZM9TSnl0gztTIWFzKAwtLpw46TNATKTJjUnRX17y0XFDa7zX87%2FTabIa9WwrHV7vYG3FtB5H7XSyE4PCWmtZoajRKZ5DchcxfLsYclCP2CNNc5URhEvQwTrpNEzo7GtweZgD7KCp80yIXvnGmSUGi2g5lr0BBx86Xyojf30QbQ038uyNArc3kc09FgQ0vUqL4g37y6Smh%2Bzf5OU2Ul95Zeiod0xW6ngYt6AkBYqR%2FN8RbzFPCGvAiCOIQq24%2FGIRzweDssyruIRL3l%2FMKiiTobYwkKj49olJAzCYS%2BY9PqTIuyzKGBR%2FEK89WXzndRC6t1tQOVZhOy%2BKNa986BnsHga0wlIOj1iZqdiewX%2Bdiz%2Fpk3S%2F9niD9spvSo7NzfssUtfzNdGyerTy5Qy7zML3EFC%2BoSmZ8vf%2F5F%2BAQ%3D%3D&RelayState=ss%3Amem%3Aa5fdf98e3ff7dffcbf91baa24e711748c9afccca9714a33f4dfdbfb754435f71’`` (redirected from ‘``https://ondemand-dev.it.emory.edu/node/ip-10-66-251-136.ec2.internal/6071/lab/api/translations/default?1755553249719’``) from origin ‘``https://ondemand-dev.it.emory.edu``’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Without the Shibboleth session present in the notebook tab, the link is redirected to the login URL at https://login.emory.edu

Hmmmmm, that’s odd.

Maybe you’re able to add that header through an apache directive? You can use custom_vhost_directives to add directives to the vhost (also custom_location_directives to add directives to every location).

Something like this maybe (you’ll have to account for the actual hostname here)?

RequestHeader setifempty Access-Control-Allow-Origin ondemand-dev.it.emory.edu

That didn’t change the behavior, unfortunately. IIRC Access-Control-Allow-Origin is a response header so can’t really be changed via the vhost. I’ve also tested with attempts at removing the auth items from the /node location (AuthType/ShibRequestSetting/RequestHeader/Require) to no avail; Apache hits a 500 in that scenario.

Something else strange that I’ve noticed - sometimes the shib session cookie is still present in the newly opened Jupyter session browser tab, and I can even get as far as opening a notebook file (another new tab) and running commands, before the cookie is cleared when saving the notebook.

Yea but the directive is RequestHeader to edit request headers.

In any case, maybe you can try to use the current tab? In the view.html.erb you probably have target="_blank". Try removing this to get Jupyter in the same tab and see if that’s any better for you.

@jeff.ohrstrom Do you know if any institution have successfully deployed OOD with Jupyter Interactive app behind Shibboleth? If there is, we would like to reach out to understand their setup.

You can try to ping the folks on this topic - from the looks of it they run shibboleth and have Jupyter running. They appear to be from the University of Virginia.

2 Likes

I pulled that topic from searching Shib on this forum, there may be others.

https://discourse.openondemand.org/search?q=Shib%20order%3Alatest

Thanks for the input, @jeff.ohrstrom . Still the same behavior with opening the Jupyter session in the same browser tab via removal of target="_blank" from view.html.erb.

I’ll have a look through those links and reach out to those folks. I’ve also reverted our setup from Shibboleth to LDAP and found that to be working as expected.