リソースとスコープ

Microsoft ID プラットフォームでは、スコープ中心のモデルを使用してリソースにアクセスします。 ここでは、リソースとは、アクセス トークンの受信者 (MS Graph APIや独自の Web API など) を指し、スコープ ("アクセス許可" とも呼ばれる) は、アクセス トークンが権限を付与するリソースの任意の側面を指します。

アクセストークン の要求は、MSAL.js では リソースごと、スコープごと になるように設計されています。 これは、スコープscp1でリソースAに対して要求されたアクセス トークンが存在することを意味します。

  • は、スコープ を使用してリソース scp2 にアクセスするために使用できません。
  • は、どのスコープのリソース B にもアクセスするために使用できません。

アクセス トークンの目的の受信者は、aud要求によって表されます。aud要求の値がリソース APP ID URI と一致しない場合、トークンは無効と見なす必要があります。 同様に、 アクセス トークン が付与するアクセス許可は、 scp 要求によって表されます。 詳細については、「 アクセス トークン要求 」を参照してください。

既定のスコープ

既定では、MSAL.js はすべての要求に openidprofile 、および 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.ReadUser.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のログイン (loginPopuploginRedirect) および acquireToken (つまり acquireTokenPopupacquireTokenRedirectacquireTokenSilent) メソッドに影響します。 以下を検討してください。

 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.ReadMail.Readに同意し、明日アプリケーションの新しいインスタンスを実行して、アクセストークンUser.Readについてのみ要求した場合でも、両方のUser.ReadMail.Readに対して発行されたトークンを引き続き受け取ることになります。 詳細については、「 アクセス許可と同意」を参照してください。