Open dylanmcreynolds opened 2 years ago
About PKCE, this is a nice discussion: https://dropbox.tech/developers/pkce--what-and-why-
To add more information about PKCE. Until recently, SPA (and mobile apps) were guided towards implicit flow
for a number of reasons. Without cross-site scripting capability, following code authorization
flow would leak the client ID in the browser. So, implicit flow
was as good as it got.
Then, CORS came around, allowing the browser to potentially post to the IdP (ORCID) and Service (Tiled). This opens the door for the Service (Tiled) to perform the code exchange behind the scenes. Because that's now possible and it's more secure, the recommendation is to do it. However...because this is still through the browser, the code (coming from the IdP (ORCID) to the Service (Tiled) is now viewable. So, the recommendation is to add PKCE to the mix so that the IdP (ORCID) can verify that the request came from the same browser that asked for the code. Here's how I think this will work:
Browser redirects user to ORCID, adding OAuth bits to the url.
https://orcid.org/oauth/authorize?
response_type=code
&redirect_uri=
Once the user logs in, ORCID redirects the browser back to the ?code=<code>
to the url
Browser app posts the code and the code_verifier
that was used to create the code_challenge
to Tiled (at /auth/code
)
Tiled then adds the code_verifier
and code_challenge_method
to the message it already sends to ORCID.
ORCID validates the the code_challenge
and code_verifier
match before issuing an access_token.
Now, this seems pretty important. Unfortunately, it looks like ORCID does not yet support it! (https://trello.com/c/3A5mdVZ1/289-oauth-pkce-cors-support) But I surely wanted to get this typed out for posterity.
Trying to write a login page from HTML that works with Tiled using ORCID as the authenticator. (Everything herein is about ORCID, but should apply to any OIDC IdP.)
The general flow I'm trying to setup is:
login.html
sends the user to ORCID saying "I want: return type of code, oidc scope and redirect back to me when the user is done"login.html
says "oh, there's a code in the query params of me"/auth/code
access_token
andrefresh_token
This works as long as I configure the tiled to use the one and only login page.
But what if a single tiled server supports multiple web pages from multiple realms?
That isn't possible now, because when tiled exchanges the code with ORCID (https://github.com/bluesky/tiled/blob/cfa0e45b5042049bb2fccc2f673160bf1e0d058b/tiled/authenticators.py#L126) the code that ORCID is checking was built with the redirect_url of the web page. But tiled is building the message using the "configured" redirect_url that works for our python clients (and notebooks). ORCID rejects this message because that was not the redirect_url that the code was created for.
I propose enhancing tiled to configure multiple redirect_urls (like OIDC IdPs do)? Then we could send the redirect_url we want in a query param of the
/auth/code
. If the provided redirect_url wasn't pre-configured, then we reject the message. But if it was, then we send it to ORCID so that it can correctly validate the code.Also, we need to look into supporting PKCE. https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-11#section-2.1.1 I'm not sure what all will go into that but putting it here for discussion.