Échange d’identifiants clients

Au point d’extensibilité Échange d’identifiants clients, les Hooks vous permettent d’exécuter des actions personnalisées lorsqu’un jeton d’accès est émis via le point de terminaisonPOST /oauth/token de l’Authentication API à l’aide du flux des identifiants client. Par exemple, vous pouvez refuser l’émission du jeton, ajouter des demandes personnalisées au jeton d’accès ou modifier ses permissions. Pour en savoir plus, consulter Flux des identifiants client.

Les Hooks à ce point d’extensibilité sont bloquants (synchrones), ce qui signifie qu’ils s’exécutent dans le cadre du processus du déclencheur et empêchent le reste du pipeline Auth0 de s’exécuter jusqu’à ce que le hook soit terminé.

Code de départ et paramètres

Lors de la création d’un hook exécuté au point d’extensibilité Échange d’identifiants clients, le code de départ suivant peut s’avérer utile. Les paramètres qui peuvent être transmis et utilisés par la fonction Hook sont énumérés en haut de l’exemple de code.

/**
@param {object} client - client information
@param {string} client.name - client name
@param {string} client.id - client ID
@param {string} client.tenant - Auth0 tenant name
@param {object} client.metadata - client metadata
@param {array|undefined} scope - either an array of strings representing the token's scope claim, or undefined
@param {string} audience - token's audience claim
@param {object} context - Auth0 context info
@param {object} context.webtask - Hook (webtask) context
@param {function} cb - function (error, accessTokenClaims)
*/

module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token.scope = scope; // do not remove this line

  // Modify scopes or add extra claims
  // access_token['https://example.com/claim'] = 'bar';
  // access_token.scope.push('extra');

  // Deny the token and respond with an OAuth2 error response
  // if (denyExchange) {
  //   // To return an HTTP 400 with { "error": "invalid_scope", "error_description": "Not authorized for this scope." }
  //   return cb(new InvalidScopeError('Not authorized for this scope.'));
  //
  //   // To return an HTTP 400 with { "error": "invalid_request", "error_description": "Not a valid request." }
  //   return cb(new InvalidRequestError('Not a valid request.'));
  //
  //   // To return an HTTP 500 with { "error": "server_error", "error_description": "A server error occurred." }
  //   return cb(new ServerError('A server error occurred.'));
  // }

  cb(null, access_token);
};

Was this helpful?

/

Remarque :

  • La fonction de rappel (cb) à la fin de l’exemple de code signale l’achèvement et doit être incluse.

  • La ligne access_token.scope = scope garantit que toutes les permissions accordées seront présentes dans le jeton d’accès. Si vous la supprimez, toutes les permissions seront réinitialisées et le jeton n’inclura que les permissions que vous aurez ajoutés avec le script.

Réponse par défaut

Lorsque vous exécutez un hook au point d’extensibilité Échange d’identifiants clients, l’objet de réponse par défaut est :

{
  "scope": "array of strings"
}

Was this helpful?

/

Réponse du code de départ

Une fois que vous avez personnalisé le code de départ avec vos permissions et vos demandes supplémentaires, vous pouvez tester le hook à l’aide du programme d’exécution intégré à Éditeur de hook. Le programme d’exécution simule un hook avec le même corps et la même réponse que vous obtiendriez avec un Échange d’identifiants clients.

Lorsque vous exécutez un hook basé sur le code de départ, l’objet de réponse est :

{
  "audience": "https://my-tenant.auth0.com/api/v2/",
  "client": {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "client-name",
    "tenant": "my-tenant",
    "metadata": {
      "plan": "full"
    }
  },
  "scope": [
    "read:connections"
  ]
}

Was this helpful?

/

Exemple de script : Ajouter une permission supplémentaire au jeton d’accès

Dans cet exemple, nous utilisons un hook pour ajouter une permission supplémentaire à celles qui existent déjà pour le jeton d’accès.

module.exports = function(client, scope, audience, context, cb) {
    // Scopes to be added
    var access_token = {};

    // Get the scope that's currently on the Access Token
    // and add it to the object we're working with
    // Do not remove this line!
    access_token.scope = scope;

    // Append the `read:resource` scope
    access_token.scope.push('read:resource');

    // Callback to indicate completion and to return new
    // array of scopes
    cb(null, access_token);
};

Was this helpful?

/

Pour en savoir plus, consulter Permissions.

Réponse

Lorsque nous exécutons ce hook, l’objet de réponse est :

{
  "scope": [
    "read:connections",
    "read:resource"
  ]
}

Was this helpful?

/

Exemple de script : Ajouter une demande au jeton d’accès

Dans cet exemple, nous ajoutons une demande personnalisée avec espace de noms et sa valeur au jeton d’accès. Pour en savoir plus, consulter Créer des demandes personnalisées avec espace de noms.

Vous pouvez ajouter les éléments suivants en tant que demandes au jeton émis :

  • La propriété scope de l’objet de réponse

  • Toutes les propriétés avec des noms de propriété avec espace de noms

Le point d’extensibilité ignore toutes les autres propriétés de l’objet de réponse.

module.exports = function(client, scope, audience, context, cb) {
    // Claims to be added
    var access_token = {};

    // New claim to add to the token
    access_token['https://example.com/foo'] = 'bar';

    // Callback to indicate completion and to return new claim
    cb(null, access_token);
  };

Was this helpful?

/

Réponse

Lorsque nous exécutons ce hook, l’objet de réponse est :

{
  "https://example.com/foo": "bar"
}

Was this helpful?

/

Exemple de script : Générer une erreur ou refuser un jeton d’accès

Dans cet exemple, nous utilisons des objets erreur personnalisés pour générer des réponses d’erreur OAuth2. (Pour en savoir plus, consultez OAuth2 RFC - Section 5.2 dans le Datatracker de l’IETF).

Si une erreur JavaScript simple est renvoyée dans le rappel, comme par exemple :

module.exports = function(client, scope, audience, context, cb) {
    // Callback to indicate completion and to return new claim
    cb(new Error("Unknown error occurred.");
  };

Was this helpful?

/

Ensuite, lorsque vous demandez une autorisation client_credentials à partir du point de terminaison /oauth/token, Auth0 répondra par :

HTTP 500
{ "error": "server_error", "error_description": "Unknown error occurred." }

Was this helpful?

/

Toutefois, si vous souhaitez exercer un contrôle supplémentaire sur la réponse d’erreur OAuth2, vous pouvez utiliser trois objets erreur personnalisés.

InvalidScopeError

module.exports = function(client, scope, audience, context, cb) {
    const invalidScope = ...; // determine if scope is valid

    if(invalidScope) {
      cb(new InvalidScopeError("Scope is not permitted."));
    }
  };

Was this helpful?

/

Ainsi, lorsque vous demandez une autorisation client_credentials à partir du point de terminaison /oauth/token, Auth0 répond par :

HTTP 400
{ "error": "invalid_scope", "error_description": "Scope is not permitted." }

Was this helpful?

/

InvalidRequestError

module.exports = function(client, scope, audience, context, cb) {
    const invalidRequest = ...; // determine if request is valid

    if(invalidRequest) {
      cb(new InvalidRequestError("Bad request."));
    }
  };

Was this helpful?

/

Ensuite, lorsque vous demandez une autorisation client_credentials à partir du point de terminaison /oauth/token, Auth0 répondra par :

HTTP 400
{ "error": "invalid_request", "error_description": "Bad request." }

Was this helpful?

/

ServerError

module.exports = function(client, scope, audience, context, cb) {
    callOtherService(function(err, response) {
      if(err) {
        return cb(new ServerError("Error calling remote system: " + err.message));
      }
    });
  };

Was this helpful?

/

Lorsque vous demandez une autorisation client_credentials à partir du point de terminaison /oauth/token, Auth0 répond par :

HTTP 400
{ "error": "server_error", "error_description": "Error calling remote system: ..." }

Was this helpful?

/

En savoir plus