使用 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。
登入流程
登入流程牽涉到下列步驟:
- 使用者移至 Web 應用程式,然後選取 [登入 ]。
- 應用程式會起始驗證要求,並將使用者重新導向至 Azure AD B2C。
- 使用者 註冊或登入 並 重設密碼 。 或者,他們可以使用社交帳戶 登入 。
- 使用者登入之後,Azure AD B2C 會將授權碼傳回應用程式。
- 單頁應用程式會驗證識別碼權杖、讀取宣告,然後讓使用者呼叫受保護的資源和 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 範圍。 要求存取權杖時,您的應用程式會在要求的範圍參數中指定所需的許可權。
下圖說明應用程式架構和註冊:
呼叫 Web API
驗證完成後,使用者會與叫用受保護 Web API 的應用程式互動。 Web API 使用 持有人權杖 驗證。 持有人權杖是應用程式從 Azure AD B2C 取得的存取權杖。 應用程式會在 HTTPS 要求的授權標頭中傳遞權杖。
Authorization: Bearer <access token>
如果存取權杖的範圍不符合 Web API 的範圍,驗證程式庫會取得具有正確範圍的新存取權杖。
登出流程
登出流程牽涉到下列步驟:
- 從應用程式,使用者登出。
- 應用程式會清除其會話物件,而驗證程式庫會清除其權杖快取。
- 應用程式會將使用者帶往 Azure AD B2C 登出端點,以終止 Azure AD B2C 會話。
- 系統會將使用者重新導向回應用程式。
必要條件
正在執行的電腦:
- Visual Studio Code 或其他程式碼編輯器。
- Node.js 執行時間
步驟 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 ),請遵循下列步驟:
登入 Azure 入口網站。
請確定您使用的是包含 Azure AD B2C 租使用者的目錄。 在入口網站工具列中選取 [ 目錄 + 訂用帳戶 ] 圖示。
在入口 網站設定 |[目錄 + 訂用帳戶 ] 頁面,在 [ 目錄名稱 ] 清單中尋找您的 Azure AD B2C 目錄,然後選取 [ 切換 ]。
在 Azure 入口網站中,搜尋並選取 [Azure AD B2C]。
選取 [應用程式註冊],然後選取 [新增註冊]。
針對 [ 名稱 ],輸入應用程式的名稱(例如 my-api1 )。 保留 [重新導向 URI] 和 [支援的帳戶類型 ] 的預設值 。
選取註冊。
完成應用程式註冊之後,請選取 [ 概觀 ]。
記錄應用程式 (client) 識別碼 值,以供稍後在設定 Web 應用程式時使用。
步驟 2.2:設定範圍
選取您建立的 my-api1 應用程式( 應用程式識別碼:2 )以開啟其 [概 觀 ] 頁面。
在 [管理] 底下 ,選取 [ 公開 API ]。
在 [ 應用程式識別碼 URI] 旁,選取 [ 設定 ] 連結。 以唯一名稱取代預設值 ( GUID),然後選取 [ 儲存 ]。
當您的 Web 應用程式要求 Web API 的存取權杖時,它應該新增此 URI 作為您為 API 定義之每個範圍的前置詞。
在此 API 定義的 [範圍] 下 ,選取 [ 新增範圍 ]。
若要建立定義 API 讀取存取權的範圍:
- 針對 [範圍名稱 ],輸入 tasks.read 。
- 如需 管理員同意顯示名稱 ,請輸入 工作 API 的讀取權限。
- 針對 管理員同意描述 ,輸入 [允許讀取工作 API ]。
選取新增範圍。
選取 [新增範圍 ],然後新增定義 API 寫入權限的範圍:
- 針對 [範圍名稱 ],輸入 tasks.write 。
- 針對 管理員同意顯示名稱 ,輸入 工作 API 的寫入存取權。
- 針對 管理員同意描述 ,輸入 [允許寫入工作 API ]。
選取新增範圍。
步驟 2.3:註冊 SPA
若要建立 SPA 註冊,請使用下列步驟:
- 登入 Azure 入口網站。
- 如果您有多個租使用者的存取權,請選取 頂端功能表中的 [設定 ] 圖示,從 [目錄 + 訂 用帳戶] 功能表切換至您的 Azure AD B2C 租使用者。
- 搜尋並選取 Azure AD B2C。
- 選取 [應用程式註冊],然後選取 [新增註冊]。
- 輸入應用程式的 [名稱 ] (例如 MyApp )。
- 在 [支援的帳戶類型] 下,選取 [任何身分識別提供者或組織目錄中的帳戶 (用於運用使用者流程來驗證使用者)]。
- 在 [重新導向 URI] 下 ,選取 [單頁應用程式], 然後在 [URL] 方塊中輸入
http://localhost:6420
。 - 在 [許可權] 底下,選取 [ 授與系統管理員同意以開啟識別碼和離線存取權限] 核取方塊。
- 選取註冊。
當您設定 Web 應用程式時,請記錄應用程式(用戶端)識別碼 以供稍後使用。
步驟 2.4:啟用隱含授與流程
在您自己的環境中,如果您的 SPA 應用程式使用 MSAL.js 1.3 或更早版本和隱含授與流程,或設定 https://jwt.ms/ 應用程式以測試使用者流程或自訂原則,則必須在應用程式註冊中啟用隱含授與流程:
在左側功能表中,於 [管理]下,選取 [驗證]。
在 [隱含授與和混合式流程] 下,選取 [存取權杖 (用於隱含流程)] 和 [識別碼權杖 (用於隱含和混合式流程)] 核取方塊。
選取 [儲存]。
如果您的應用程式使用 MSAL.js 2.0 或更新版本,請勿啟用隱含流程授與,因為 MSAL.js 2.0+ 支援 PKCE 的授權碼流程。 本文中的 SPA 應用程式會使用 PKCE 流程,因此您不需要啟用隱含授與流程。
步驟 2.5:授與許可權
若要授與您的應用程式 ( 應用程式識別碼: 1 ) 許可權,請遵循下列步驟:
選取 [應用程式註冊 ],然後選取您建立的應用程式( 應用程式識別碼:1 )。
在 [管理] 底下 ,選取 [API 許可權 ]。
在 [設定的許可權 ] 底下 ,選取 [ 新增許可權 ]。
選取 [ 我的 API] 索引卷 標。
選取應授與 Web 應用程式存取權的 API ( 應用程式識別碼:2 )。 例如,輸入 my-api1 。
在 [許可權] 下 展開工作 ,然後選取您稍早定義的範圍(例如 tasks.read 和 tasks.write )。
選取新增權限。
選取 [ 授與管理員同意] 以取得 <租用戶名稱>。
選取 [是] 。
選取 [重新整理],然後確認 [已授與...] 出現在這兩個範圍的 [狀態] 底下。
從 [ 設定的許可權] 清單中,選取您的範圍,然後複製範圍完整名稱。
步驟 3:取得 SPA 範例程式代碼
此範例示範單頁應用程式如何使用 Azure AD B2C 進行用戶註冊和登入。 然後應用程式會取得存取令牌,並呼叫受保護的 Web API。
若要取得 SPA 範例程式代碼,您可以執行下列其中一項:
執行下列命令,從 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 範例程式代碼,請執行下列其中一項:
執行下列命令,從 GitHub 複製範例 Web API 專案:
git clone https://github.com/Azure-Samples/active-directory-b2c-javascript-nodejs-webapi.git
您也可以直接移至 GitHub 上的 Azure-Samples/active-directory-b2c-javascript-nodejs-webapi 專案。
步驟 4.1:更新 Web API
在程式 代碼編輯器中開啟 config.json 檔案。
使用您稍早建立的應用程式註冊來修改變量值。 並將 更新
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
開啟主控台視窗,並變更為包含 Node.js Web API 範例的目錄。 例如:
cd active-directory-b2c-javascript-nodejs-webapi
執行下列命令:
npm install && npm update node index.js
主控台視窗會顯示裝載應用程式的埠號碼。
Listening on port 5000...
執行單頁應用程式
開啟另一個控制台視窗,並變更為包含 JavaScript SPA 範例的目錄。 例如:
cd ms-identity-b2c-javascript-spa
執行下列命令:
npm install && npm update npm start
主控台視窗會顯示裝載應用程式的埠號碼。
Listening on port 6420...
若要檢視應用程式,請在瀏覽器中移至
http://localhost:6420
。完成註冊或登入程式。 成功登入之後,您應該會看到「用戶 <使用者名稱> 已登入」訊息。
選取 [ 呼叫 API] 按鈕。 SPA 會將要求中的存取令牌傳送至受保護的 Web API,以傳回登入使用者的顯示名稱:
部署您的應用程式
在生產應用程式中,應用程式註冊重新導向 URI 通常是應用程式執行所在的可公開存取端點,例如 https://contoso.com/signin-oidc
。
您可以隨時在已註冊的應用程式中新增和修改重新導向 URI。 下列限制適用於重新導向 URI:
- 回復 URL 的開頭必須是 配置
https
。 - 回復 URL 會區分大小寫。 其大小寫必須符合執行中應用程式的 URL 路徑大小寫。
下一步
如需本文所討論之概念的詳細資訊:
- 深入瞭解程式代碼範例。
- 在您自己的 SPA 中啟用驗證。
- 在 SPA 中設定驗證選項。
- 在您自己的 Web API 中啟用驗證。