Aracılığıyla paylaş


Azure Active Directory B2C kullanarak kendi Node.js web API'nizde kimlik doğrulamasını etkinleştirme

Önemli

1 Mayıs 2025 tarihinden itibaren Azure AD B2C artık yeni müşteriler için satın alınamayacak. SSS bölümünden daha fazla bilgi edinebilirsiniz.

Bu makalede, web API'nizi çağıran web uygulamanızı oluşturmayı öğreneceksiniz. Web API'sinin Azure Active Directory B2C (Azure AD B2C) tarafından korunması gerekir. Web API'sine erişimi yetkilendirmek için, Azure AD B2C tarafından verilen geçerli bir erişim belirteci içeren istekler sağlarsınız.

Önkoşullar

1. Adım: Korumalı web API'si oluşturma

Node.js web API'nizi oluşturmak için bu adımları izleyin.

1.1. Adım: Projeyi oluşturma

Web API oluşturmak için Node.js sürümüyle Express kullanın. Web API'sini oluşturmak için aşağıdakileri yapın:

  1. TodoList adlı yeni bir klasör oluşturun.
  2. klasörünün TodoList altında adlı index.jsbir dosya oluşturun.
  3. Komut kabuğunda npm init -y komutunu çalıştırın. Bu komut, Node.js projeniz için varsayılan bir package.json dosyası oluşturur.
  4. Komut kabuğunda npm install express komutunu çalıştırın. Bu komut Express çerçevesini yükler.

1.2. Adım: Bağımlılıkları yükleme

Kimlik doğrulama kitaplığını web API'niz projesine ekleyin. Kimlik doğrulama kitaplığı HTTP kimlik doğrulama üst bilgisini ayrıştırıyor, belirteci doğrular ve talepleri ayıklar. Daha fazla bilgi için kitaplığın belgelerini gözden geçirin.

Kimlik doğrulama kitaplığını eklemek için aşağıdaki komutu çalıştırarak paketleri yükleyin:

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

Morgan paketi, Node.jsiçin bir HTTP istek günlükçü ara yazılımıdır.

1.3. Adım: Web API'sinin sunucu kodunu yazma

index.js Dosyasına aşağıdaki kodu ekleyin:

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);
});

index.jsdosyasındaki aşağıdaki kod parçacıklarını kaydedin.

  • Microsoft Entra Passport kitaplığını içeri aktarır

    const BearerStrategy = require('passport-azure-ad').BearerStrategy;
    
  • Azure AD B2C seçeneklerini ayarlar

    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
    }
    
  • Azure AD B2C seçenekleriyle Passport Microsoft Entra kitaplığının örneğini oluşturma

    const bearerStrategy = new BearerStrategy(options, (token, done) => {
            // Send user info using the second argument
            done(null, { }, token);
        }
    );
    
  • Korumalı API uç noktası. Geçerli bir Azure AD B2C tarafından verilen erişim belirteci içeren istekler sağlar. Bu uç nokta, erişim belirteci içindeki talebin değerini name döndürür.

    // 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']});
        }
    );
    
  • Anonim API uç noktası. Web uygulaması erişim belirteci sunmadan bunu çağırabilir. Anonim çağrılarla web API'nizde hata ayıklamak için bu api'yi kullanın.

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

1.4. Adım: Web API'sini yapılandırma

Yapılandırma dosyasına yapılandırmalar ekleyin. Dosya, Azure AD B2C kimlik sağlayıcınız hakkında bilgi içerir. Web API uygulaması, web uygulamasının taşıyıcı belirteç olarak geçirdiği erişim belirtecini doğrulamak için bu bilgileri kullanır.

  1. Proje kök klasörünün altında bir config.json dosya oluşturun ve ardından aşağıdaki JSON nesnesini ekleyin:

    {
        "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. config.json Dosyasında aşağıdaki özellikleri güncelleştirin:

Bölüm Anahtar Değer
kimlik bilgileri kiracıAdı Azure AD B2C kiracı adınızın ilk bölümü (örneğin, fabrikamb2c).
kimlik bilgileri müşteriKimliği Web API'si uygulama kimliği. Web API'si uygulama kayıt kimliğinizi nasıl alacağınızı öğrenmek için bkz. Önkoşullar.
Politikalar politikaAdı Kullanıcı akışları ya da özel politika. Kullanıcı akışınızı veya ilkenizi nasıl edineceğinizi öğrenmek için bkz. Önkoşullar.
kaynak kapsam [tasks.read] gibi web API uygulama kaydınızın kapsamları. Web API'nizin kapsamını almayı öğrenmek için bkz. Önkoşullar.

2. Adım: Web Node web uygulamasını oluşturma

Node web uygulamasını oluşturmak için bu adımları izleyin. Bu web uygulaması, 1. adımda oluşturduğunuz Node web API'sini çağırmak için kullanılan erişim belirtecini almak için kullanıcının kimliğini doğrular:

Adım 2.1: Node.js projesini oluşturun

Düğüm uygulamanızı tutmak için gibi call-protected-apibir klasör oluşturun.

  1. Terminalinizde, cd call-protected-api gibi düğüm uygulama klasörünüze gidin ve npm init -y komutunu çalıştırın. Bu komut, Node.js projeniz için varsayılan bir package.json dosyası oluşturur.

  2. Terminalinizde npm install express komutunu çalıştırın. Bu komut Express çerçevesini yükler.

  3. Aşağıdaki proje yapısını elde etmek için daha fazla klasör ve dosya oluşturun:

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

    Klasör, views web uygulamasının kullanıcı arabirimi için handlebars dosyalarını içerir.

2.2. Adım: Bağımlılıkları yükleme

Terminalinizde, dotenv, express-handlebars, express-session ve @azure/msal-node paketlerini aşağıdaki komutları çalıştırarak yükleyin.

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

2.3. Adım: Web uygulaması kullanıcı arabirimi bileşenleri oluşturma

  1. main.hbs Dosyasına aşağıdaki kodu ekleyin:

    <!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>
    

    Dosya main.hbs klasördedir layout ve uygulamanız genelinde gerekli olan tüm HTML kodlarını içermelidir. Bootstrap 5 CSS Framework ile oluşturulmuş kullanıcı arabirimini uygular. Sayfadan sayfaya signin.hbs gibi değişen herhangi bir kullanıcı arabirimi, gösterilen yer tutucuya {{{body}}} yerine yerleştirilir.

  2. signin.hbs Dosyasına aşağıdaki kodu ekleyin:

    <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. api.hbs Dosyasına aşağıdaki kodu ekleyin:

    <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>
    

    Bu sayfada API'den gelen yanıt görüntülenir. bg-{{bg_color}} Bootstrap'ın kartındaki sınıf özniteliği, kullanıcı arabiriminin farklı API uç noktaları için farklı bir arka plan rengi görüntülemesini sağlar.

2.4. Adım: Web uygulaması sunucu kodunu tamamlama

  1. Dosyaya .env sunucu http bağlantı noktası, uygulama kayıt ayrıntıları ve oturum açıp kullanıcı akışı/ilke ayrıntılarını içeren aşağıdaki kodu ekleyin:

    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
    

    .env bölümünde açıklandığı gibi dosyalardaki değerleri değiştirme

  2. Dosyanıza index.js aşağıdaki kodu ekleyin:

    /*
     * 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));
    

    Dosyadaki index.js kod genel değişkenlerden ve hızlı yollardan oluşur.

    Genel değişkenler:

    • confidentialClientConfig: Gizli istemci uygulama nesnesini oluşturmak için kullanılan MSAL yapılandırma nesnesi.

      /**
       * 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: Web API'de yapılandırılmış ve web uygulamasına verilen kapsamları içeren webApiScopes özelliğini (değeri bir dizi olmalıdır) içerir. Ayrıca çağrılmak üzere web API'sinin URI'leri de vardır; yani anonymousUri ve protectedUri.

      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: İstekte bulunan ve belirteç yanıtında da döndürülen bir değer. Azure AD B2C'den alınan yanıtlar arasında ayrım yapmak için kullanılır.

    • authCodeRequest: Yetkilendirme kodunu almak için kullanılan yapılandırma nesnesi.

    • tokenRequest: Yetkilendirme koduyla belirteç almak için kullanılan yapılandırma nesnesi.

    • sessionConfig: Hızlı oturum için yapılandırma nesnesi.

    • getAuthCode: Kullanıcının uygulamaya kimlik bilgileri girip onay vermesine izin veren yetkilendirme isteğinin URL'sini oluşturan bir yöntem. getAuthCodeUrl sınıfında tanımlanan yöntemini kullanır.

    Ekspres güzergahlar:

    • /:
      • Bu, web uygulamasına giriş ve signin sayfasını görüntüler.
    • /signin:
      • Kullanıcıda oturum açar.
      • getAuthCode() metodunu çağırır ve authority kullanıcı akışı/ilkesine , APP_STATES.LOGIN, ve apiConfig.webApiScopes aktarır.
      • Bu, son kullanıcının oturum açma bilgilerini girmesinin zorlanması veya kullanıcının bir hesabı yoksa kaydolabilmesine neden olur.
      • Bu uç noktadan elde edilen son yanıt, yetkilendirme kodunun /redirect uç noktasına B2C tarafından gönderildiğini içerir.
    • /redirect:
      • Azure portalında web uygulaması için Yeniden Yönlendirme URI'si olarak ayarlanan uç noktadır.
      • Web uygulamasından state yapılan istekler arasında ayrım yapmak için Azure AD B2C'nin yanıtında sorgu parametresini kullanır.
      • Uygulama durumu APP_STATES.LOGIN olduğunda, acquireTokenByCode() yöntemi kullanılarak bir belirteç almak için alınan yetkilendirme kodu kullanılır. yöntemini kullanarak acquireTokenByCode belirteç isteğinde bulunurken, yetkilendirme kodunu alırken kullanılan kapsamların aynısını kullanırsınız. Alınan belirteç bir accessToken, idTokenve idTokenClaimsiçerir. accessToken oluşturduktan sonra, daha sonra web API'sini çağırmak üzere kullanmak için bir oturumda saklarsınız.
    • /api:
      • Web API'sini çağırır.
      • accessToken oturumunda değilse anonim API uç noktasını ()http://localhost:5000/public çağırın, aksi takdirde korumalı API uç noktasını ()http://localhost:5000/hello çağırın.
    • /signout:
      • Kullanıcının oturumunu kapatın.
      • Web uygulaması oturumunu temizler ve ardından Azure AD B2C oturum kapatma uç noktasına bir HTTP çağrısı yapar.

3. Adım: Web uygulamasını ve API'yi çalıştırma

Web uygulamanızı ve web API'nizi test etmek için Web uygulamasını ve API'yi çalıştırma'daki adımları izleyin.

Sonraki Adımlar