waterbutler
waterbutler copied to clipboard
OAuth2 login broken in QOpenScienceFramework
The QOpenScienceFramework python library, which is also used by OpenSesame to log into the OSF, has broken. I'm not sure what caused it to break (it used to work fine), but I suspect it's related to the redesigned OSF login window when logging in through OAuth2 (or at least breakage happened around the same time that the login window also changed in appearance).
When the login window is opened, the following URLs are called in rapid succession. The first is called by us, the others are redirected by the OSF itself.
https://accounts.osf.io/oauth2/authorize?response_type=token&client_id=e34213865878476da9bdbf24e9393797&redirect_uri=https%3A%2F%2Fosdoc.cogsci.nl%2Fcallback%2F&scope=osf.full_read+osf.full_write&state=DsmSU4Dc7wPbdda9NRoYgTeewVCeBe
https://accounts.osf.io/oauth2/authorize?response_type=token&client_id=e34213865878476da9bdbf24e9393797&redirect_uri=https%3A%2F%2Fosdoc.cogsci.nl%2Fcallback%2F&scope=osf.full_read+osf.full_write&state=DsmSU4Dc7wPbdda9NRoYgTeewVCeBe
https://accounts.osf.io/login?service=https%3A%2F%2Faccounts.osf.io%2Foauth2%2FcallbackAuthorize%3Fclient_id%3De34213865878476da9bdbf24e9393797%26redirect_uri%3Dhttps%253A%252F%252Fosdoc.cogsci.nl%252Fcallback%252F%26response_type%3Dtoken%26client_name%3DCasOAuthClient
At this point, a login window appears, as you would expect.
If I then enter my login credentials and actually try to log in, the following URL is called:
https://accounts.osf.io/oauth2/authorize?response_type=token&client_id=e34213865878476da9bdbf24e9393797&redirect_uri=https%3A%2F%2Fosdoc.cogsci.nl%2Fcallback%2F&scope=osf.full_read+osf.full_write&state=zqDIUktAsU3oICTAZ6xWY6ZXaBziLk
At this point, a window with the following error appears:
I initially thought that the issue was due to the redirect URL that we used. But I tried different ones, and they all give the same error.
See also #open-cogsci/QOpenScienceFramework#24
Ping @dschreij
Thanks for reporting the issue @smathot and 👍 for the details. You are right about the cause of the failure.
-
We disabled the response type
token
to force thecode
->token
approach, unaware of any external usages. Sorry about this and we will add it back. -
The error message is confusing too here since the redirect URI is also the service ID of the OAuth app that gets displayed. We use the Apereo CAS OAuth module and let me see if we can improve this part as well. At least it should say something like
response type [response_type=token] not allowed for OAuth service [id=...]
.
I will link the fix here once it's up.
After further look, I discovered the reason that we disabled the token
as response type is because it is the legacy implicit flow. This is no longer recommended and is unsafe to use. See: https://oauth.net/2/grant-types/implicit/. We are now hesitating reenabling it.
Maybe it's a better choice for the the library client to use the authorization code (https://oauth.net/2/grant-types/authorization-code/). In our implementation (which follows OAuth 2.0 specs), it is response_type=code
during authorization request and grant_type=authorization_code
during exchanging the code for access token.
Thanks for the explanation. So basically this means you have switched to the PKCE grant flow? Do you have any documentation on the end points you have created to make this possible? @smathot I think this will take some time to fix. This authentication process is highly similar to the previous one, but does involve an extra step, and I do need to get familiar again with the code that did authentication for QOSF. I hope to find some consecutive hours for this soon.
So basically this means you have switched to the PKCE grant flow?
Not yet, this is the second / future part of our OAuth server upgrade which is supported by the library we use. We will put a notification up for the change when it is ready but I don't think we will make it required.
Do you have any documentation on the end points you have created to make this possible?
I am working on writing a new documentation. As for the current one, the our API Doc points to the wrong place. for now you can take a look at this one. I will let you know when the new docs are up and the links are fixed later this week.
One extra note, the scope delimiter is a
(space) instead of a +
when you have multiple scopes.
Thanks for the information, so as far as I can tell there is one extra step involved in which you trade the code for a token, compared to the previous (our current) situation, in which we directly received the token after authorization. I will see if I can work around this. As far as my knowledge of PKCE grant flow goes, this seems exactly it! (e.g. adding the extra code -> token step). What in your view is still missing from this current process compared to a real PKCE flow?
Apology for losing track of this! Have you been able to fix issue with the Authorization code flow?
I found a better page that explains the differences between the three (i.e. implicit, code, code with PKCE).
And more details for what problems PKCE solves for the following two types of app compared to code flow.
Native apps Cannot securely store a Client Secret. Decompiling the app will reveal the Client Secret, which is bound to the app and is the same for all users and devices. May make use of a custom URL scheme to capture redirects (e.g., MyApp://) potentially allowing malicious applications to receive an Authorization Code from your Authorization Server.
Single-page apps Cannot securely store a Client Secret because their entire source is available to the browser.
Have you been able to fix issue with the Authorization code flow?
No, we haven't had time to dive into this yet!