-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add login using ORCID oauth #2276
base: dev
Are you sure you want to change the base?
Conversation
d2dc9b3
to
03a3e01
Compare
There are a few issues I see here - some small, some larger - but first we need to understand the high level functionality. We currently have the option to add an ORCID ID to a user's profile. Is it your intention that someone who has already done that should now be able to log in via ORCID? What does "log in via ORCID" mean, exactly? What is the process that the user goes through (explain the steps for somebody who doesn't understand OAuth) and how does this process prove that the person sitting at the keyboard is the person with that ORCID ID? You also need to explain how "registration" works: describe at a high level what steps are taken, from when a new user first visits the site, until they are fully registered and logged-in. |
Yes, it was my intention that someone who has already linked an ORCID ID profile should now be able to log in using ORCID. In my opinion, those shouldn't be separate, user still have the option to log in using a username and password. Moreover, linking ORCID ID uses the same Oauth mechanism to authorize a user. It would be a bad user experience that once accounts are linked, users cannot use all linked account benefits and have to link ORCID one more time just to log in.
From a user's perspective, once the user clicks From a technical point of view, when the user is redirected to Physionet page after authorization, Physionet and Orcid exchange first the code, then the token, which consists of encrypted Orcid user data, such as ORCID ID. This token could also be used to access more ORCID user data, but we are not using this functionality. On our site, we are validating the token against malicious behavior. If everything is correct and this ORCID ID is linked to some user in Physionet then this user is logged in.
If, after the authorization process, we see that this ORCID ID is not linked to any account, then we redirect users to a standard registration form, where they have to create a Physionet account providing a username, email, and password. Orcid profile is automatically linked to the new account using data from the Orcid authorization token. If an account is not created then nothing happens. |
What is validated? What kind of malicious behavior? Please be specific. This article seems like a good place to start: https://oauth.net/articles/authentication/ |
Thanks for a great article. Referring to it, when I was writing Also when implementing ORCID authentication, I followed their documentation ( |
04185f1
to
8a5df40
Compare
Hi @bemoody, after our last call I two changes:
|
If somebody's ORCID account was compromised on Monday, and they reset their ORCID password on Tuesday, and they try to log in to PhysioNet using ORCID on Wednesday, how do we know whether it's the real person or the attacker? If they logged in to PhysioNet using ORCID on Monday, and their ORCID account was compromised on Tuesday, and they reset their ORCID password on Wednesday, and they visit a PhysioNet page on Thursday using the session cookie they received on Monday, how do we know whether it's the real person or the attacker? |
If the password is changed on Tuesday then all the active ORCID sessions should be invalidated including this Monday's one, therefor if the attacker tries to log in to Physionet on Thursday they will have to go through the OAuth authentication flow again which requires knowledge of the new ORCID password
It depends on how long we keep the session on our side. When the ORCID account is compromised, Physionet itself cannot automatically know this. Unfortunately, ORCID (like most of the OAuth providers) does not notify relying parties about password resets or compromises. It is on our side to invalidate session cookies as often as possible (24 hours seems reasonable). If the attacker gets the session cookie to Physionet, he/she will be able to access the attacked account until the cookie expires. Also, if someone's ORCID account is compromised, good practice is to change the passwords to all websites this ORCID account was linked. Those are very extreme scenarios. As website creators, we often cannot determine whether the account was compromised. Currently, in our flow, if an attacker gets access to a user's email, then Physionet cannot do anything, as the attacker can change the password (using reset password form) and log in to Physionet using a new password. In both scenarios, we trust the users that they can keep their email/ORCID accounts safe. |
Right. So how do you know that the person went through the ORCID login - how do you know that the "code" they gave you was generated recently?
PhysioNet session IDs are valid for 14 days. This is not a security problem, because when you change your password, all other sessions are invalidated. Having sessions that expire without warning or recourse is a significant usability problem (which is why I've insisted that we don't change from the Django defaults.) For example, I don't think it's okay if, after somebody spends 8 hours uploading a file, the upload is rejected because they had logged in 31 hours earlier. In fact, we could and should do better than we're doing now. |
I've now done a bunch of reading on OIDC, looked at some existing libraries and was unimpressed. ;) But it seems like there are a couple of possibilities:
|
It doesn't say in the documentation but I checked it experimentally and code is valid for no more than 10 minutes. After this time I got
That's a valid case, but as said on a meeting the attackers will have access to the Physionet as long as they will have valid session. If we want to keep session alive as long as the ORCID session they it will last couple of hours (no more than one day). |
To elaborate on my previous comment: Naturally, we only know what happens on our server. Verifying the We want to allow authenticated clients to remain logged-in to PhysioNet for a reasonably long time (say, at least 24 hours), and we also want unauthenticated clients to be rejected within a reasonably short time period after they cease to be authenticated (say, at most one hour.) That means that we need to regularly receive updated information from the ORCID service to tell us whether that client is still authenticated from their point of view. There is no clever way to make this work without polling the ORCID server in some way. making the client do the pollingOne way to poll the ORCID server is to tell the client to go and get a new authorization code. It's possible that this could be done by embedding an iframe (e.g., in navbar.html, with appropriate CSS to make it invisible), where the content of the iframe contains:
Then, after 600 seconds, the client will request a new auth code from orcid.org; orcid.org will give either a new auth code or an error; and we tell the client to do the same thing 600 seconds later. Some logic is needed to ensure that if the user is authenticated via ORCID, and we have not received a positive response from the ORCID server recently, then the user is treated as anonymous. It might be possible to do this by expiring the Django session, but it might be better to use a separate middleware for this purpose. Of course, we can also add logic to the user login view to say: if the client was previously authenticated via ORCID and has now expired, then redirect directly to ORCID without showing a PhysioNet login form. polling on the server sideThe other way to poll the ORCID server is to use the refresh_token, as described here: https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens This might or might not work, depending on the OIDC provider. The advantage is that it's seamless from the client's POV - it works in places where client-side redirection is impossible. This would have to be done by middleware, I would think. The Django auth backend API doesn't seem to provide a way to do it. |
Thanks @bemoody for explaining what you want to achieve. It makes sense but let me verify what options we have and whether they are programmaticaly doable. Thanks also for the tip with iframe and refresh_token. I will come back to you with potential solutions. |
ed65f4f
to
4e2602a
Compare
Since i have partly taken over this one:
That in a way is quite limiting since a user would be trapped into "orcid login" way of accessing our platform whenever he/she connects orcid to the physionet itself, we could be adding some sort of disconnect feature but that kind of defeats a purpose. We could be also adding a button to
Refresh token is not deactivated when user changes password and the token by itself has quite long expiry date which means that the attacker would be able to access the site anyway. |
[T-CAIREM 1243]
[T-CAIREM 1243]
4e2602a
to
f4f6b1e
Compare
Change introduces three new endpoints:
authorcid_login
-> which exchanges token with ORCID using Oauth and logs in the user if ORCID is already connected to the existing user or redirects toorcid_register
for new usersorcid_register
-> present a form to register new users and links ORCID to it once registeredorcid_init_login
-> builds URL and redirects to ORCID for authorizationThis PR also introduces changes in the login view and SSO login view: