使用 Azure AD B2C 在範例單頁應用程式中設定驗證
本文使用範例 JavaScript 單頁應用程式 (SPA) 來說明如何將 Azure Active Directory B2C (Azure AD B2C) 驗證新增至您的 SPA。
概觀
OpenID Connect (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 API 範圍的權限授與 Web 應用程式。 要求存取權杖時,您的應用程式會在要求的範圍參數中指定所需的權限。
下圖說明應用程式結構和註冊:
呼叫 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] 和 [支援的帳戶類型] 的預設值。
選取註冊。
當應用程式註冊完成之後,選取 [概觀]。
當您設定 Web 應用程式時,請記錄 [應用程式 (用戶端) 識別碼] 值,以供稍後使用。
步驟 2.2:設定範圍
選取您建立的 my-api1 應用程式 (「應用程式識別碼:2」),以開啟其 [概觀] 頁面。
在 [管理] 底下,選取 [公開 API]。
選取 [應用程式識別碼 URI] 旁邊的 [設定] 連結。 以唯一的名稱 (例如 tasks-api) 取代預設值 (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
。 - 在 [權限] 底下,選取 [對 openid 與 offline_access 權限授與管理員同意] 核取方塊。
- 選取註冊。
當您設定 Web 應用程式時,請記錄應用程式(用戶端)識別碼 以供稍後使用。
步驟 2.4:啟用隱含授與流程
您可以使用 MSAL.js 1.3 版或更早版本,或使用應用程式註冊來 測試使用者流程以供測試時,有兩個原因可以啟用隱含授與流程。
使用下列步驟為您的應用程式啟用隱含授與流程:
選取您建立的應用程式註冊。
在 [管理] 底下,選取 [驗證]。
在 [隱含授與和混合式流程] 下,選取 [存取權杖 (用於隱含流程)] 和 [識別碼權杖 (用於隱含和混合式流程)] 核取方塊。
選取 [儲存]。
注意
如果您的應用程式使用 MSAL.js 2.0 或更新版本,請勿啟用隱含授與流程,因為 MSAL.js 2.0+ 支援 OAuth 2.0 授權碼流程(使用 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 中啟用驗證。