如何將 JavaScript 應用程式從 ADAL.js 遷移至MSAL.js
Microsoft適用於 JavaScript 的驗證連結庫 (MSAL.js也稱為 msal-browser
) 2.x 是建議在 Microsoft 身分識別平台 上搭配 JavaScript 應用程式使用的驗證連結庫。 本文強調您需要進行的變更,以移轉使用 ADAL.js 的應用程式,以使用 MSAL.js 2.x
注意
強烈建議MSAL.js 2.x MSAL.js 1.x。 驗證碼授與流程更安全,並允許單頁應用程式維持良好的用戶體驗,儘管Safari等隱私權措施瀏覽器已實作來封鎖第三方Cookie等優點。
必要條件
- 您必須在應用程式註冊入口網站上將 [平臺 / 回復 URL 類型] 設定為 [單頁應用程式] (如果您已在應用程式註冊中新增其他平臺,例如 Web,您必須確定重新導向 URI 不會重疊。請參閱:重新導向 URI 限制)
- 您必須為MSAL.js依賴的ES6功能提供 polyfills ,才能在Internet Explorer 上 執行您的應用程式
- 如果您尚未將Microsoft Entra 應用程式遷移至 v2 端點
安裝和匯入 MSAL
有兩種方式可以安裝 MSAL.js 2.x 連結庫:
透過 npm:
npm install @azure/msal-browser
然後,根據您的模組系統,匯入它,如下所示:
import * as msal from "@azure/msal-browser"; // ESM
const msal = require('@azure/msal-browser'); // CommonJS
透過 CDN:
在 HTML 檔的標頭區段中載入文稿:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://alcdn.msauth.net/browser/2.14.2/js/msal-browser.min.js"></script>
</head>
</html>
如需使用 CDN 時的替代 CDN 連結和最佳做法,請參閱: CDN 使用量
初始化 MSAL
在ADAL.js中,您會具現化 AuthenticationContext 類別,然後公開可用來達成驗證的方法(login
等等 acquireTokenPopup
)。 此物件可作為應用程式與授權伺服器或識別提供者之連線的表示法。 初始化時,唯一的必要參數是 clientId:
window.config = {
clientId: "YOUR_CLIENT_ID"
};
var authContext = new AuthenticationContext(config);
在 MSAL.js中,您會改為具現化 PublicClientApplication 類別。 如同ADAL.js,建構函式會預期至少包含 參數的clientId
組態物件。 如需詳細資訊,請參閱: 初始化MSAL.js
const msalConfig = {
auth: {
clientId: 'YOUR_CLIENT_ID'
}
};
const msalInstance = new msal.PublicClientApplication(msalConfig);
在ADAL.js和MSAL.js中,如果未指定,授權單位 URI 會預設 https://login.microsoftonline.com/common
為 。
注意
如果您在 v2.0 中使用 https://login.microsoftonline.com/common
授權單位,將允許使用者使用任何 Microsoft Entra 組織或個人Microsoft帳戶 (MSA) 登入。 在MSAL.js中,如果您想要限制登入任何Microsoft Entra 帳戶(與 ADAL.js 的行為相同),請改用 https://login.microsoftonline.com/organizations
。
設定 MSAL
ADAL.js中某些組態選項在初始化 AuthenticationContext 時所使用的設定選項在 MSAL.js 中已被取代,同時引進一些新選項。 請參閱可用選項的完整清單。 重要的是,除了 clientId
之外,這些選項中的許多都可以在令牌取得期間覆寫,讓您根據每個要求設定這些 選項 。 例如,您可以在取得令牌時,使用不同於您在初始化期間設定的授權單位 URI 或重新導向 URI。
此外,您不再需要透過組態選項指定登入體驗(也就是使用彈出視窗或重新導向頁面)。 MSAL.js
而是透過 PublicClientApplication
實例公開 loginPopup
和 loginRedirect
方法。
啟用 記錄
在ADAL.js中,您會在程式碼的任何位置分別設定記錄:
window.config = {
clientId: "YOUR_CLIENT_ID"
};
var authContext = new AuthenticationContext(config);
var Logging = {
level: 3,
log: function (message) {
console.log(message);
},
piiLoggingEnabled: false
};
authContext.log(Logging)
在MSAL.js中,記錄是組態選項的一部分,並在 初始化 PublicClientApplication
期間建立:
const msalConfig = {
auth: {
// authentication related parameters
},
cache: {
// cache related parameters
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
}
const msalInstance = new msal.PublicClientApplication(msalConfig);
切換至 MSAL API
ADAL.js中的某些公用方法在 MSAL.js中具有對等專案:
ADAL | MSAL (部分機器翻譯) | 備註 |
---|---|---|
acquireToken |
acquireTokenSilent |
已重新命名,現在需要 帳戶 物件 |
acquireTokenPopup |
acquireTokenPopup |
現在異步並傳回承諾 |
acquireTokenRedirect |
acquireTokenRedirect |
現在異步並傳回承諾 |
handleWindowCallback |
handleRedirectPromise |
使用重新導向體驗時需要 |
getCachedUser |
getAllAccounts |
已重新命名,現在會傳回帳戶陣列。 |
其他方法已被取代,而MSAL.js提供新的方法:
ADAL | MSAL (部分機器翻譯) | 備註 |
---|---|---|
login |
N/A | 已取代。 使用 loginPopup 或 loginRedirect |
logOut |
N/A | 已取代。 使用 logoutPopup 或 logoutRedirect |
N/A | loginPopup |
|
N/A | loginRedirect |
|
N/A | logoutPopup |
|
N/A | logoutRedirect |
|
N/A | getAccountByHomeId |
依家庭識別碼篩選帳戶 (oid + 租使用者識別碼) |
N/A | getAccountLocalId |
依本機識別碼篩選帳戶(適用於ADFS) |
N/A | getAccountUsername |
依使用者名稱篩選帳戶(如果有) |
此外,由於 typeScript 中實作MSAL.js與ADAL.js不同,它會公開您可以在專案中使用的各種類型和介面。 如需詳細資訊, 請參閱MSAL.js API 參考 。
使用範圍而非資源
Azure Active Directory v1.0 與 2.0 端點之間的重要差異在於如何存取資源。 搭配 v1.0 端點使用ADAL.js時,您會先在應用程式註冊入口網站上註冊許可權,然後要求資源的存取令牌(例如 Microsoft Graph),如下所示:
authContext.acquireTokenRedirect("https://graph.microsoft.com", function (error, token) {
// do something with the access token
});
MSAL.js僅 支援 v2.0 端點。 v2.0 端點會採用以範圍為中心的模型來存取資源。 因此,當您要求資源的存取令牌時,您也需要指定該資源的範圍:
msalInstance.acquireTokenRedirect({
scopes: ["https://graph.microsoft.com/User.Read"]
});
以範圍為中心的模型的優點之一是能夠使用 動態範圍。 使用 v1.0 端點建置應用程式時,您需要註冊應用程式所需的完整許可權集(稱為 靜態範圍),讓使用者在登入時同意。 在 v2.0 中,您可以使用 scope 參數在您想要的許可權時要求許可權(因此, 動態範圍)。 這可讓使用者對範圍提供 累加同意 。 因此,如果一開始您只想讓使用者登入您的應用程式,而且您不需要任何類型的存取權,您可以這麼做。 如果您稍後需要能夠讀取使用者的行事曆,您可以接著在 acquireToken 方法中要求行事曆範圍,並取得使用者的同意。 如需詳細資訊,請參閱: 資源和範圍
使用承諾而不是回呼
在ADAL.js中,回呼會在驗證成功且取得響應之後用於任何作業:
authContext.acquireTokenPopup(resource, extraQueryParameter, claims, function (error, token) {
// do something with the access token
});
在MSAL.js中,會改用承諾:
msalInstance.acquireTokenPopup({
scopes: ["User.Read"] // shorthand for https://graph.microsoft.com/User.Read
}).then((response) => {
// do something with the auth response
}).catch((error) => {
// handle errors
});
您也可以使用 ES8 隨附的 async/await 語法:
const getAccessToken = async() => {
try {
const authResponse = await msalInstance.acquireTokenPopup({
scopes: ["User.Read"]
});
} catch (error) {
// handle errors
}
}
快取和擷取令牌
如同ADAL.js,MSAL.js使用 Web 記憶體 API 快取瀏覽器記憶體中的令牌和其他驗證成品。 建議您使用sessionStorage
選項(請參閱:組態),因為它在儲存使用者取得的令牌時更安全,但localStorage
會讓您跨索引卷標和用戶會話 單一登入。
重要的是,您不應該直接存取快取。 相反地,您應該使用適當的MSAL.js API 來擷取驗證成品,例如存取令牌或用戶帳戶。
使用重新整理令牌更新令牌
ADAL.js使用 OAuth 2.0 隱含流程,因為安全性原因不會傳回重新整理令牌(重新整理令牌的存留期比存取令牌長,因此在惡意執行者手中更危險)。 因此,ADAL.js使用隱藏的 IFrame 執行令牌更新,讓使用者不會重複提示進行驗證。
使用 PKCE 支援的驗證程式碼流程,使用 MSAL.js 2.x 的應用程式會取得重新整理令牌,以及標識元和存取令牌,可用來更新令牌。 重新整理令牌的使用已抽象化,開發人員不應該建置其周圍的邏輯。 相反地,MSAL 會自行使用重新整理令牌來管理令牌更新。 使用 ADAL.js 的先前令牌快取無法傳輸至MSAL.js,因為令牌快取架構已變更,且與ADAL.js中使用的架構不相容。
處理錯誤和例外狀況
使用MSAL.js時,最常見的錯誤類型是 interaction_in_progress
錯誤。 當另一個互動式 API 仍在進行中時叫用互動式 API 時loginPopup
,loginRedirect
acquireTokenPopup
acquireTokenRedirect
就會擲回此錯誤。 和 acquireToken*
API 是異步的login*
,因此您必須確保產生的承諾已在叫用另一個承諾之前解決。
另一個常見的錯誤是 interaction_required
。 這個錯誤通常是藉由起始互動式令牌取得提示來解決。 例如,您嘗試存取的 Web API 可能會有條件式存取原則,要求使用者執行多重要素驗證 (MFA)。 在此情況下,藉由觸發 acquireTokenPopup
或 acquireTokenRedirect
會提示使用者輸入 MFA 來處理interaction_required
錯誤,讓他們能夠完整處理它。
然而,您可能會遇到的另一個常見錯誤是 consent_required
,當使用者未同意取得受保護資源存取令牌所需的許可權時,就會發生這種情況。 如同 在 中 interaction_required
,錯誤的解決方案 consent_required
通常會使用 acquireTokenPopup
或 acquireTokenRedirect
來起始互動式令牌取得提示。
如需詳細資訊,請參閱: 常見的MSAL.js錯誤及其處理方式
使用事件 API
MSAL.js (>=v2.4) 引進可在應用程式中使用的事件 API。 這些事件與驗證程式以及 MSAL 在任何時刻執行的動作相關,而且可用來更新 UI、顯示錯誤訊息、檢查是否有任何互動正在進行等等。 例如,以下是在登入進程因任何原因而失敗時所呼叫的事件回呼:
const callbackId = msalInstance.addEventCallback((message) => {
// Update UI or interact with EventMessage here
if (message.eventType === EventType.LOGIN_FAILURE) {
if (message.error instanceof AuthError) {
// Do something with the error
}
}
});
為了達到效能,當不再需要事件回呼時,請務必取消註冊事件回呼。 如需詳細資訊,請參閱: MSAL.js事件 API
處理多個帳戶
ADAL.js具有代表目前已驗證實體的使用者概念。 MSAL.js會以帳戶取代使用者,因為使用者可以有多個與其相關聯的帳戶。 這也表示您現在必須控制多個帳戶,並選擇適當的帳戶來處理。 下列代碼段說明此程式:
let homeAccountId = null; // Initialize global accountId (can also be localAccountId or username) used for account lookup later, ideally stored in app state
// This callback is passed into `acquireTokenPopup` and `acquireTokenRedirect` to handle the interactive auth response
function handleResponse(resp) {
if (resp !== null) {
homeAccountId = resp.account.homeAccountId; // alternatively: resp.account.homeAccountId or resp.account.username
} else {
const currentAccounts = myMSALObj.getAllAccounts();
if (currentAccounts.length < 1) { // No cached accounts
return;
} else if (currentAccounts.length > 1) { // Multiple account scenario
// Add account selection logic here
} else if (currentAccounts.length === 1) {
homeAccountId = currentAccounts[0].homeAccountId; // Single account scenario
}
}
}
如需詳細資訊,請參閱: MSAL.js中的帳戶
使用包裝函式連結庫
如果您要針對 Angular 和 React 架構進行開發,則可以分別使用 MSAL Angular v2 和 MSAL React。 這些包裝函式會公開與MSAL.js相同的公用 API,同時提供可簡化驗證和令牌擷取程式的架構特定方法和元件。
執行應用程式
變更完成後,請執行應用程式並測試您的驗證案例:
npm start
範例:使用 ADAL.js 保護 SPA 與 MSAL.js
下列代碼段示範單頁應用程式使用 Microsoft 身分識別平台 驗證使用者所需的最少程式碼,並使用第一個ADAL.js取得 Microsoft Graph 的存取令牌,然後MSAL.js:
使用ADAL.js | 使用MSAL.js |
|
|
下一步
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: