單一登入(SSO)透過減少使用者被要求提供憑證的次數,提供更無縫的體驗。 使用者只需輸入一次憑證,建立的會話即可在同一裝置上被其他應用程式重複使用,無需進一步提示。
Microsoft Entra ID 透過設定使用者首次驗證時的會話 Cookie 來啟用 SSO。 MSAL.js 也會依各應用程式網域,將使用者的 ID 權杖和存取權杖快取在瀏覽器儲存體中。 這兩個機制,Microsoft Entra 會話 cookie 與 Microsoft 驗證資源庫(MSAL)快取,彼此獨立,但協同運作以提供 SSO 行為。
同一個應用程式的瀏覽器分頁間的單一登入
當使用者在多個分頁開啟應用程式並在其中一個分頁登入時,他們可以在其他分頁開啟同一應用程式時,無需被提示登入。 為此,你需要在 MSAL.js 設定物件中設定 cacheLocation , localStorage 如下範例所示:
const config = {
auth: {
clientId: "1111-2222-3333-4444-55555555",
},
cache: {
cacheLocation: "localStorage",
},
};
const msalInstance = new msal.PublicClientApplication(config);
此時,不同瀏覽器分頁中的應用程式實例會使用相同的 MSAL 快取,因此彼此共享認證狀態。 你也可以利用 MSAL 事件來更新使用者從其他瀏覽器分頁或視窗登入時的應用程式實例。 更多資訊請參見:跨 分頁與視窗同步登入狀態
不同應用程式之間的單一登入
當使用者通過驗證時,系統會在瀏覽器中的 Microsoft Entra 網域上設定一個工作階段 Cookie。 MSAL.js 依賴此工作階段 Cookie,為使用者在不同應用程式之間提供單一登入(SSO)。 特別是,MSAL.js 提供 ssoSilent 一種無需互動即可登入用戶並取得代幣的方法。 然而,如果使用者在使用 Microsoft Entra ID 的會話中有多個使用者帳號,系統會提示他們選擇一個帳號來登入。 因此,使用 ssoSilent 方法達成單向 SSO 有兩種方法。
附有使用者提示
為了提升效能並確保授權伺服器會尋找正確的帳號會話,你可以在方法的 ssoSilent 請求物件中傳遞以下選項之一,靜默取得該令牌。
-
login_hint,可從account物件使用者名稱屬性或upnID 標記中的聲明中取得。 如果你的應用程式是用 B2C 來認證用戶,請參考: 設定 B2C 使用者流程以 ID 代幣發送使用者名稱 - 工作階段 ID
sid,可從account物件的idTokenClaims取得。 -
account,可使用其中一種帳戶方法來取得
我們建議使用login_hint提供給 ssoSilent 的選用 ID 權杖宣告作為loginHint,因為它是無訊息和互動式要求中最可靠的帳戶提示資訊。
使用登入提示
login_hint可選性聲明向 Microsoft Entra ID 提供使用者帳號嘗試登入的提示。 為繞過互動式驗證請求中通常顯示的帳號選擇提示,請提供如下所示:loginHint
const silentRequest = {
scopes: ["User.Read", "Mail.Read"],
loginHint: "user@contoso.com"
};
try {
const loginResponse = await msalInstance.ssoSilent(silentRequest);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(silentRequest).catch(error => {
// handle error
});
} else {
// handle error
}
}
在此範例中,loginHint 包含使用者的電子郵件或 UPN,其會在互動式權杖請求期間作為提示使用。 提示可以在應用程式間傳遞,以促進靜默 SSO,應用程式 A 可以登入使用者、讀取 loginHint,然後將申訴及當前租戶上下文傳送給應用程式 B。Microsoft Entra ID 會嘗試預先填寫登入表單,或繞過帳號選擇提示,直接對指定使用者進行認證程序。
如果申訴中的 login_hint 資訊與任何現有使用者不符,他們會被導向進入標準登入體驗,包括帳號選擇。
使用 session ID
要使用 session ID,請在應用程式的 ID 標記中新增 sid 可 選的聲明 。 該sid主張允許應用程式獨立於帳號名稱或使用者名稱之外,識別使用者的 Microsoft Entra 會話。 想了解如何新增可選聲明,例如 sid,請參閱 「為你的應用程式提供可選聲明」。 在 MSAL.js中進行 ssoSilent 靜默驗證請求時,請使用會話 ID(SID)。
const request = {
scopes: ["user.read"],
sid: sid,
};
try {
const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(request).catch(error => {
// handle error
});
} else {
// handle error
}
}
使用帳戶物件
如果你知道使用者帳號資訊,也可以透過以下 getAccountByUsername() or getAccountByHomeId() 方法取得該帳號:
const username = "test@contoso.com";
const myAccount = msalInstance.getAccountByUsername(username);
const request = {
scopes: ["User.Read"],
account: myAccount
};
try {
const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(request).catch(error => {
// handle error
});
} else {
// handle error
}
}
無需使用者提示
你可以嘗試使用 ssoSilent 此方法而不傳遞任何 account, sid 或 login_hint 如以下程式碼所示:
const request = {
scopes: ["User.Read"]
};
try {
const loginResponse = await msalInstance.ssoSilent(request);
} catch (err) {
if (err instanceof InteractionRequiredAuthError) {
const loginResponse = await msalInstance.loginPopup(request).catch(error => {
// handle error
});
} else {
// handle error
}
}
然而,如果應用程式在同一個瀏覽器會話中有多個使用者,或該使用者在該瀏覽器會話中有多個帳號,就有可能發生靜默登入錯誤。 若多個帳號可用,可能會顯示以下錯誤:
InteractionRequiredAuthError: interaction_required: AADSTS16000: Either multiple user identities are available for the current request or selected account is not supported for the scenario.
錯誤表示伺服器無法判斷要登入哪個帳號,因此需要前述account範例中的參數(, login_hint, ) sid或互動式登入來選擇帳號。
使用 ssoSilent 時的注意事項
重定向 URI(回覆網址)
為了提升效能並避免問題,可以設定 redirectUri 為空白頁面或其他不使用 MSAL 的頁面。
- 如果應用程式只使用快顯和靜默方法,請在
PublicClientApplication設定物件上設定redirectUri。 - 如果應用程式也使用重新導向方法,請針對每個要求分別設定
redirectUri。
第三方 Cookie
ssoSilent嘗試開啟隱藏的 iframe 並重用現有的 Microsoft Entra ID 會話。 這在阻擋第三方 Cookie 的瀏覽器(如 Safari)中無法運作,且會導致互動錯誤:
InteractionRequiredAuthError: login_required: AADSTS50058: A silent sign-in request was sent but no user is signed in. The cookies used to represent the user's session were not sent in the request to Azure AD
為了解決錯誤,使用者必須使用 loginPopup() 或 loginRedirect()建立一個互動式認證請求。 在某些情況下,提示參數值 none 可與互動式 MSAL.js 方法一起使用,以實現單一登入(SSO)。 詳情請參閱使用 prompt=none 的互動式請求。 如果你已經有該使用者的登入資訊,你可以傳遞 loginHint 或 sid 這兩個選用參數之一,以登入特定帳戶。
使用 prompt=login 停用 SSO
如果你希望 Microsoft Entra ID 即使在與授權伺服器已有作用中工作階段時,仍提示使用者輸入其憑證,則可以在使用 MSAL.js 的要求中使用 login 提示參數。 詳情請參見 MSAL.js 提示行為 。
ADAL.js 與 MSAL.js 之間共享認證狀態
MSAL.js 在Microsoft Entra驗證情境下,與 ADAL.js 功能相當。 為了讓從 ADAL.js 移轉到 MSAL.js 的過程更加容易,並在應用程式之間共用驗證狀態,該程式庫會讀取 ADAL.js 快取中代表使用者工作階段的 ID 權杖。 從 ADAL.js 遷移時,若要利用這項功能,您必須確保這些程式庫使用 localStorage 來快取權杖。 在初始化時,請在 MSAL.js 和 ADAL.js 的設定中,將 cacheLocation 設為 localStorage,如下:
// In ADAL.js
window.config = {
clientId: "1111-2222-3333-4444-55555555",
cacheLocation: "localStorage",
};
var authContext = new AuthenticationContext(config);
// In latest MSAL.js version
const config = {
auth: {
clientId: "1111-2222-3333-4444-55555555",
},
cache: {
cacheLocation: "localStorage",
},
};
const msalInstance = new msal.PublicClientApplication(config);
下一步
欲了解更多關於SSO的資訊,請參閱: