Skip to content
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

Bug: Scopes from UserInfo object not propagated for all authentication providers. #2164

Closed
jblankenship5 opened this issue Apr 22, 2024 · 4 comments · Fixed by #2283
Closed
Labels
bug Something isn't working

Comments

@jblankenship5
Copy link

I'm using google sign in... there's nothing in docs (that I've seen) about how to set user scopes that works. I can set the user scopes, but that corresponds to the user scopes in the UserInfo table... which doesn't actually mean anything? I saw in another post that you have to set user scopes on sign in with session.auth.signInUser. Does anyone know how to achieve this with google sign in?

@SandPod SandPod added bug Something isn't working and removed bug Something isn't working labels Apr 22, 2024
@SandPod
Copy link
Contributor

SandPod commented Apr 22, 2024

Hey @jblankenship5!

I understand the confusion around this. I need to update my answer in the discussion you engage in as well (source).

In order to set the scopes for a user you should use the Users.updateUserScopes(...) method. The method updates both the User model and already existing authentication keys for the user. You can find our documentation around it here: https://docs.serverpod.dev/concepts/authentication/basics#managing-scopes

There is however an issue here that needs to be fixed. For all providers (except the email provider) the scopes defined in the user are not used when creating new authentication keys. This means the authenticatoin key might have zero scopes when authenticated through the google provider even though the user has been granted additional scopes.

This is a bug that we need to fix and I will update the title of the issue to better reflet it.

@SandPod SandPod changed the title How to set user scopes when using google authentication Bug: Scopes from UserInfo object not propagated for all authentication providers. Apr 22, 2024
@SandPod
Copy link
Contributor

SandPod commented Apr 22, 2024

You can also use the authentication callback onUserCreated to set any scopes for the user once they are created.

@jblankenship5
Copy link
Author

jblankenship5 commented Apr 24, 2024

Thanks for the quick response @SandPod. Could you provide a little more detail around best practices when using Users.updateUserScopes. A real world example would be perfect. Currently I'm updating the scopes after login by passing the scopes from UserInfo.scopeNames to Users.updateUserScopes(session, id, userScopes), which feels really gross. Also, after doing so, session manager listener doesn't trigger when scopes are changed by updateUserScopes, and I can't access the new scopes in the same endpoint method after changing the scopes. i.e. await Users.updateUserScopes(session, id, userScopes) then final Set<Scope>? newScopes = await session.scopes; newScopes == [];

It would be great if I could return the updated scopes after setting them, or get the updated scopes via listener on SessionManager from client side.

@SandPod
Copy link
Contributor

SandPod commented Apr 25, 2024

Currently I'm updating the scopes after login by passing the scopes from UserInfo.scopeNames to Users.updateUserScopes(session, id, userScopes), which feels really gross.

Unfortunately, this is a consequence of the bug that this issue is targeted to fix. Once resolved, the scopes defined on the UserInfo should be set by default for any new logins for all providers and not just the email provider.

Also, after doing so, session manager listener doesn't trigger when scopes are changed by updateUserScopes, and I can't access the new scopes in the same endpoint method after changing the scopes. i.e. await Users.updateUserScopes(session, id, userScopes) then final Set? newScopes = await session.scopes; newScopes == [];

The authentication information stored in the session object is retrieved as soon as the framework or the developer makes a call to session.authenticatedUserId or session.scopes. This happens in the framework as part of the endpoint authentication system. So before the endpoint method is called this information has already been retrieved and stored in the session object.

Therefore, when you fetch the scopes through await session.scopes you will retrieve the scopes that were set for the user when it authenticated for the endpoint.

updated scopes via listener on SessionManager from client side.

Note that scopes is a server-only concept. The client only gets an authentication key that is tied to certain scopes stored on the server. The client should never be responsible for defining what scopes are granted a user as that would make it easy for a bad actor to escalate their privilage.

Best practices

We first of all need to fix the issue where scopes are not retrieved from UserInfo in all providers. Once that is done, You should override the onUserCreated method in order to configure the scopes you want for your users. This should allow you to remove the fix you currently have in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants