Assigning roles for first login accross two rules

Hi,

we have a rule in order to assign roles for a user that logs in for the first time. In a second rule we add these roles to the token.

First rule for first login, based upon implementation Assign Roles to users using Rules:

function (user, context, callback) {

  var count = context.stats && context.stats.loginsCount ? context.stats.loginsCount : 0;
  if (count > 1) {
    return callback(null, user, context);
  }

  var ManagementClient = require('auth0@2.17.0').ManagementClient;
  var management = new ManagementClient({
    token: auth0.accessToken,
    domain: auth0.domain
  });

  management.assignRolestoUser(
    { id : user.user_id}, 
    { "roles" :["rol_123456789"]},  // sample role ID of "Standard API Enduser"
    function (err) {
      if (err) {
        console.log('Error assigning role: ' + err);
      }    
      callback(null, user, context);
  });

The second rule assigns these roles to the token, based upon implementation Add user roles to tokens:

function (user, context, callback) {
  const namespace = 'http://demozero.net';
  const assignedRoles = (context.authorization || {}).roles;

  let idTokenClaims = context.idToken || {};
  let accessTokenClaims = context.accessToken || {};

  idTokenClaims[`${namespace}/roles`] = assignedRoles;
  accessTokenClaims[`${namespace}/roles`] = assignedRoles;

  context.idToken = idTokenClaims;
  context.accessToken = accessTokenClaims;

  callback(null, user, context);
}

We have observed, that in case of a first login, the role gets assigned by the ManagementClient successfully via the first rule. However, the context object is not updated for the second rule. Due to this, the assigned role from the first rule is missing in the token.

However, if the user logs in a second time, the role is available. Therefore, I would like to ask, whether it is an intended design of the rules-flow not to update the context object between the processing of several rules?

Best regards
Luuk

1 Like

We have solved it via the first rule by adding the role also in the context:

let assignedRoles = (context.authorization || {}).roles;
assignedRoles.push('myrole123456789');

Hi Luuk,

Thank you so much for sharing your code above. I ran in the same situation as you and used the first rule to assign a default role when the count is to 1.

But there’s still something I don’t get and I believe you solved this issue by reading your post on June 20.

I have three rules that run when a user logs in:

  1. Assign default role if this is a new user
  2. Fetch the roles of the user
  3. Fetch the permissions of the user

I would have thought that once I assign a role with rule 1, it would get put in the user and its context in rule 2. Looking at my logs, it doesn’t seem like it.

You say that you added the following lines of code in rule 1:

let assignedRoles = (context.authorization || {}).roles;
assignedRoles.push(‘myrole123456789’);

Where exactly did you put this in rule 1?

Hi @lpcarignan

Nice to talk to you again.
An easier workaround is to use silent auth to get an access token again.
The second time around it will have the roles.

John

1 Like

Thanks for the hint @john.gateley

As I’m using the auth0/auth0-react package in my React SPA project, are you aware of any way of doing this with this library?

I’ve read the article Configure silent authentication and it seems to indicate the use of parameter prompt=none for a silent authentication on a GET request.

As my library auth0-react has probably abstracted those GET calls underneath, are you aware if I can use this parameter, prompt=none, in loginWithRedirect from the auth0/react library?

Or is there another way to do a silent auth in a React SPA? I’ve searched the community forums but most of the posts around this topic are 1 year old and have just a question without any follow-ups.

Hey Louis,

See this page: Auth0 React SDK for Single Page Apps
And the getTokenSilently function

John

Thank you for your input, this solution sounds interesting, could you please tell me where you implemented this solution? directely in the rule 1?

Tagging @luuk.de.ville for visibility

1 Like

I ran into this issue as well. Although I see @luuk.de.ville’s workaround, there’s still no answer to the question is it a bug or it’s working as intended? For me it seems first because of simple fact. I have three rules:

  1. Assign extra info to user.app_metadata
  2. According to that info initialize user roles, the same as OP did.
  3. Grab info from user.app_metadata and context.authorization and put it into idToken.

All of this seems to match official guides. On the first login I have information from user.app_metadata updated during rules flow and I’m getting it in idToken, but not getting updated context.authorization.roles. Both app_metadata and roles updated by calls via auth0 client.

@konrad.sopala @john.gateley ?

Re get token again: I understand this is workaround as well but IMO it’s not good as it forces client application to change to cover this gap in rules flow. First workaround works solely on rules flow.

I got this working. Just make sure its before any callback(null, user, context). Also, I had to use the actual role rather than the role id.

1 Like

Perfect! Glad to hear that! Thanks for sharing it with the rest of community!