MSAL ブラウザーのアカウント

これは、キャッシュされたアカウントにアクセスするための次の API を提供する、 @azure/msal-browser ライブラリのプラットフォーム固有のアカウントに関するドキュメントです。

  • getAllAccounts(): 現在キャッシュ内にあるすべてのアカウントを返します。 特定のアカウント セットを返すオプションのフィルターをサポートします。 アプリケーションは、トークンをサイレントモードで取得するアカウントを選択する必要があります。
  • getAccount(): 渡されたフィルターに一致する最初のキャッシュされたアカウントを返します。 アカウントがキャッシュから読み取られる順序は任意であり、フィルター処理された一覧の最初のアカウントが、 getAccountの 2 つの呼び出しで同じになることは保証されません。 以下で説明するように、フィルター属性の数を増やすと、より正確な一致が提供されます。

Account Filter オブジェクト

AccountFilter 型のドキュメントには、アカウントをフィルター処理するために使用および結合できるプロパティが一覧表示されています。

Note

通常、単一アカウント フィルター属性は、キャッシュされたアカウント オブジェクトを一意に識別することは保証されません。 homeAccountId + localAccountIdなど、繰り返されない属性の組み合わせを追加すると、検索を絞り込むことができます。

Note

realm がキャッシュに tenantId

次の getAccountBy API は非推奨となりました。 代わりに、適切なフィルター オブジェクトで getAccount() を使用してください。

  • getAccountByHomeId(): 代わりに getAccount({ homeAccountId }) を使用します。
  • getAccountByLocalId(): 代わりに getAccount({ localAccountId }) を使用します。
  • getAccountByUsername(): 代わりに getAccount({ username }) を使用します。

これらの API の使用例を次に示します。


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 code here
            homeAccountId = ...
        } else if (currentAccounts.length === 1) {
            homeAccountId = currentAccounts[0].homeAccountId; // Single account scenario
        }
    }
}

次に、 homeAccountIdlocalAccountIdusername などのアカウント プロパティを使用して、トークンをサイレントで取得する前に、キャッシュされたアカウントを検索できます。

// This method attempts silent token acquisition and falls back on acquireTokenPopup
async function getTokenPopup(request, homeAccountId) {
    // In this case, accounts are filtered by homeAccountId, but more attributes can be added to refine the search and increase the precision of the account filter
    const accountFilter = {
        homeAccountId: homeAccountId,
    };
    request.account = myMSALObj.getAccount(accountFilter);
    return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
        // Handle error
        return await myMSALObj.acquireTokenPopup(request);
    });
}

ログイン ヒントによるフィルター処理

@azure/msal-browser@3.2.0時点では、すべてのログイン ヒント値を使用してアカウントを検索およびフィルター処理できます。 ログイン ヒントでフィルター処理するために、MSAL は、AccountFilter オブジェクトのloginHint値を次のアカウント属性 (優先順位順) と比較して一致を検索します。

  • login_hint ID トークン要求
  • username account プロパティ
  • upn ID トークン要求

Note

上記のすべての属性は、 loginHint プロパティとしてアカウント フィルターに渡すことができます。 アカウント フィルターでは、 username 属性も usernameとして受け入れ、よりパフォーマンスの高い検索が生成されます。

login_hint要求の使用

const accountFilter = {
    loginHint: previouslyObtainedIdTokenClaims.login_hint;
};
request.account = myMSALObj.getAccount(accountFilter);
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
    // Handle error
    return await myMSALObj.acquireTokenPopup(request);
});

'username' の使用

Note

username値は、usernameまたはloginHintとしてAccountFilter オブジェクトに含めることができます。 これは、 username 要求が、トークン サービスがログイン ヒントとして受け入れる 3 つの値 ( login_hint および upn ID トークン要求と共) のいずれかであるためです。 アプリケーションで問題の値が usernameであることが確実な場合は、 AccountFilter.username プロパティとして設定すると、検索パフォーマンスが向上します。 username値を loginHint として設定できることは、アプリケーションがログイン ヒントを利用し、その値がusernamelogin_hint、またはupn要求から取得されたかどうかに関するコンテキストを保持しない場合に便利です。

usernameを次のように渡すloginHint

const accountUsername = userProfile.username;
const accountFilter = {
    loginHint: accountUsername;
};
request.account = myMSALObj.getAccount(accountFilter);
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
    // Handle error
    return await myMSALObj.acquireTokenPopup(request);
});

usernameを次のように渡すusername

const accountUsername = userProfile.username;
const accountFilter = {
    username: accountUsername;
};
request.account = myMSALObj.getAccount(accountFilter);
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
    // Handle error
    return await myMSALObj.acquireTokenPopup(request);
});

upn要求の使用

const accountFilter = {
    loginHint: previouslyObtainedIdTokenClaims.upn;
};
request.account = myMSALObj.getAccount(accountFilter);
return await myMSALObj.acquireTokenSilent(request).catch(async (error) => {
    // Handle error
    return await myMSALObj.acquireTokenPopup(request);
});

アクティブ なアカウント API

@azure/msal-browser ライブラリには、現在 "アクティブ" であり、トークン要求に使用する必要があるアカウントを追跡するのに役立つ便利な API が 2 つ用意されています。

  • getActiveAccount(): 現在アクティブなアカウントを返します。
  • setActiveAccount(): アカウント オブジェクトを受け取り、アクティブなアカウントとして設定します。

トークンの取得に使用するアカウントはアプリによって異なりますが、使用するアカウントを決定したら、選択したアカウント オブジェクトで setActiveAccount() API を呼び出すだけです。 個々の要求で別のアカウントが指定されていない場合、 acquireTokenlogin 、または ssoSilent の呼び出しでは、既定でアクティブ なアカウントが使用されるようになりました。 現在アクティブなアカウントをクリアするには、 setActiveAccount(null)を呼び出すことができます。

function login() {
    return myMsalObj.loginPopup().then((response) => {
        // After a successful login set the active account to be the user that just logged in
        myMsalObj.setActiveAccount(response.account);
    });
}

function getAccessToken() {
    // Providing an account in the token request is not required if there is an active account set
    return myMsalObj.acquireTokenSilent({ scopes: ["User.Read"] });
}

注: バージョン 2.16.0 以降、アクティブなアカウントは、 PublicClientApplication インスタンスで構成されたキャッシュの場所に格納されます。 以前のバージョンを使用している場合、アクティブなアカウントはメモリ内に格納されるため、ページの読み込みごとにリセットする必要があります。

入れ子になったアプリ認証

NAA アプリケーションの場合、 setActiveAccount()getActiveAccount() は NO-OP API です。 ユーザーはアクティブなアカウントを設定して取得できますが、NAA アプリケーションには常に 1 つの アカウントが必要であり、アカウントはホスト アプリケーションによって accountContextで提供されるため、アクティブに無視されます。 今後、ハブ全体で複数のアカウントがサポートされる場合、この動作は変わると予想されます。

メモ

  • 現在の msal-browser の既定の サンプル には、動作する単一アカウントのシナリオがあります。
  • 複数のアカウントのシナリオがある場合は、 サンプル ( handleResponse()) を変更して、キャッシュされたすべてのアカウントを一覧表示し、特定のアカウントを選択してください。
  • アプリケーションがusernameに基づいてアカウントを取得する場合は、getAccount() API でusername フィルターを使用する前に、(特定のユーザーのlogin API の応答から) usernameを保存する必要があります。
  • getAllAccounts() は、複数の対話型トークン要求を行い、ユーザーが 2 つ以上の対話で異なるアカウントを選択した場合、複数のアカウントを返します。 最初の操作の後にアカウントの選択画面をMicrosoft Entra ID表示するには、対話型の acquireToken またはログイン API にprompt: "select_account"またはprompt: "login"を渡す必要がある場合があります。
  • アカウント API はローカル アカウントの状態を返し、必ずしもサーバーの状態を反映しているわけではありません。 以前に MSAL.js を使用してこのアプリにサインインしたアカウントが返され、サーバー セッションがまだアクティブな場合とそうでない場合があります。
  • 異なるドメインでホストされている 2 つのアプリは、ブラウザー ストレージがドメインごとにセグメント化されているため、アカウントの状態を共有しません。
  • getAllAccounts() は順序付けされておらず、複数の呼び出しで同じ順序になることは保証されていません
  • acquireToken またはログイン API の呼び出しが成功するたびに、1 つのアカウントが返されます