How to get scopes in access token

Hi, we are migrating from Rules to Actions.
I understand we can add/remove scope by api.accessToken.addScope() and api.accessToken.removeScope().

Is there is a way to list existing scopes in accessToken? We need to remove scope on Post Login but need to know what’s already in there.

Hello @andy.cui1 welcome to the community!

You should be able to get these with event.transaction.requested_scopes of the Event object.

console.log(event.transaction.requested_scopes);

Gives me “undefined”

1 Like

How about:

 if (event.authorization) {
  console.log(event.transaction.requested_scopes);
 }

Same, it still print out undefined

1 Like

Hmm, that’s odd - Are you able to print out event.transaction? What type of login flow are you using in particular?

event.transaction is { protocol: 'oauth2-password' }
I am making POST request to /oauth/token endpoint with client_id, client_secret, audience, grant_type=http://auth0.com/oauth/grant-type/password-realm, username, password and realm
Not sure what is the name of this type.

Ah, thanks for clarifying!

Because you’re using a password grant type, scopes won’t be accessible in event.transaction.requested_scopes as scope filtering is not done for ROPG grant types. Instead you’ll need to get scopes from the body of the request, something like:

const reqeustedScopesArray = event.request.body.scope?.split(" ")
1 Like

This is still undefined.

I’d like to provide more context on my use case.
I am migrating Auth0 Rules to Actions. One of the current rule is assigning scopes in accessToken
context.accessToken.scope = ["some-scopes"];
In Actions, there is no assignment, I can only add or remove scopes. So I just add the ones I want to the accessToken
api.accessToken.addScope("a"); apt.accessToken.addScope("b");
But the final access toke contains a lot more than I added in Actions. Seems like some of them are pre-populated into the access token scope.

So I need to clean up before running my api.accessToken.addScope(); But couldn’t find a way to do that.

2 Likes

Gotcha, thanks for clarifying!

Do you know where these scopes are coming from? AFAIK using a password grant and omitting the scopes param in the request results in an access token with no scopes at all. The only way I can access scopes in an Action is if I add them to the request as outlined here.

The scopes are all permissions defined in the API. But I have no idea where they come from. I tried turn off all custom rules and Actions. (just leave the default auth0-authorization-extension rule). But the scopes are still in the access token.

1 Like

Perhaps they are being added in the authorization extension itself?

It is pretty much the default. I don’t see it adding any scope in it.

function (user, context, callback) {
  var _ = require('lodash');
  var EXTENSION_URL = "OUR_INSTANCE_URL";

  var audience = '';
  audience = audience || (context.request && context.request.query && context.request.query.audience);
  if (audience === 'urn:auth0-authz-api') {
    return callback(new UnauthorizedError('no_end_users'));
  }

  audience = audience || (context.request && context.request.body && context.request.body.audience);
  if (audience === 'urn:auth0-authz-api') {
    return callback(new UnauthorizedError('no_end_users'));
  }

  getPolicy(user, context, function(err, res, data) {
    if (err) {
      console.log('Error from Authorization Extension:', err);
      return callback(new UnauthorizedError('Authorization Extension: ' + err.message));
    }

    if (res.statusCode !== 200) {
      console.log('Error from Authorization Extension:', res.body || res.statusCode);
      return callback(
        new UnauthorizedError('Authorization Extension: ' + ((res.body && (res.body.message || res.body) || res.statusCode)))
      );
    }

    // Update the user object.

    // Store this in the user profile (app_metadata).
    saveToMetadata(user, data.groups, data.roles, data.permissions, function(err) {
      return callback(err, user, context);
    });
  });
  
  // Convert groups to array
  function parseGroups(data) {
    if (typeof data === 'string') {
      // split groups represented as string by spaces and/or comma
      return data.replace(/,/g, ' ').replace(/\s+/g, ' ').split(' ');
    }
    return data;
  }

  // Get the policy for the user.
  function getPolicy(user, context, cb) {
    request.post({
      url: EXTENSION_URL + "/api/users/" + user.user_id + "/policy/" + context.clientID,
      headers: {
        "x-api-key": configuration.AUTHZ_EXT_API_KEY
      },
      json: {
        connectionName: context.connection || user.identities[0].connection,
        groups: parseGroups(user.groups)
      },
      timeout: 5000
    }, cb);
  }

  // Store authorization data in the user profile so we can query it later.
  function saveToMetadata(user, groups, roles, permissions, cb) {
    user.app_metadata = user.app_metadata || {};
    user.app_metadata.authorization = {
      groups: groups,
      roles: roles,
      permissions: permissions
    };

    auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
    .then(function() {
      cb();
    })
    .catch(function(err){
      cb(err);
    });
  }
}

Do you mind DMing me the tenant you are testing with as well as an example access token payload decoded at jwt.io?

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.