developmentseed / eoapi-risk

An implementation of eoAPI for Risk data and the Humanitarian sector
MIT License
2 stars 0 forks source link

Enable CORS #23

Closed alukach closed 10 months ago

alukach commented 10 months ago

If we are to support a PKCE auth flow, the JupyterHub API must reply to OPTIONS requests with CORS headers (Access-Control-Allow-Origin, Access-Control-Allow-Methods, etc) to permit application frontends to make POST requests to the JupyterHub API when exchanging an authorization code for an access token.

In the beginning, I think it's reasonable to set Access-Control-Allow-Origin to * and then we can later rework that to an allow-list once origins have been established.

batpad commented 10 months ago

cc @sunu

batpad commented 10 months ago

@alukach I'm fairly certain JupyterHub does not support this directly and one does need a backend application in the middle to handle the OAuth hand-off with JupyterHub.

Are there other reasons to support CORS on JupyterHub?

There's some tickets on Jupyter to enable CORS: https://github.com/jupyter/jupyter/issues/79 but am not sure this is exactly what we need.

@alukach is it possible to use a browser extension to disable CORS to check whether doing that does indeed solve the problem you're facing before delving into the JupyterHub config to support CORS?

alukach commented 10 months ago

@batpad @sunu Unfortunately, I don't think #25 did the trick. I'm not seeing Access-Control-Allow-Origin or Access-Control-Allow-Methods in the response headers:

▶ curl 'https://jupyter.ifrc-risk.k8s.labs.ds.io/hub/api/oauth2/token' -X 'OPTIONS' --verbose
*   Trying 35.239.254.92:443...
* Connected to jupyter.ifrc-risk.k8s.labs.ds.io (35.239.254.92) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=jupyter.ifrc-risk.k8s.labs.ds.io
*  start date: Nov 22 06:46:05 2023 GMT
*  expire date: Feb 20 06:46:04 2024 GMT
*  subjectAltName: host "jupyter.ifrc-risk.k8s.labs.ds.io" matched cert's "jupyter.ifrc-risk.k8s.labs.ds.io"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x13980c000)
> OPTIONS /hub/api/oauth2/token HTTP/2
> Host: jupyter.ifrc-risk.k8s.labs.ds.io
> user-agent: curl/7.79.1
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< date: Wed, 17 Jan 2024 21:12:44 GMT
< content-type: application/json
< content-length: 0
< x-jupyterhub-version: 4.0.2
< access-control-allow-headers: accept, content-type, authorization
< content-security-policy: frame-ancestors 'self'; report-uri /hub/security/csp-report; default-src 'none'
< strict-transport-security: max-age=15724800; includeSubDomains
< 
alukach commented 10 months ago

@batpad sorry, my reading comprehension was a little off earlier. Using a browser extension to circumvent CORS was a totally reasonable suggestion, I should have thought of that before bothering you all.

Disabling CORS did not help, I received a 403 from https://jupyter.ifrc-risk.k8s.labs.ds.io/hub/api/oauth2/token stating:

{"status": 403, "message": "'_xsrf' argument missing from POST"}

We can call this a "won't-fix".

alukach commented 10 months ago

I've reverted #25 in #26.

batpad commented 10 months ago

Thanks @alukach ! no worries at all - yea, I was a bit afraid the Jupyter auth system fundamentally does not support this currently.

I can definitely see the value in JupyterHub allowing this, though, so that clients can auth directly without needing an intermediary backend - I'll follow up with Yuvi about this and see if there's anything we can do upstream to make this happen.