Appeler une API REST à l’aide de la stratégie Azure Active Directory B2C personnalisée

La stratégie personnalisée Azure Active Directory B2C (Azure AD B2C) vous permet d’interagir avec la logique d’application que vous implémentez en dehors d’Azure AD B2C. Pour ce faire, vous passez un appel HTTP à un point de terminaison. Les stratégies Azure AD B2C personnalisées fournissent un profil technique RESTful à cet effet. Grâce à cette fonctionnalité, vous pouvez implémenter des fonctionnalités qui ne sont pas disponibles dans la stratégie Azure AD B2C personnalisée.

Dans cet article, vous apprendrez comment :

  • Créez et déployez un exemple d’application Node.js pour une utilisation en tant que service RESTful.

  • Passez un appel HTTP au service Node.js RESTful à l’aide du profil technique RESTful.

  • Gérez ou signalez une erreur qu’un service RESTful retourne à votre stratégie personnalisée.

Présentation du scénario

Dans Créer une branche dans le parcours utilisateur à l’aide de stratégies Azure AD B2C personnalisées, les utilisateurs qui sélectionnent Compte personnel doivent fournir un code d’accès d’invitation valide pour continuer. Nous utilisons un code d’accès statique, mais les applications réelles ne fonctionnent pas de cette manière. Si le service qui émet les codes d’accès est externe à votre stratégie personnalisée, vous devez effectuer un appel à ce service et passer l’entrée du code d’accès par l’utilisateur pour validation. Si le code d’accès est valide, le service retourne une réponse HTTP 200 OK et Azure AD B2C émet un jeton JWT. Sinon, le service retourne une réponse HTTP 409 Conflict et l’utilisateur doit entrer à nouveau un code d’accès.

A flowchart of calling a R E S T A P I.

Prérequis

Notes

Cet article fait partie de la série de guides pratiques Créer et exécuter vos propres stratégies personnalisées dans Azure Active Directory B2C. Nous vous recommandons de commencer cette série par le premier article.

Étape 1 : création et déploiement d’une application Node.js

Vous devez déployer une application servant d’application externe. Votre stratégie personnalisée passe ensuite un appel HTTP à cette application.

Étape 1.1 : créer l’application Node.js

  1. Créez un dossier pour héberger votre application Node, par exemple access-code-app.

  2. Dans votre terminal, accédez à un répertoire dans votre dossier d’application Node, par exemple cd access-code-app, et exécutez npm init -y. Cette commande crée un fichier package.json par défaut pour votre projet Node.js.

  3. Dans votre terminal, exécutez npm install express body-parser. Cette commande installe l’infrastructure Express et le package body-parser.

  4. Créez un index.js fichier dans votre projet.

  5. Dans VS Code, ouvrez le fichier index.js, puis ajoutez le code suivant :

        const express = require('express');
        let bodyParser = require('body-parser')
        //Create an express instance
        const app = express();
    
        app.use( bodyParser.json() );       // to support JSON-encoded bodies
        app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
          extended: true
        }));
    
    
        app.post('/validate-accesscode', (req, res) => {
            let accessCode = '88888';
            if(accessCode == req.body.accessCode){
                res.status(200).send();
            }else{
                let errorResponse = {
                    "version" :"1.0",
                    "status" : 409,
                    "code" : "errorCode",
                    "requestId": "requestId",
                    "userMessage" : "The access code you entered is incorrect. Please try again.",
                    "developerMessage" : `The provided code ${req.body.accessCode} does not match the expected code for user.`,
                    "moreInfo" :"https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
                };
                res.status(409).send(errorResponse);                
            }
        });
    
        app.listen(80, () => {
            console.log(`Access code service listening on port !` + 80);
        });
    

    Vous pouvez observer que quand un utilisateur envoie un code d’accès incorrect, vous pouvez retourner une erreur directement à partir de l’API REST. Les stratégies personnalisées vous permettent de retourner un message d’erreur HTTP 4xx, tel que 400 (requête incorrecte) ou 409 (conflit) avec un corps de réponse JSON mis en forme comme indiqué dans la variable errorResponse. La source du accessCode dans l’application peut être lue à partir d’une base de données. En savoir plus sur le Renvoi d’un message d’erreur de validation.

  6. Pour tester le fonctionnement attendu de l’application, procédez comme suit :

    1. Dans votre terminal, exécutez la commande node index.js pour démarrer votre serveur d’application.
    2. Pour effectuer une requête POST similaire à celle présentée dans cet exemple, vous pouvez utiliser un client HTTP tel que Microsoft PowerShell ou Postman :
        POST http://localhost/validate-accesscode HTTP/1.1
        Host: localhost
        Content-Type: application/x-www-form-urlencoded
    
        accessCode=user-code-code
    

    Remplacez user-code-code par une entrée de code d’accès par l’utilisateur, telle que 54321. Si vous utilisez PowerShell, exécutez le script suivant.

        $accessCode="54321"
        $endpoint="http://localhost/validate-accesscode"
        $body=$accessCode
        $response=Invoke-RestMethod -Method Post -Uri $endpoint -Body $body
        echo $response
    

    Si vous utilisez un code d’accès incorrect, la réponse est semblable à l’extrait de code JSON suivant :

        {
            "version": "1.0",
            "status": 409,
            "code": "errorCode",
            "requestId": "requestId",
            "userMessage": "The access code you entered is incorrect. Please try again.",
            "developerMessage": "The provided code 54321 does not match the expected code for user.",
            "moreInfo": "https://docs.microsoft.com/en-us/azure/active-directory-b2c/string-transformations"
        }
    

À ce point, vous êtes prêt à déployer votre application Node.js.

Étape 1.2 : déployer l’application Node.js dans Azure App Service

Pour que votre stratégie personnalisée puisse contacter votre application Node.js, elle doit être accessible. Vous devez donc la déployer. Dans cet article, vous déployez l’application à l’aide d’Azure App Service, mais en utilisant une autre approche d’hébergement.

Suivez les étapes décrites dans Déployer votre application dans Azure pour déployer votre application Node.js sur Azure. Pour le Nom de l’application, utilisez un nom descriptif tel que custompolicyapi. Par conséquent :

  • L’URL de l’application ressemble à https://custompolicyapi.azurewebsites.net.

  • Le point de terminaison de service ressemble à https://custompolicyapi.azurewebsites.net/validate-accesscode.

Vous pouvez tester l’application que vous avez déployée à l’aide d’un client HTTP tel que Microsoft PowerShell ou Postman. Cette fois, utilisez l’URL https://custompolicyapi.azurewebsites.net/validate-accesscode comme point de terminaison.

Étape 2 : appeler l’API REST

Maintenant que votre application est en cours d’exécution, vous devez passer un appel HTTP à partir de votre stratégie personnalisée. La stratégie Azure AD B2C personnalisée fournit un Profil technique RESTful que vous utilisez pour appeler un service externe.

Étape 2.1 : définir un profil technique RESTful

Dans votre fichier ContosoCustomPolicy.XML, recherchez la section ClaimsProviders et définissez un nouveau profil technique RESTful à l’aide du code suivant :

    <!--<ClaimsProviders>-->
        <ClaimsProvider>
            <DisplayName>HTTP Request Technical Profiles</DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="ValidateAccessCodeViaHttp">
                    <DisplayName>Check that the user has entered a valid access code by using Claims Transformations</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.RestfulProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="ServiceUrl">https://custompolicyapi.azurewebsites.net/validate-accesscode</Item>
                        <Item Key="SendClaimsIn">Body</Item>
                        <Item Key="AuthenticationType">None</Item>
                        <Item Key="AllowInsecureAuthInProduction">true</Item>
                    </Metadata>
                    <InputClaims>
                        <InputClaim ClaimTypeReferenceId="accessCode" PartnerClaimType="accessCode" />
                    </InputClaims>
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    <!--</ClaimsProviders>-->

À partir du protocole, vous pouvez observer que nous configurons le profil technique pour utiliser RestfulProvider. Vous pouvez également observer les informations suivantes dans la section métadonnées :

  • L’élément ServiceUrl représente le point de terminaison de l’API. Sa valeur est de https://custompolicyapi.azurewebsites.net/validate-accesscode. Si vous avez déployé votre application Node.js à l’aide d’une autre méthode, veillez à mettre à jour la valeur du point de terminaison.

  • SendClaimsIn spécifie la façon dont les revendications d’entrée sont envoyées au fournisseur de revendications RESTful. Valeurs possibles : Body (default), Form, Header, Url ou QueryString. Lorsque vous utilisez Body, comme dans cet article, vous appelez le verbe HTTP POST et les données que vous envoyez à l’API, si elles sont mises en forme en tant que clés, des paires de valeurs dans le corps de la requête. Découvrez comment appeler le verbe HTTP GET et passer des données en tant que chaîne de requête.

  • AuthenticationType spécifie le type d’authentification effectué par le fournisseur de revendications RESTful. Notre fournisseur de revendications RESTful appelle un point de terminaison non protégé. Nous avons donc défini notre AuthenticationType sur Aucun. Si vous définissez le type d’authentification sur Bearer, vous devez ajouter un élément CryptographicKeys qui spécifie le stockage de votre jeton d’accès. En savoir plus sur les types d’authentification pris en charge par le fournisseur de revendications RESTful.

  • L’attribut PartnerClaimType dans le InputClaim spécifie la façon dont vous recevez vos données dans l’API.

Étape 2.2 : mettre à jour le profil technique de validation

Dans Créer une branche dans le parcours utilisateur à l’aide d’une stratégie Azure AD B2C personnalisée, vous avez validé le accessCode à l’aide d’une transformation de revendications. Dans cet article, vous validez le accessCode en passant un appel HTTP à un service externe. Vous devez donc mettre à jour votre stratégie personnalisée afin qu’elle reflète la nouvelle approche.

Recherchez le profil technique AccessCodeInputCollector et remplacez ReferenceId de l’élément ValidationTechnicalProfile par ValidateAccessCodeViaHttp :

de :

    <ValidationTechnicalProfile ReferenceId="CheckAccessCodeViaClaimsTransformationChecker"/>

à :

    <ValidationTechnicalProfile ReferenceId="ValidateAccessCodeViaHttp"/>

À ce stade, le profil technique avec IdCheckAccessCodeViaClaimsTransformationChecker n’est pas indispensable et peut être supprimé.

Étape 3 : charger un fichier de stratégie personnalisée

Vérifiez que votre application Node.js est en cours d’exécution, puis suivez les étapes décrites dans Charger un fichier de stratégie personnalisée pour charger votre fichier de stratégie. Si vous chargez un fichier portant le même nom que celui déjà présent dans le portail, veillez à sélectionner Remplacer la stratégie personnalisée si elle existe déjà.

Étape 4 : tester la stratégie personnalisée

Suivez les étapes décrites dans Tester la stratégie personnalisée pour tester votre stratégie personnalisée :

  1. Pour Type de compte, sélectionnez Compte personnel
  2. Entrez le reste des détails en fonction des besoins, puis sélectionnez Continuer. Un nouvel écran s’affiche.
  3. Pour le Code d’accès, saisissez 88888, puis sélectionnez Continuer. Une fois l’exécution de la stratégie terminée, vous êtes redirigé vers https://jwt.ms et le jeton JWT décodé s’affiche. Si vous répétez la procédure et entrez un Code d’accès autre que 88888, une erreur s’affiche : Le code d’accès que vous avez entré est incorrect. Réessayez.

Étape 5 : activez le mode débogage

Dans le développement, vous souhaiterez peut-être voir les erreurs détaillées envoyées par l’API, telles que developerMessage et moreInfo. Dans ce cas, vous devez activer le mode débogage dans votre fournisseur technique RESTful.

  1. Localisez votre fournisseur technique ValidateAccessCodeViaHttp et ajoutez l’élément suivant dans le fournisseur technique metadata :

        <Item Key="DebugMode">true</Item>
    
  2. Enregistrez les modifications et chargez votre fichier de stratégie.

  3. Testez votre stratégie personnalisée. Veillez à utiliser une entrée incorrecte pour votre Code d’accès. Une erreur similaire à celle de cette capture d’écran s’affiche :

    A screenshot error when you enable debug mode.

Gérer des charges utiles JSON d’une requête complexe

Si l’API REST appelée vous oblige à envoyer une charge utile JSON complexe, vous pouvez créer la charge utile à l’aide des Transformations de revendications JSON GenerateJson. Une fois la charge utile générée, vous pouvez utiliser l’option ClaimUsedForRequestPayloadmétadonnéee pour le nom de la revendication contenant la charge utile JSON.

Par exemple, utilisez la transformation de revendications suivante pour générer une charge utile JSON :

    <ClaimsTransformation Id="GenerateRequestBodyClaimsTransformation" TransformationMethod="GenerateJson">
        <InputClaims>
            <InputClaim ClaimTypeReferenceId="email" TransformationClaimType="customerEntity.email" />
            <InputClaim ClaimTypeReferenceId="objectId" TransformationClaimType="customerEntity.userObjectId" />
            <InputClaim ClaimTypeReferenceId="givenName" TransformationClaimType="customerEntity.firstName" />
            <InputClaim ClaimTypeReferenceId="surname" TransformationClaimType="customerEntity.lastName" />
            <InputClaim ClaimTypeReferenceId="accessCode" TransformationClaimType="customerEntity.accessCode" />
        </InputClaims>
        <InputParameters>
            <InputParameter Id="customerEntity.role.name" DataType="string" Value="Administrator" />
            <InputParameter Id="customerEntity.role.id" DataType="long" Value="1" />
        </InputParameters>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="requestBodyPayload" TransformationClaimType="outputClaim" />
        </OutputClaims>
    </ClaimsTransformation>

ClaimsTransformation génère l’objet JSON suivant :

{
   "customerEntity":{
      "email":"john.s@contoso.com",
      "userObjectId":"01234567-89ab-cdef-0123-456789abcdef",
      "firstName":"John",
      "lastName":"Smith",
      "accessCode":"88888",
      "role":{
         "name":"Administrator",
         "id": 1
      }
   }
}

Ensuite, mettez à jour les éléments Métadonnées, InputClaimsTransformations et InputClaims de votre fournisseur technique RESTful, comme indiqué ci-dessous :

    <Metadata>
        <Item Key="ClaimUsedForRequestPayload">requestBodyPayload</Item>
        <!--Other Metadata items -->
    </Metadata>
    
    <!--Execute your InputClaimsTransformations to generate your request Payload-->
    <InputClaimsTransformations>
        <InputClaimsTransformation ReferenceId="GenerateRequestBodyClaimsTransformation" />
    </InputClaimsTransformations>
    
    <InputClaims>
        <InputClaim ClaimTypeReferenceId="requestBodyPayload" />
    </InputClaims>

Recevoir des données à partir de l’API REST

Si votre API REST renvoie des données que vous souhaitez inclure en tant que revendications dans votre stratégie, vous pouvez les recevoir en spécifiant des revendications dans l’élément OutputClaims du profil technique RESTful. Si le nom de la revendication définie dans votre stratégie est différent du nom défini dans l’API REST, vous devez mapper ces noms à l’aide de l’attribut PartnerClaimType.

Suivez les étapes décrites dans la section Réception de données pour découvrir comment mettre en forme les données attendues par la stratégie personnalisée, comment gérer les valeurs NULL et comment analyser via REST le corps JSON imbriqué de l’API.

Étapes suivantes

Découvrez ensuite :