Partager via


Activer l’authentification dans votre propre API web Node.js à l’aide d’Azure Active Directory B2C

Important

À compter du 1er mai 2025, Azure AD B2C ne sera plus disponible pour les nouveaux clients. Pour plus d’informations, consultez notre FAQ.

Dans cet article, vous allez apprendre à créer votre application web qui appelle votre API web. L’API web doit être protégée par Azure Active Directory B2C (Azure AD B2C). Pour autoriser l’accès à l’API web, vous répondez aux demandes qui incluent un jeton d’accès valide émis par Azure AD B2C.

Conditions préalables

  • Avant de lire et de suivre les étapes, configurez l'authentification dans un exemple d'API web Node.js à l'aide d'Azure AD B2C. Suivez ensuite les étapes décrites dans cet article pour remplacer l’exemple d’application web et l’API web par votre propre API web.

  • Visual Studio Code ou un autre éditeur de code

  • Environnement d'exécution Node.js

Étape 1 : Créer une API web protégée

Suivez ces étapes pour créer votre API web Node.js.

Étape 1.1 : Créer le projet

Utilisez Express pour Node.js pour créer une API web. Pour créer une API web, procédez comme suit :

  1. Créez un dossier appelé TodoList.
  2. Sous le TodoList dossier, créez un fichier nommé index.js.
  3. Dans un interpréteur de commandes, exécutez npm init -y. Cette commande crée un fichier package.json par défaut pour votre projet Node.js.
  4. Dans l’interpréteur de commandes, exécutez npm install express. Cette commande installe l’infrastructure Express.

Étape 1.2 : Installer les dépendances

Ajoutez la bibliothèque d’authentification à votre projet d’API web. La bibliothèque d’authentification analyse l’en-tête d’authentification HTTP, valide le jeton et extrait les revendications. Pour plus d’informations, consultez la documentation de la bibliothèque.

Pour ajouter la bibliothèque d’authentification, installez les packages en exécutant la commande suivante :

npm install passport
npm install passport-azure-ad
npm install morgan

Le package morgan est un middleware de journalisation des requêtes HTTP pour Node.js.

Étape 1.3 : Écrire le code du serveur d’API web

Dans le index.js fichier, ajoutez le code suivant :

const express = require('express');
const morgan = require('morgan');
const passport = require('passport');
const config = require('./config.json');
const todolist = require('./todolist');
const cors = require('cors');

//<ms_docref_import_azuread_lib>
const BearerStrategy = require('passport-azure-ad').BearerStrategy;
//</ms_docref_import_azuread_lib>

global.global_todos = [];

//<ms_docref_azureadb2c_options>
const options = {
    identityMetadata: `https://${config.credentials.tenantName}.b2clogin.com/${config.credentials.tenantName}.onmicrosoft.com/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`,
    clientID: config.credentials.clientID,
    audience: config.credentials.clientID,
    policyName: config.policies.policyName,
    isB2C: config.settings.isB2C,
    validateIssuer: config.settings.validateIssuer,
    loggingLevel: config.settings.loggingLevel,
    passReqToCallback: config.settings.passReqToCallback
}

//</ms_docref_azureadb2c_options>

//<ms_docref_init_azuread_lib>
const bearerStrategy = new BearerStrategy(options, (token, done) => {
        // Send user info using the second argument
        done(null, { }, token);
    }
);
//</ms_docref_init_azuread_lib>
const app = express();

app.use(express.json()); 

//enable CORS (for testing only -remove in production/deployment)
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Authorization, Origin, X-Requested-With, Content-Type, Accept');
    next();
});

app.use(morgan('dev'));

app.use(passport.initialize());

passport.use(bearerStrategy);

// To do list endpoints
app.use('/api/todolist', todolist);

//<ms_docref_protected_api_endpoint>
// API endpoint, one must present a bearer accessToken to access this endpoint
app.get('/hello',
    passport.authenticate('oauth-bearer', {session: false}),
    (req, res) => {
        console.log('Validated claims: ', req.authInfo);
    
          
        // Service relies on the name claim.  
        res.status(200).json({'name': req.authInfo['name']});
    }
);
//</ms_docref_protected_api_endpoint>

//<ms_docref_anonymous_api_endpoint>
// API anonymous endpoint, returns a date to the caller.
app.get('/public', (req, res) => res.send( {'date': new Date() } ));
//</ms_docref_anonymous_api_endpoint>

const port = process.env.PORT || 5000;

app.listen(port, () => {
    console.log('Listening on port ' + port);
});

Notez les extraits de code suivants dans le index.jsfichier :

  • Importe la bibliothèque de Microsoft Entra de passeport

    const BearerStrategy = require('passport-azure-ad').BearerStrategy;
    
  • Définit les options Azure AD B2C

    const options = {
        identityMetadata: `https://${config.credentials.tenantName}.b2clogin.com/${config.credentials.tenantName}.onmicrosoft.com/${config.policies.policyName}/${config.metadata.version}/${config.metadata.discovery}`,
        clientID: config.credentials.clientID,
        audience: config.credentials.clientID,
        policyName: config.policies.policyName,
        isB2C: config.settings.isB2C,
        validateIssuer: config.settings.validateIssuer,
        loggingLevel: config.settings.loggingLevel,
        passReqToCallback: config.settings.passReqToCallback
    }
    
  • Instancie la bibliothèque Microsoft Entra de passeport avec les options Azure AD B2C

    const bearerStrategy = new BearerStrategy(options, (token, done) => {
            // Send user info using the second argument
            done(null, { }, token);
        }
    );
    
  • Point de terminaison d’API protégé. Il traite les demandes qui incluent un jeton d’accès émis par Azure AD B2C valide. il retourne la valeur de la revendication name dans le jeton d’accès.

    // API endpoint, one must present a bearer accessToken to access this endpoint
    app.get('/hello',
        passport.authenticate('oauth-bearer', {session: false}),
        (req, res) => {
            console.log('Validated claims: ', req.authInfo);
        
              
            // Service relies on the name claim.  
            res.status(200).json({'name': req.authInfo['name']});
        }
    );
    
  • Point de terminaison d’API anonyme. L’application web peut l’appeler sans présenter de jeton d’accès. Utilisez-le pour déboguer votre API web avec des appels anonymes.

    // API anonymous endpoint, returns a date to the caller.
    app.get('/public', (req, res) => res.send( {'date': new Date() } ));
    

Étape 1.4 : Configurer l’API web

Ajoutez des configurations à un fichier de configuration. Le fichier contient des informations sur votre fournisseur d’identité Azure AD B2C. L'application API web utilise ces informations pour valider le jeton d'accès que l'application web transmet comme jeton porteur.

  1. Sous le dossier racine du projet, créez un config.json fichier, puis ajoutez-le à l’objet JSON suivant :

    {
        "credentials": {
            "tenantName": "fabrikamb2c",
            "clientID": "Enter_the_Application_Id_Here"
        },
        "policies": {
            "policyName": "B2C_1_susi"
        },
        "resource": {
            "scope": ["tasks.read"]
        },
        "metadata": {
            "authority": "login.microsoftonline.com",
            "discovery": ".well-known/openid-configuration",
            "version": "v2.0"
        },
        "settings": {
            "isB2C": true,
            "validateIssuer": true,
            "passReqToCallback": false,
            "loggingLevel": "info"
        }
    }
    
  2. Dans le config.json fichier, mettez à jour les propriétés suivantes :

Section Clé Valeur
informations d’identification nom du locataire Première partie de votre nom de client Azure AD B2C (par exemple, fabrikamb2c).
informations d’identification identifiant du client ID d’application de l’API web. Pour savoir comment obtenir votre ID d’inscription d’application d’API web, consultez Conditions préalables.
politiques nom_stratégie Les parcours utilisateur ou une stratégie personnalisée. Pour savoir comment obtenir votre flux d’utilisateur ou votre stratégie, consultez Conditions préalables.
ressource portée Étendues de l’inscription de votre application API web (par exemple, [tasks.read]). Pour savoir comment obtenir l’étendue de votre API web, consultez Conditions préalables.

Étape 2 : Créer l’application web Node web

Procédez comme suit pour créer l’application web Node. Cette application web authentifie un utilisateur pour acquérir un jeton d’accès utilisé pour appeler l’API web Node que vous avez créée à l’étape 1 :

Étape 2.1 : Créer le projet de nœud

Créez un dossier pour contenir votre application Node.js, comme call-protected-api.

  1. Dans votre terminal, remplacez le répertoire par votre dossier d’application de nœud, par cd call-protected-apiexemple, et exécutez npm init -y. Cette commande crée un fichier package.json par défaut pour votre projet Node.js.

  2. Dans votre terminal, exécutez npm install express. Cette commande installe l’infrastructure Express.

  3. Créez d’autres dossiers et fichiers pour obtenir la structure de projet suivante :

    call-protected-api/
    ├── index.js
    └── package.json
    └── .env
    └── views/
        └── layouts/
            └── main.hbs
        └── signin.hbs
        └── api.hbs
    

    Le views dossier contient des fichiers handlebars pour l’interface utilisateur de l’application web.

Étape 2.2 : Installer les dépendances

Dans votre terminal, installez les paquets dotenv, express-handlebars, express-session et @azure/msal-node en exécutant les commandes suivantes :

npm install dotenv
npm install express-handlebars
npm install express
npm install axios
npm install express-session
npm install @azure/msal-node

Étape 2.3 : Créer des composants d’interface utilisateur d’application web

  1. Dans le main.hbs fichier, ajoutez le code suivant :

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
        <title>Azure AD B2C | Enable authenticate on web API using MSAL for B2C</title>
    
        <!-- adding Bootstrap 4 for UI components  -->
        <!-- CSS only -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
        <link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
      </head>
      <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
          <a class="navbar-brand" href="/">Microsoft Identity Platform</a>
            {{#if showSignInButton}}
                <div class="ml-auto">
                    <a type="button" id="SignIn" class="btn btn-success" href="/signin" aria-haspopup="true" aria-expanded="false">
                        Sign in to call PROTECTED API
                    </a>
                    <a type="button" id="SignIn" class="btn btn-warning" href="/api" aria-haspopup="true" aria-expanded="false">
                        Or call the ANONYMOUS API 
                     </a>
                </div>
            {{else}}
                    <p class="navbar-brand d-flex ms-auto">Hi {{givenName}}</p>
                    <a class="navbar-brand d-flex ms-auto" href="/signout">Sign out</a>
            {{/if}}
        </nav>
        <br>
        <h5 class="card-header text-center">MSAL Node Confidential Client application with Auth Code Flow</h5>
        <br>
        <div class="row" style="margin:auto" >
          {{{body}}}
        </div>
        <br>
        <br>
      </body>
    </html>
    

    Le main.hbs fichier se trouve dans le layout dossier et doit contenir tout code HTML requis dans l’ensemble de votre application. Il implémente l’interface utilisateur générée avec l’infrastructure CSS Bootstrap 5. Toute interface utilisateur qui passe de la page à la page, telle que signin.hbs, est placée dans l’espace réservé affiché comme {{{body}}}.

  2. Dans le signin.hbs fichier, ajoutez le code suivant :

    <div class="col-md-3" style="margin:auto">
      <div class="card text-center">
        <div class="card-body">
          {{#if showSignInButton}}
    
          {{else}}
               <h5 class="card-title">You have signed in</h5>
              <a type="button" id="Call-api" class="btn btn-success" href="/api" aria-haspopup="true" aria-expanded="false">
                  Call the PROTECTED API
              </a>
          {{/if}}
        </div>
        </div>
      </div>
    </div>
    
  3. Dans le api.hbs fichier, ajoutez le code suivant :

    <div class="col-md-3" style="margin:auto">
      <div class="card text-center bg-{{bg_color}}">
        <div class="card-body">
    
              <h5 class="card-title">{{data}}</h5>
    
        </div>
      </div>
    </div>
    

    Cette page affiche la réponse de l’API. L’attribut bg-{{bg_color}} de classe dans la carte bootstrap permet à l’interface utilisateur d’afficher une couleur d’arrière-plan différente pour les différents points de terminaison d’API.

Étape 2.4 : Code complet du serveur d’applications web

  1. Dans le fichier .env, ajoutez le code suivant, qui inclut le port http du serveur, les informations d’enregistrement de l’application, ainsi que les détails des flux utilisateur/de la politique de connexion et d'inscription.

    SERVER_PORT=3000
    #web apps client ID
    APP_CLIENT_ID=<You app client ID here>
    #session secret
    SESSION_SECRET=sessionSecretHere
    #web app client secret
    APP_CLIENT_SECRET=<Your app client secret here>
    #tenant name
    TENANT_NAME=<your-tenant-name>
    #B2C sign up and sign in user flow/policy name and authority
    SIGN_UP_SIGN_IN_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name>
    AUTHORITY_DOMAIN=https://<your-tenant-name>.b2clogin.com
    #client redorect url
    APP_REDIRECT_URI=http://localhost:3000/redirect
    LOGOUT_ENDPOINT=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name>/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000
    

    Modifier les valeurs dans les .env fichiers, comme expliqué dans Configurer l’exemple d’application web

  2. Dans votre index.js fichier, ajoutez le code suivant :

    /*
     * Copyright (c) Microsoft Corporation. All rights reserved.
     * Licensed under the MIT License.
     */
    require('dotenv').config();
    const express = require('express');
    const session = require('express-session');
    const {engine}  = require('express-handlebars');
    const msal = require('@azure/msal-node');
    //Use axios to make http calls 
    const axios = require('axios');
    
    //<ms_docref_configure_msal>
    /**
     * Confidential Client Application Configuration
     */
     const confidentialClientConfig = {
        auth: {
            clientId: process.env.APP_CLIENT_ID, 
            authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, 
            clientSecret: process.env.APP_CLIENT_SECRET,
            knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array
            redirectUri: process.env.APP_REDIRECT_URI,
            validateAuthority: false
        },
        system: {
            loggerOptions: {
                loggerCallback(loglevel, message, containsPii) {
                    console.log(message);
                },
                piiLoggingEnabled: false,
                logLevel: msal.LogLevel.Verbose,
            }
        }
    };
    
    // Initialize MSAL Node
    const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);
    //</ms_docref_configure_msal>
    // Current web API coordinates were pre-registered in a B2C tenant.
    
    //<ms_docref_api_config>
    const apiConfig = {
        webApiScopes: [`https://${process.env.TENANT_NAME}.onmicrosoft.com/tasks-api/tasks.read`],
        anonymousUri: 'http://localhost:5000/public',
        protectedUri: 'http://localhost:5000/hello'
    };
    //</ms_docref_api_config>
    
    /**
     * The MSAL.js library allows you to pass your custom state as state parameter in the Request object
     * By default, MSAL.js passes a randomly generated unique state parameter value in the authentication requests.
     * The state parameter can also be used to encode information of the app's state before redirect. 
     * You can pass the user's state in the app, such as the page or view they were on, as input to this parameter.
     * For more information, visit: https://docs.microsoft.com/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request
     */
    const APP_STATES = {
        LOGIN: 'login',
        CALL_API:'call_api'   
    }
    
    
    /** 
     * Request Configuration
     * We manipulate these two request objects below 
     * to acquire a token with the appropriate claims.
     */
     const authCodeRequest = {
        redirectUri: confidentialClientConfig.auth.redirectUri,
    };
    
    const tokenRequest = {
        redirectUri: confidentialClientConfig.auth.redirectUri,
    };
    
    
    /**
     * Using express-session middleware. Be sure to familiarize yourself with available options
     * and set them as desired. Visit: https://www.npmjs.com/package/express-session
     */
     const sessionConfig = {
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: {
            secure: false, // set this to true on production
        }
    }
    //Create an express instance
    const app = express();
    
    //Set handlebars as your view engine
    app.engine('.hbs', engine({extname: '.hbs'}));
    app.set('view engine', '.hbs');
    app.set("views", "./views");
    
    app.use(session(sessionConfig));
    
    /**
     * This method is used to generate an auth code request
     * @param {string} authority: the authority to request the auth code from 
     * @param {array} scopes: scopes to request the auth code for 
     * @param {string} state: state of the application, tag a request
     * @param {Object} res: express middleware response object
     */
    
     const getAuthCode = (authority, scopes, state, res) => {
        // prepare the request
        console.log("Fetching Authorization code")
        authCodeRequest.authority = authority;
        authCodeRequest.scopes = scopes;
        authCodeRequest.state = state;
    
        //Each time you fetch Authorization code, update the authority in the tokenRequest configuration
        tokenRequest.authority = authority;
    
        // request an authorization code to exchange for a token
        return confidentialClientApplication.getAuthCodeUrl(authCodeRequest)
            .then((response) => {
                console.log("\nAuthCodeURL: \n" + response);
                //redirect to the auth code URL/send code to 
                res.redirect(response);
            })
            .catch((error) => {
                res.status(500).send(error);
            });
    }
    
    app.get('/', (req, res) => {
        res.render('signin', { showSignInButton: true });
    });
    
    
    
    app.get('/signin',(req, res)=>{ 
            //Initiate a Auth Code Flow >> for sign in
            //Pass the api scopes as well so that you received both the IdToken and accessToken
            getAuthCode(process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY,apiConfig.webApiScopes, APP_STATES.LOGIN, res);
    });
    
    
    app.get('/redirect',(req, res)=>{    
        
        if (req.query.state === APP_STATES.LOGIN) {
            // prepare the request for calling the web API
            tokenRequest.authority = process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY;
            tokenRequest.scopes = apiConfig.webApiScopes;
            tokenRequest.code = req.query.code;
            confidentialClientApplication.acquireTokenByCode(tokenRequest)
            .then((response) => {
                req.session.accessToken = response.accessToken;
                req.session.givenName = response.idTokenClaims.given_name;
                console.log('\nAccessToken:' + req.session.accessToken);
                res.render('signin', {showSignInButton: false, givenName: response.idTokenClaims.given_name});
            }).catch((error) => {
                console.log(error);
                res.status(500).send(error);
            });
        }else{
            res.status(500).send('We do not recognize this response!');
        }
    });
    
    //<ms_docref_api_express_route>
    app.get('/api', async (req, res) => {
        if(!req.session.accessToken){
            //User is not logged in and so they can only call the anonymous API
            try {
                const response = await axios.get(apiConfig.anonymousUri);
                console.log('API response' + response.data); 
                res.render('api',{data: JSON.stringify(response.data), showSignInButton: true, bg_color:'warning'});
            } catch (error) {
                console.error(error);
                res.status(500).send(error);
            }         
        }else{
            //Users have the accessToken because they signed in and the accessToken is still in the session
            console.log('\nAccessToken:' + req.session.accessToken);
            let accessToken = req.session.accessToken;
            const options = {
                headers: {
                    //accessToken used as bearer token to call a protected API
                    Authorization: `Bearer ${accessToken}`
                }
            };
    
            try {
                const response = await axios.get(apiConfig.protectedUri, options);
                console.log('API response' + response.data); 
                res.render('api',{data: JSON.stringify(response.data), showSignInButton: false, bg_color:'success', givenName: req.session.givenName});
            } catch (error) {
                console.error(error);
                res.status(500).send(error);
            }
        }     
    });
    
    //</ms_docref_api_express_route>
    
    /**
     * Sign out end point
    */
    app.get('/signout',async (req, res)=>{    
        logoutUri = process.env.LOGOUT_ENDPOINT;
        req.session.destroy(() => {
            res.redirect(logoutUri);
        });
    });
    app.listen(process.env.SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on port !` + process.env.SERVER_PORT));
    

    Le code du index.js fichier se compose de variables globales et d’itinéraires express.

    Variables globales :

    • confidentialClientConfig: objet de configuration MSAL, utilisé pour créer l’objet d’application cliente confidentielle.

      /**
       * Confidential Client Application Configuration
       */
       const confidentialClientConfig = {
          auth: {
              clientId: process.env.APP_CLIENT_ID, 
              authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, 
              clientSecret: process.env.APP_CLIENT_SECRET,
              knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array
              redirectUri: process.env.APP_REDIRECT_URI,
              validateAuthority: false
          },
          system: {
              loggerOptions: {
                  loggerCallback(loglevel, message, containsPii) {
                      console.log(message);
                  },
                  piiLoggingEnabled: false,
                  logLevel: msal.LogLevel.Verbose,
              }
          }
      };
      
      // Initialize MSAL Node
      const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);
      
    • apiConfig: Contient la propriété webApiScopes (il doit s’agir d’un tableau), correspondant aux étendues configurées dans l’API web et accordées à l’application web. Il a également des URI vers l’API web à appeler, c’est-à-dire anonymousUriprotectedUri.

      const apiConfig = {
          webApiScopes: [`https://${process.env.TENANT_NAME}.onmicrosoft.com/tasks-api/tasks.read`],
          anonymousUri: 'http://localhost:5000/public',
          protectedUri: 'http://localhost:5000/hello'
      };
      
    • APP_STATES: valeur incluse dans la requête qui est également retournée dans la réponse du jeton. Permet de différencier les réponses reçues d’Azure AD B2C.

    • authCodeRequest: objet de configuration utilisé pour récupérer le code d’autorisation.

    • tokenRequest: objet de configuration utilisé pour acquérir un jeton par code d’autorisation.

    • sessionConfig: objet de configuration pour la session express.

    • getAuthCode: méthode qui crée l’URL de la demande d’autorisation, permettant à l’utilisateur d’entrer les informations d’identification et de donner son consentement à l’application. Elle utilise la getAuthCodeUrl méthode, qui est définie dans la classe ConfidentialClientApplication .

    Itinéraires express :

    • /:
      • Il s’agit de l’entrée de l’application web et affiche la signin page.
    • /signin:
      • Connecte l’utilisateur.
      • Appelle la méthode getAuthCode() et transmet le authority pour le flux/la stratégie utilisateur Connexion et inscription, APP_STATES.LOGIN et apiConfig.webApiScopes à celui-ci.
      • Cela incite l'utilisateur final à saisir ses identifiants ou, si l'utilisateur n'a pas de compte, il peut s'inscrire.
      • La réponse finale résultant de ce point de terminaison inclut un code d’autorisation de B2C retourné au point de terminaison /redirect.
    • /redirect:
      • Il s’agit du point de terminaison défini comme URI de redirection pour l’application web dans le portail Azure.
      • Il utilise le paramètre de requête dans la state réponse d’Azure AD B2C pour différencier les requêtes effectuées à partir de l’application web.
      • Si l’état de l’application est APP_STATES.LOGIN, le code d’autorisation acquis est utilisé pour récupérer un jeton à l’aide de la acquireTokenByCode() méthode. Quand vous demandez un jeton à l’aide de la méthode acquireTokenByCode, vous utilisez les mêmes étendues que celles utilisées lors de l’acquisition du code d’autorisation. Le jeton acquis comprend accessToken, idToken et idTokenClaims. Une fois que vous avez acquis le accessToken, vous le placez dans une session pour l'utiliser ultérieurement afin d'appeler l'API web.
    • /api:
      • Appelle l’API web.
      • Si le accessToken n’est pas dans la session, appelez le point de terminaison d’API anonyme (http://localhost:5000/publicsinon, appelez le point de terminaison d’API protégé (http://localhost:5000/hello).
    • /signout:
      • Déconnecte l’utilisateur.
      • supprime la session de l'application web et effectue un appel HTTP au point de terminaison de déconnexion d'Azure AD B2C.

Étape 3 : Exécuter l’application web et l’API

Suivez les étapes décrites dans Exécuter l’application web et l’API pour tester votre application web et votre API web.

Étapes suivantes