I'm creating a Dashboard service where multiple users can access multiple notebook servers via JupyterHub.
Users log in using a separate Authentication service, and once in Dashboard, JupyterHub
gets rendered inside an <iframe>
.
I'm hosting JupyterHub
in a Kubernetes
cluster on GCP. These are the relevant portions of my config.yaml
:
...
# Changes the Jupyter's notebook headers to allow it to be displayed
# inside of an iframe object.
c.JupyterHub.tornado_settings = {
"headers": {
"Content-Security-Policy": "default-src * data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval' 'unsafe-dynamic'; script-src * data: blob: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src * data: blob: ; style-src * data: blob: 'unsafe-inline'; font-src * data: blob: 'unsafe-inline';",
}
}
...
auth:
type: custom
custom:
className: oauthenticator.generic.GenericOAuthenticator
config:
login_service: "OpenID"
client_id: "<client_id>"
client_secret: "<client_secret>"
However, when I try to sign in just via my JupyterHub
endpoint I get:
500 Internal Server Error
logs:
IwN2YyNzVhNTk0MzM0ZTM5YmIyZTdmZDQzY2U2ZDI3YyIsICJuZXh0X3VybCI6IG51bGx9&session_state=641fb9aca6490d2c3332871d72ee0639b3ed46b8a9f02c363ee8f7bf46f1c989.74e37d534296
cad45421019d1d442153', version='HTTP/1.1', remote_ip='<>')
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/tornado/web.py", line 1703, in _execute
result = await result
File "/usr/local/lib/python3.6/dist-packages/oauthenticator/oauth2.py", line 213, in get
user = await self.login_user()
File "/usr/local/lib/python3.6/dist-packages/jupyterhub/handlers/base.py", line 699, in login_user
authenticated = await self.authenticate(data)
File "/usr/local/lib/python3.6/dist-packages/jupyterhub/auth.py", line 383, in get_authenticated_user
authenticated = await maybe_future(self.authenticate(handler, data))
File "/usr/local/lib/python3.6/dist-packages/oauthenticator/generic.py", line 136, in authenticate
resp_json = json.loads(resp.body.decode('utf8', 'replace'))
File "/usr/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 5 column 1 (char 4)
I know it actually does redirect to the Authentication Server and the callback is correct. Even still when I attempt to access via Dashboard, within the <iframe>
I get:
400 OAuth state missing from cookies
logs:
400 GET /hub/oauth_callback?code=d37de16a855a49dda94fb65c2c2c8ffa&state=eyJzdGF0ZV9pZCI6ICIwN2YyNzVhNTk0MzM0ZTM5Ym
IyZTdmZDQzY2U2ZDI3YyIsICJuZXh0X3VybCI6IG51bGx9&session_state=641fb9aca6490d2c3332871d72ee0639b3ed46b8a9f02c363ee8f7bf46f1c989.74e37d534296cad45421019d1d442153
OAuth state missing from cookies
For context: I previously used the Github OAuthenticator class and registered an OAuth app within Github and got JupyterHub
to work fine. However, Github does not allow their apps to be used within an <iframe>
so I had to go the generic route.
Point is, the setup was very similar and at least had JupyterHub
working outside of Dashboard, so I'm really stumped on what else I could be missing. Any help is appreciated.