使用 Azure AD B2C 在範例單頁應用程式中設定驗證

本文使用範例 JavaScript 單頁應用程式 (SPA) 來說明如何將 Azure Active Directory B2C (Azure AD B2C) 驗證新增至您的 SPA。

概觀

OpenID 連線 (OIDC) 是以 OAuth 2.0 為基礎的驗證通訊協定。 您可以使用它安全地將使用者登入應用程式。 此 SPA 範例會使用 MSAL.js 和 OIDC PKCE 流程。 MSAL.js 是 Microsoft 提供的程式庫,可簡化將驗證和授權支援新增至 SPA。

登入流程

登入流程牽涉到下列步驟:

  1. 使用者移至 Web 應用程式,然後選取 [登入 ]。
  2. 應用程式會起始驗證要求,並將使用者重新導向至 Azure AD B2C。
  3. 使用者 註冊或登入 重設密碼 。 或者,他們可以使用社交帳戶 登入
  4. 使用者登入之後,Azure AD B2C 會將授權碼傳回應用程式。
  5. 單頁應用程式會驗證識別碼權杖、讀取宣告,然後讓使用者呼叫受保護的資源和 API。

應用程式註冊概觀

若要讓應用程式能夠使用 Azure AD B2C 登入並呼叫 Web API,請在 Azure AD B2C 目錄中註冊兩個應用程式。

  • Web 應用程式註冊可讓您的應用程式 使用 Azure AD B2C 登入。 在註冊期間,您可以指定 重新導向 URI 。 重新導向 URI 是完成 Azure AD B2C 驗證之後,Azure AD B2C 將使用者重新導向的端點。 應用程式註冊程式會產生應用程式識別碼 ,也稱為 用戶端識別碼 ,可唯一 識別您的應用程式。

  • Web API 註冊可讓您的應用程式呼叫安全的 Web API。 註冊包含 Web API 範圍 。 範圍提供管理受保護資源許可權的方法,例如您的 Web API。 您會將 Web 應用程式許可權授與 Web API 範圍。 要求存取權杖時,您的應用程式會在要求的範圍參數中指定所需的許可權。

下圖說明應用程式架構和註冊:

Diagram of a web app with web API call registrations and tokens.

呼叫 Web API

驗證完成後,使用者會與叫用受保護 Web API 的應用程式互動。 Web API 使用 持有人權杖 驗證。 持有人權杖是應用程式從 Azure AD B2C 取得的存取權杖。 應用程式會在 HTTPS 要求的授權標頭中傳遞權杖。

Authorization: Bearer <access token>

如果存取權杖的範圍不符合 Web API 的範圍,驗證程式庫會取得具有正確範圍的新存取權杖。

登出流程

登出流程牽涉到下列步驟:

  1. 從應用程式,使用者登出。
  2. 應用程式會清除其會話物件,而驗證程式庫會清除其權杖快取。
  3. 應用程式會將使用者帶往 Azure AD B2C 登出端點,以終止 Azure AD B2C 會話。
  4. 系統會將使用者重新導向回應用程式。

必要條件

正在執行的電腦:

步驟 1:設定您的使用者流程

當使用者嘗試登入您的應用程式時,應用程式會透過使用者流程 啟動授權端點的 驗證要求。 使用者流程會定義和控制使用者體驗。 使用者完成使用者流程之後,Azure AD B2C 會產生權杖,然後將使用者重新導向回您的應用程式。

如果您尚未這麼做, 請建立使用者流程或自訂原則 。 重複這些步驟以建立三個不同的使用者流程,如下所示:

  • 合併登入 和註冊 使用者流程,例如 susi 。 此使用者流程也支援 忘記密碼 體驗。
  • 設定檔編輯 使用者流程,例如 edit_profile
  • 密碼重設 使用者流程,例如 reset_password

Azure AD B2C 前面加上 B2C_1_ 使用者流程名稱。 例如,susi 會成為 B2C_1_susi

步驟 2:註冊 SPA 和 API

在此步驟中,您會建立 SPA 和 Web API 應用程式註冊,並指定 Web API 的範圍。

步驟 2.1:註冊 Web API 應用程式

若要建立 Web API 應用程式註冊( 應用程式識別碼:2 ),請遵循下列步驟:

  1. 登入 Azure 入口網站

  2. 請確定您使用的是包含 Azure AD B2C 租使用者的目錄。 在入口網站工具列中選取 [ 目錄 + 訂用帳戶 ] 圖示。

  3. 在入口 網站設定 |[目錄 + 訂用帳戶 ] 頁面,在 [ 目錄名稱 ] 清單中尋找您的 Azure AD B2C 目錄,然後選取 [ 切換 ]。

  4. 在 Azure 入口網站中,搜尋並選取 [Azure AD B2C]

  5. 選取 [應用程式註冊],然後選取 [新增註冊]

  6. 針對 [ 名稱 ],輸入應用程式的名稱(例如 my-api1 )。 保留 [重新導向 URI] 和 [支援的帳戶類型 ] 的預設值

  7. 選取註冊

  8. 完成應用程式註冊之後,請選取 [ 概觀 ]。

  9. 記錄應用程式 (client) 識別碼 值,以供稍後在設定 Web 應用程式時使用。

    Screenshot that demonstrates how to get a web A P I application I D.

步驟 2.2:設定範圍

  1. 選取您建立的 my-api1 應用程式( 應用程式識別碼:2 )以開啟其 [概 ] 頁面。

  2. 在 [管理] 底下 ,選取 [ 公開 API ]。

  3. 在 [ 應用程式識別碼 URI] 旁,選取 [ 設定 ] 連結。 以唯一名稱取代預設值 ( GUID),然後選取 [ 儲存 ]。

    當您的 Web 應用程式要求 Web API 的存取權杖時,它應該新增此 URI 作為您為 API 定義之每個範圍的前置詞。

  4. 在此 API 定義的 [範圍] 下 ,選取 [ 新增範圍 ]。

  5. 若要建立定義 API 讀取存取權的範圍:

    1. 針對 [範圍名稱 ],輸入 tasks.read
    2. 如需 管理員同意顯示名稱 ,請輸入 工作 API 的讀取權限。
    3. 針對 管理員同意描述 ,輸入 [允許讀取工作 API ]。
  6. 選取新增範圍

  7. 選取 [新增範圍 ],然後新增定義 API 寫入權限的範圍:

    1. 針對 [範圍名稱 ],輸入 tasks.write
    2. 針對 管理員同意顯示名稱 ,輸入 工作 API 的寫入存取權。
    3. 針對 管理員同意描述 ,輸入 [允許寫入工作 API ]。
  8. 選取新增範圍

步驟 2.3:註冊 SPA

若要建立 SPA 註冊,請使用下列步驟:

  1. 登入 Azure 入口網站
  2. 如果您有多個租使用者的存取權,請選取 頂端功能表中的 [設定 ] 圖示,從 [目錄 + 訂 用帳戶] 功能表切換至您的 Azure AD B2C 租使用者。
  3. 搜尋並選取 Azure AD B2C
  4. 選取 [應用程式註冊],然後選取 [新增註冊]
  5. 輸入應用程式的 [名稱 ] (例如 MyApp )。
  6. 在 [支援的帳戶類型] 下,選取 [任何身分識別提供者或組織目錄中的帳戶 (用於運用使用者流程來驗證使用者)]
  7. 在 [重新導向 URI] 下 ,選取 [單頁應用程式], 然後在 [URL] 方塊中輸入 http://localhost:6420
  8. [許可權] 底下,選取 [ 授與系統管理員同意以開啟識別碼和離線存取權限] 核取方塊。
  9. 選取註冊

當您設定 Web 應用程式時,請記錄應用程式(用戶端)識別碼 以供稍後使用。

Screenshot of the web app Overview page for recording your web application ID.

步驟 2.4:啟用隱含授與流程

在您自己的環境中,如果您的 SPA 應用程式使用 MSAL.js 1.3 或更早版本和隱含授與流程,或設定 https://jwt.ms/ 應用程式以測試使用者流程或自訂原則,則必須在應用程式註冊中啟用隱含授與流程:

  1. 在左側功能表中,於 [管理]下,選取 [驗證]

  2. 在 [隱含授與和混合式流程] 下,選取 [存取權杖 (用於隱含流程)] 和 [識別碼權杖 (用於隱含和混合式流程)] 核取方塊。

  3. 選取 [儲存]。

如果您的應用程式使用 MSAL.js 2.0 或更新版本,請勿啟用隱含流程授與,因為 MSAL.js 2.0+ 支援 PKCE 的授權碼流程。 本文中的 SPA 應用程式會使用 PKCE 流程,因此您不需要啟用隱含授與流程。

步驟 2.5:授與許可權

若要授與您的應用程式 ( 應用程式識別碼: 1 ) 許可權,請遵循下列步驟:

  1. 選取 [應用程式註冊 ],然後選取您建立的應用程式( 應用程式識別碼:1 )。

  2. 在 [管理] 底下 ,選取 [API 許可權 ]。

  3. 在 [設定的許可權 ] 底下 ,選取 [ 新增許可權 ]。

  4. 選取 [ 我的 API] 索引卷 標。

  5. 選取應授與 Web 應用程式存取權的 API ( 應用程式識別碼:2 )。 例如,輸入 my-api1

  6. [許可權] 展開工作 ,然後選取您稍早定義的範圍(例如 tasks.read tasks.write )。

  7. 選取新增權限

  8. 選取 [ 授與管理員同意] 以取得 <租用戶名稱>

  9. 選取 [是] 。

  10. 選取 [重新整理],然後確認 [已授與...] 出現在這兩個範圍的 [狀態] 底下

  11. 從 [ 設定的許可權] 清單中,選取您的範圍,然後複製範圍完整名稱。

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

步驟 3:取得 SPA 範例程式代碼

此範例示範單頁應用程式如何使用 Azure AD B2C 進行用戶註冊和登入。 然後應用程式會取得存取令牌,並呼叫受保護的 Web API。

若要取得 SPA 範例程式代碼,您可以執行下列其中一項:

  • 下載 zip 檔案

  • 執行下列命令,從 GitHub 複製範例:

    git clone https://github.com/Azure-Samples/ms-identity-b2c-javascript-spa.git
    

步驟 3.1:更新 SPA 範例

既然您已取得 SPA 範例,請使用您的 Azure AD B2C 和 Web API 值來更新程式碼。 在範例資料夾的資料夾中, App 開啟下表所列的JavaScript檔案,然後使用對應的值加以更新。

檔案 機碼
authConfig.js clientId 步驟 2.3 中的 SPA 識別符。
policies.js 名稱 您在步驟 1建立的使用者流程或自定義原則。
policies.js 當局 您的 Azure AD B2C 使用者流程或自訂原則授權單位,例如 https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<your-sign-in-sign-up-policy>。 將 取代 your-sign-in-sign-up-policy 為您在步驟 1 中 建立的使用者流程或自定義原則
policies.js authorityDomain 您的 Azure AD B2C 授權單位網域,例如 <your-tenant-name>.b2clogin.com
apiConfig.js b2cScopes 您在步驟 2.2 中建立的 Web API 範圍(例如 , b2cScopes: ["https://<your-tenant-name>.onmicrosoft.com/tasks-api/tasks.read"]
apiConfig.js webApi Web API 的 URL, http://localhost:5000/hello

產生的程式代碼看起來應該類似下列範例:

authConfig.js

const msalConfig = {
    auth: {
      clientId: "<your-MyApp-application-ID>", // This is the ONLY mandatory field; everything else is optional.
      authority: b2cPolicies.authorities.signUpSignIn.authority, // Choose sign-up/sign-in user-flow as your default.
      knownAuthorities: [b2cPolicies.authorityDomain], // You must identify your tenant's domain as a known authority.
      redirectUri: "http://localhost:6420", // You must register this URI on Azure Portal/App Registration. Defaults to "window.location.href".
    },
    cache: {
      cacheLocation: "sessionStorage",  
      storeAuthStateInCookie: false, 
    },
    system: {
      loggerOptions: {
        loggerCallback: (level, message, containsPii) => {
          if (containsPii) {
            return;
          }
          switch (level) {
            case msal.LogLevel.Error:
              console.error(message);
              return;
            case msal.LogLevel.Info:
              console.info(message);
              return;
            case msal.LogLevel.Verbose:
              console.debug(message);
              return;
            case msal.LogLevel.Warning:
              console.warn(message);
              return;
          }
        }
      }
    }
  };
};

const loginRequest = {
  scopes: ["openid", ...apiConfig.b2cScopes],
};

const tokenRequest = {
  scopes: [...apiConfig.b2cScopes],  // e.g. ["https://fabrikamb2c.onmicrosoft.com/helloapi/demo.read"]
  forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

policies.js

const b2cPolicies = {
    names: {
        signUpSignIn: "b2c_1_susi",
        forgotPassword: "b2c_1_reset",
        editProfile: "b2c_1_edit_profile"
    },
    authorities: {
        signUpSignIn: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi",
        },
        forgotPassword: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_reset",
        },
        editProfile: {
            authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile"
        }
    },
    authorityDomain: "your-tenant-name.b2clogin.com"
}

apiConfig.js

const apiConfig = {
  b2cScopes: ["https://your-tenant-name.onmicrosoft.com/tasks-api/tasks.read"],
  webApi: "http://localhost:5000/hello"
};

步驟 4:取得 Web API 範例程式代碼

現在 Web API 已註冊,而且您已定義其範圍,請將 Web API 程式代碼設定為與您的 Azure AD B2C 租使用者搭配使用。

若要取得 Web API 範例程式代碼,請執行下列其中一項:

步驟 4.1:更新 Web API

  1. 在程式 代碼編輯器中開啟 config.json 檔案。

  2. 使用您稍早建立的應用程式註冊來修改變量值。 並將 更新 policyName 為您建立為必要條件一部分的使用者流程(例如, b2c_1_susi)。

    "credentials": {
        "tenantName": "<your-tenant-name>",
        "clientID": "<your-webapi-application-ID>"
    },
    "policies": {
        "policyName": "b2c_1_susi"
    },
    "resource": {
        "scope": ["tasks.read"] 
    },
    

步驟 4.2:啟用 CORS

若要允許單頁應用程式呼叫 Node.js Web API,您必須在 Web API 中啟用跨原始來源資源分享 (CORS)。 在生產應用程式中,請留意哪個網域正在提出要求。 在此範例中,允許來自任何網域的要求。

若要啟用 CORS,請使用下列中間件。 在您下載的 Node.js Web API 程式代碼範例中,它已新增至 index.js 檔案。

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

步驟 5:執行 SPA 和 Web API

您現在已準備好測試單頁應用程式對 API 的範圍存取。 在本機電腦上執行 Node.js Web API 和範例 JavaScript 單頁應用程式。 然後,登入單頁應用程式,然後選取 [呼叫 API] 按鈕來起始受保護 API 的要求。

執行 Node.js Web API

  1. 開啟主控台視窗,並變更為包含 Node.js Web API 範例的目錄。 例如:

    cd active-directory-b2c-javascript-nodejs-webapi
    
  2. 執行下列命令:

    npm install && npm update
    node index.js
    

    主控台視窗會顯示裝載應用程式的埠號碼。

    Listening on port 5000...
    

執行單頁應用程式

  1. 開啟另一個控制台視窗,並變更為包含 JavaScript SPA 範例的目錄。 例如:

    cd ms-identity-b2c-javascript-spa
    
  2. 執行下列命令:

    npm install && npm update
    npm start
    

    主控台視窗會顯示裝載應用程式的埠號碼。

    Listening on port 6420...
    
  3. 若要檢視應用程式,請在瀏覽器中移至 http://localhost:6420

    Screenshot of the SPA sample app displayed in the browser window.

  4. 完成註冊或登入程式。 成功登入之後,您應該會看到「用戶 <使用者名稱> 已登入」訊息。

  5. 選取 [ 呼叫 API] 按鈕。 SPA 會將要求中的存取令牌傳送至受保護的 Web API,以傳回登入使用者的顯示名稱:

    Screenshot of the SPA in a browser window, showing the username JSON result that's returned by the API.

部署您的應用程式

在生產應用程式中,應用程式註冊重新導向 URI 通常是應用程式執行所在的可公開存取端點,例如 https://contoso.com/signin-oidc

您可以隨時在已註冊的應用程式中新增和修改重新導向 URI。 下列限制適用於重新導向 URI:

  • 回復 URL 的開頭必須是 配置 https
  • 回復 URL 會區分大小寫。 其大小寫必須符合執行中應用程式的 URL 路徑大小寫。

下一步

如需本文所討論之概念的詳細資訊: