Microsoft ID プラットフォームでは、スコープ中心のモデルを使用してリソースにアクセスします。 ここでは、リソースとは、アクセス トークンの受信者 (MS Graph APIや独自の Web API など) を指し、スコープ ("アクセス許可" とも呼ばれる) は、アクセス トークンが権限を付与するリソースの任意の側面を指します。
アクセストークン の要求は、MSAL.js では リソースごと、スコープごと になるように設計されています。 これは、スコープscp1でリソースAに対して要求されたアクセス トークンが存在することを意味します。
- は、スコープ を使用してリソース
scp2にアクセスするために使用できません。 - は、どのスコープのリソース B にもアクセスするために使用できません。
アクセス トークンの目的の受信者は、aud要求によって表されます。aud要求の値がリソース APP ID URI と一致しない場合、トークンは無効と見なす必要があります。 同様に、 アクセス トークン が付与するアクセス許可は、 scp 要求によって表されます。 詳細については、「 アクセス トークン要求 」を参照してください。
既定のスコープ
既定では、MSAL.js はすべての要求に openid、 profile 、および offline_access スコープを追加します。 これらのスコープは、更新トークンと、アカウント オブジェクトにユーザーの情報を設定するために使用される ID トークン要求を受け取るために必要です。
複数のリソースの操作
複数のリソースにアクセスする必要がある場合は、それぞれに対して個別のトークン要求を開始します。
// "User.Read" stands as shorthand for "graph.microsoft.com/User.Read"
const graphToken = await msalInstance.acquireTokenSilent({
scopes: [ "User.Read" ]
});
const customApiToken = await msalInstance.acquireTokenSilent({
scopes: [ "api://<myCustomApiClientId>/My.Scope" ]
});
同じリソースに対して複数のスコープ (MS Graph APIの、User.Read、User.WriteCalendar.Read要求できることに注意してください。
const graphToken = await msalInstance.acquireTokenSilent({
scopes: [ "User.Read", "User.Write", "Calendar.Read" ] // all MS Graph API scopes
});
トークン要求で複数のリソース を誤って 渡した場合、受け取るトークンは最初のリソースに対してのみ発行されます。
// you will only receive a token for MS GRAPH API's "User.Read" scope here
const myToken = await msalInstance.acquireTokenSilent({
scopes: [ "User.Read", "api://<myCustomApiClientId>/My.Scope" ]
});
動的スコープと段階的な同意
Microsoft Entra IDでは、アプリケーション登録に直接設定されたスコープ (アクセス許可) は静的スコープと呼ばれます。 コード内でのみ定義されている他のスコープは、 動的スコープと呼ばれます。 これは、MSAL.jsのログイン (loginPopup、loginRedirect) および acquireToken (つまり acquireTokenPopup、acquireTokenRedirect、acquireTokenSilent) メソッドに影響します。 以下を検討してください。
const loginRequest = {
scopes: [ "openid", "profile", "User.Read" ]
};
const tokenRequest = {
scopes: [ "Mail.Read" ]
};
// will return an ID Token and an Access Token with scopes: "openid", "profile" and "User.Read"
msalInstance.loginPopup(loginRequest);
// will fail and fallback to an interactive method prompting a consent screen
// after consent, the received token will be issued for "openid", "profile" ,"User.Read" and "Mail.Read" combined
msalInstance.acquireTokenSilent(tokenRequest);
上記のコード スニペットでは、ユーザーが認証し、スコープがされた ID トークンとUser.Readを受け取ると、同意を求められます。 後で、のUser.Readを要求した場合、再び同意を求められるわけではありません (つまり、トークンをサイレントで取得できます)。
一方、ユーザーは認証段階でMail.Readに同意しなかったため、スコープのMail.Readを要求するときに同意を求められます。 受信したトークンには、(その特定のリソースに対して) 以前に同意したすべてのスコープが含まれるため、 増分同意という用語が含まれます。
少し異なるケースを考えてみましょう。
const loginRequest = {
scopes: [ "openid", "profile", "User.Read" ],
extraScopesToConsent: [ "api://<myCustomApiClientId>/My.Scope"]
};
const tokenRequest = {
scopes: [ "Mail.Read" ]
};
const anotherTokenRequest = {
scopes: [ "api://<myCustomApiClientId>/My.Scope" ]
}
// will return an ID Token and an Access Token with scopes: "openid", "profile" and "User.Read"
msalInstance.loginPopup(loginRequest);
// will fail with InteractionRequiredError due to lack of consent for "Mail.Read" scope. You should fallback to an interactive method in this case.
msalInstance.acquireTokenSilent(tokenRequest);
// will succeed and return an Access Token with scope "api://<myCustomApiClientId>/My.Scope"
msalInstance.acquireTokenSilent(anotherTokenRequest);
上記のコード スニペットでは、ユーザーが User.Read スコープと api://<myCustomApiClientId>/My.Scope スコープの両方に同意した場合でも、リソースごとのスコープの原則に従って MS Graph APIのアクセス トークンのみを受け取ります。 ただし、 api://<myCustomApiClientId>/My.Scopeに既に同意しているため、後でそのリソース/スコープの アクセス トークン を サイレント モード で取得できます。
同意の有効期間
Microsoft Entra IDでは、同意はアプリケーションの有効期間を超えて存続します。 つまり、リソース のアクセス トークン を要求すると、その時点で要求されたスコープに関係なく、そのリソースに対して以前に同意したすべてのスコープが返されます。 つまり、今日User.ReadとMail.Readに同意し、明日アプリケーションの新しいインスタンスを実行して、アクセストークンをUser.Readについてのみ要求した場合でも、両方のUser.ReadとMail.Readに対して発行されたトークンを引き続き受け取ることになります。 詳細については、「 アクセス許可と同意」を参照してください。