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: Refresh Token Flow Not Working After Updating Roles #32

Open
2 tasks
anshpreet3101 opened this issue Sep 26, 2024 · 8 comments
Open
2 tasks

bug: Refresh Token Flow Not Working After Updating Roles #32

anshpreet3101 opened this issue Sep 26, 2024 · 8 comments
Labels
invalid This doesn't seem right

Comments

@anshpreet3101
Copy link

Describe the bug

I am using the management API to update the roles of a user. The roles get updated successfully on the server. However, when I refresh the token to get the updated roles using getRefreshToken() method , the roles in the token remain the same as before. Only the expiry time is updated, while the roles and other data remain unchanged.

Expected behavior

The new token should reflect the updated roles from the authentication server.
Roles Updates when user redo the browser based signIn process.

How to reproduce?

  • Authenticate a user using Logto in an Expo application.
  • Change the user's roles on the authentication server using Logto Management API.
  • Refresh the token in the Expo application using getRefreshToken().

Context

  • Logto Cloud
  • Self-hosted, Logto version = 1.2.0
    • Container (Docker image)
  • Raw Node.js
@anshpreet3101 anshpreet3101 added the bug Something isn't working label Sep 26, 2024
@pratibha3011
Copy link

pratibha3011 commented Oct 14, 2024

+1

@charIeszhao @gao-sun @simeng-li can you please check this?

@simeng-li
Copy link
Contributor

For any newly assigned roles or permissions, the user must re-authenticate again to pick up the latest changes.

@simeng-li simeng-li added invalid This doesn't seem right and removed bug Something isn't working labels Nov 1, 2024
@pratibha3011
Copy link

For any newly assigned roles or permissions, the user must re-authenticate again to pick up the latest changes.

Thanks for the response @simeng-li .
My application is using logto in a react-native app. When a logged in user subscribes in my app, asking them to logout and login is not good user experience. None of the apps, do this. after subscription, we need to provide benefits in the same session. benefits are driven by the roles/permissions in user token.

This is a blocker for us. We will need to find an alternative if this is the case. what do you suggest @simeng-li ?

@simeng-li
Copy link
Contributor

simeng-li commented Dec 19, 2024

Hi, apologize for the late response.

In the OAuth 2.0 standard, if a user is assigned a new role or permission, the client must resend an authorization request to the authorization server to obtain a refreshed access token with the updated scopes. As an alternative, you can try the Organization Roles and Permissions instead of user permission. Organization permission updates does not require a re-authorization from the user.

@charIeszhao
Copy link
Member

My application is using logto in a react-native app. When a logged in user subscribes in my app, asking them to logout and login is not good user experience

Hi, I think there is a misunderstanding in the context. I'm sorry if we may sound implying a re-login, that indeed a bad user experience. However, performing a "re-authentication" action does not always mean "logout and re-login". To be precise, it actually is a "/auth" request, with all the necessary information (e.g. grant_type, scopes, resources, etc.).

If you are still looking for a solution with pure user RBAC, you can do this whenever the user is assigned with a new role (with new scopes).

signIn({ redirectUri: 'your-redirect-uri', prompt: 'consent' });

Check the documentation for more details.

We call this a "re-consent" action, which returns new user scopes in the new access token. And from the end user point of view, doing this feels nothing but a page refresh.

In conclusion, we have 2 solutions for your use case.

  • Suggested by Simeng earlier, using organization RBAC. This is recommended as it requires less hussle.
  • Use the "re-consent" action to trigger a new "/auth" request

@yashlohia123
Copy link

yashlohia123 commented Jan 29, 2025

In the OAuth 2.0 standard, if a user is assigned a new role or permission, the client must resend an authorization request to the authorization server to obtain a refreshed access token with the updated scopes. As an alternative, you can try the Organization Roles and Permissions instead of user permission. Organization permission updates does not require a re-authorization from the user.
@charIeszhao @simeng-li

Greetings,
As suggested by you,
I tried organization roles and permissions and tested them on react native sample app provided by logto and logto SDK. But still I am required to reauthenticate via the browser in order to reflect the updated roles in the token.

Steps to recreate:

  1. First I created organization roles and assigned permissions to those roles.
  2. Then I added one member (E.g. John) to the organization and assigned a default organization role.
  3. Then I build and opened the sample app in android emulator.
  4. When I inspected the token after signing up with the member John then the default organization role was visible in the token.
  5. Then from the logto console I added more organization roles to that particular member John.
  6. Then when I reopened the app (without reauthenticating) the new roles were not reflected into the token.
  7. When I sign out a blank browser window opened and only then I was able to see the updated roles in the token.

Although I am able to get updated roles when I authenticate but I want to update the roles without going to the browser.

I also tried this approach
signIn({ redirectUri: 'your-redirect-url', prompt: 'consent' });
but this also redirects to the browser window to update the roles.

I recreated all these steps for the web sample app, then I was able to view the update roles in the token without the need of reauthentication. The issue is with react native mobile app.

This is my current JWT configuration

const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
  const user = context.user;
  let permissions = [];
  const roles = user.roles.map(role =>{
    role?.scopes.map(scope=>{
      permissions.push(scope?.name);
    })
    return role.name;
  })
  const organizationRoles = user.organizationRoles.map(role =>{
    return role.roleName;
  })
  return  {
    email: user.primaryEmail,
    roles,
    organizationRoles: organizationRoles,
    permissions,
    username: user.primaryEmail,
  };
}

@charIeszhao
Copy link
Member

In the OAuth 2.0 standard, if a user is assigned a new role or permission, the client must resend an authorization request to the authorization server to obtain a refreshed access token with the updated scopes. As an alternative, you can try the Organization Roles and Permissions instead of user permission. Organization permission updates does not require a re-authorization from the user.
@charIeszhao @simeng-li

Greetings,
As suggested by you,
I tried organization roles and permissions and tested them on react native sample app provided by logto and logto SDK. But still I am required to reauthenticate via the browser in order to reflect the updated roles in the token.

Steps to recreate:

  1. First I created organization roles and assigned permissions to those roles.
  2. Then I added one member (E.g. John) to the organization and assigned a default organization role.
  3. Then I build and opened the sample app in android emulator.
  4. When I inspected the token after signing up with the member John then the default organization role was visible in the token.
  5. Then from the logto console I added more organization roles to that particular member John.
  6. Then when I reopened the app (without reauthenticating) the new roles were not reflected into the token.
  7. When I sign out a blank browser window opened and only then I was able to see the updated roles in the token.

Although I am able to get updated roles when I authenticate but I want to update the roles without going to the browser.

I also tried this approach
signIn({ redirectUri: 'your-redirect-url', prompt: 'consent' });
but this also redirects to the browser window to update the roles.

I recreated all these steps for the web sample app, then I was able to view the update roles in the token without the need of reauthentication. The issue is with react native mobile app.

This is my current JWT configuration

const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
  const user = context.user;
  let permissions = [];
  const roles = user.roles.map(role =>{
    role?.scopes.map(scope=>{
      permissions.push(scope?.name);
    })
    return role.name;
  })
  const organizationRoles = user.organizationRoles.map(role =>{
    return role.roleName;
  })
  return  {
    email: user.primaryEmail,
    roles,
    organizationRoles: organizationRoles,
    permissions,
    username: user.primaryEmail,
  };
}

Have you tried clear all cache access tokens and request a new one in step 6?

@yashlohia123
Copy link

yashlohia123 commented Jan 29, 2025

@charIeszhao
I called these methods one by one

  • getRefreshToken()
  • getAccessToken()
  • getAccessTokenClaims()
  • getOrganizationToken()
  • getOrganizationTokenClaims()
  • getIdTokenClaims()

None of the above methods were returning the JWT with updated roles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Development

No branches or pull requests

5 participants