委任されたアクセス許可戦略を開発する

この記事は、開発者がアプリケーションのアクセス許可を管理するための最適なアプローチを実装し、ゼロ トラスト原則を使用して策定するのに役立ちます。 「リソースにアクセスするための認可を得る」で説明されているように、委任されたアクセス許可は委任されたアクセスと共に使用され、アプリケーションがユーザーに代わって動作できるようにし、ユーザーがアクセスできるものだけにアクセスできるようにします。 アプリケーションのアクセス許可は、直接アクセスと共に使用され、アプリケーションがアクセス許可が関連付けられているすべてのデータにアクセスできるようにします。 管理者とサービス プリンシパルの所有者のみが、アプリケーションのアクセス許可に同意できます。

アクセス許可と同意のモデルは、主にアプリケーションを参照します。 アクセス許可と同意のプロセスでは、ユーザーが実行できる操作を制御できません。 アプリケーションで実行できるアクションを制御します。

次のベン図を参照してください。 委任されたアクセス許可を使用すると、ユーザーが実行できる操作とアプリケーションで実行できる操作の間に共通部分ができます。 この共通部分は、アプリケーションがバインドされる有効なアクセス許可です。 委任されたアクセス許可を使用する場合、それは有効なアクセス許可によってバインドされます。

ベン図は、アプリのアクセス許可とユーザー機能の共通部分として有効なアクセス許可を示しています。

たとえば、アプリの前にユーザーが存在するアプリケーションは、テナント内のすべてのユーザーのプロファイルを更新するアクセス許可を取得します。 これは、アプリケーションを実行するすべてのユーザーが他のユーザーのプロファイルを更新できることを意味するわけではありません。 管理者がアプリケーションに User.ReadWrite.All を付与することを決定した場合、その管理者はユーザー プロファイルを更新するときにアプリケーションが適切な処理を行っていると考えます。 アプリによって変更がログに記録され、情報が適切に保護される場合があります。 管理者は、ユーザーではなく、アプリケーションに関する価値の判断を行います。

最小権限アプローチ

API は複雑になる可能性があります。 単純な API は操作が少ないものです。 Microsoft Graph などの複雑な API は、アプリケーションが使用する可能性がある多くの要求をカプセル化します。 アプリケーションに読み取る権利があるからといって、更新する権利が必要というわけではありません。 たとえば、Microsoft Graph には何千もの API があります。 ユーザーのプロファイルを読み取る権限があるからといって、すべての OneDrive ファイルを削除する権限も必要だという理由はありません。

開発者は、次の手順を実行する必要があります。

  • アプリが呼び出す API を把握する。
  • API のドキュメントと、API に必要なアクセス許可について理解する。
  • 最小限のアクセス許可でタスクを実行する。

API は、多くの場合、組織のデータ ストアへのアクセスを提供し、そのデータにアクセスする攻撃者の注目を集めます。

要求したアクセス許可を評価して、ジョブを完了するために絶対的な最小限の特権セットを確実にシークするようにします。 より高い権限のアクセス許可を要求しないでください。代わりに、Microsoft Graph などの API が提供する多数のアクセス許可を慎重に処理してください。 必要に応じ、最小限のアクセス許可を見つけて使用してください。 ユーザーのプロファイルを更新するコードを記述しなければ、アプリケーションに対して要求することもありません。 ユーザーとグループにのみアクセスするのであれば、ディレクトリ内の他の情報へのアクセスを要求することもありません。 ユーザー メールにアクセスするコードを記述しないのであれば、ユーザーの電子メールを管理するためのアクセス許可を要求することもありません。

ゼロ トラスト アプリケーション開発の場合:

  • アプリケーションの意図と必要なものを定義します。
  • 不正を行う者がアプリを意図していない方法で侵害して使用することができないようにします。
  • 要件を定義する承認の要求を行います (ユーザーのメールの読み取りなど)。

要求を承認できるユーザーは、アクセス許可の要求にいつでも同意できる管理者と、管理者ではない通常のユーザーの 2 つのカテゴリに分類されます。 ただし、テナント管理者は、管理者の同意が必要なアクセス許可と、ユーザーが同意できるアクセス許可に関する最終決定をテナントで行います。

API デザイナーでアクセス許可に対する管理者の同意が必要な場合、そのアクセス許可には常に管理者の同意が必要です。 テナント管理者はそれを優先することはできず、ユーザーの同意のみを要求します。

API デザイナーがユーザーの同意を必要とするアクセス許可を定義すると、テナント管理者は API デザイナーのユーザーの同意候補を優先できます。 テナント管理者は、テナント内の "大きな切り替え" でこれを行うことができます。すべてが管理者の同意を必要とします。 テナント管理者は、アクセス許可と同意の管理により、ユーザーの同意を細分性をより高くして無効にできます。 たとえば、ユーザーが検証済みの発行元からのユーザーの同意要求には同意できても、他の発行元からの同意要求には同意できないようにすることができます。 別の例では、ユーザーのサインインとプロファイルの読み取りを User.Read に許可しても、メールまたはファイルへのアクセス許可を求めるアプリに対しては管理者の同意が必要とすることができます。

API 設計者は提案を行いますが、テナント管理者には最終決定権があります。 そのため、開発者は、アプリが管理者の同意を必要としているタイミングを常に把握しているわけではありません。 それを計画して設計するのは良いことですが、トークン要求を行うときは、何らかの理由で拒否される可能性があることを覚えておいてください。 アクセス許可に管理者の同意が必要なタイミングは、顧客またはユーザーがアプリケーションを実行しているテナント管理者が決定するため、コードではトークンの取得を適切に処理する必要があります。

JavaScript MSAL の使用例

この例の認証では、JavaScript Microsoft Authentication Library (MSAL) を使用して、すべてのアプリ ロジックがブラウザーから実行されるシングル ページ アプリケーション (SPA) でユーザーをサインインさせます。

関連するクイックスタートの記事から、コード サンプルをダウンロードして実行できます。 これは、JavaScript シングルページ アプリケーション (SPA) が、Proof Key for Code Exchange (PKCE) による認証コード フローを使用して、ユーザーをサインインしたり、Microsoft Graph を呼び出したりする仕組みを示しています。 このコード サンプルは、Microsoft Graph API または任意の Web API を呼び出すためのアクセス トークンを取得する方法を示しています。

次のコード例に示すように、ブラウザーで完全に実行されるアプリケーションはパブリック クライアントである必要があるため、パブリック クライアントをインスタンス化します。 ユーザーは、コードがブラウザーにあるときに、アプリケーションの内部情報を取得することができます。

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

その後、MSAL ライブラリを使用します。 MSAL JavaScript には、サインインする特定の API があります。 ブラウザー内で特定の機能を利用する API は 2 つあります。 1 つは、ポップアップ エクスペリエンスでサインインし、もう 1 つは、ブラウザーのリダイレクト エクスペリエンスでサインインします。

次のコード例に示すように、サインイン ポップアップは、ユーザーが signIn 関数を呼び出すことによって実行する必要がある認証を処理します。

function signIn() {

    /**
     * You can pass a custom request object. This overrides the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginPopup(loginRequest)
        .then(handleResponse)
        .catch(error => {
            console.error(error);
        });
}

アプリは、ユーザーの表示名やユーザー ID など、ユーザーに関する情報を取得できます。 次に、アプリでは、MSAL ライブラリ全体で使用するパターンに従って、Microsoft Graph からユーザーの完全なプロファイルを読み取る承認が必要です。

次のコード例に示すように、アプリは AcquireTokenSilent を呼び出して承認を取得しようとします。 Microsoft Entra ID がユーザーと対話せずにトークンを発行できる場合、AcquireTokenSilent はアプリがユーザーの代わりに Microsoft Graph にアクセスするために必要なトークンを返します。

function getTokenPopup(request) {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);
    
    return myMSALObj.`AcquireTokenSilent`(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using popup");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.`AcquireTokenPopup`(request)
                    .then(tokenResponse => {
                        console.log(tokenResponse);
                        return tokenResponse;
                    }).catch(error => {
                        console.error(error);
                    });
            } else {
                console.warn(error);
            }
    });
}

ただし、多くの場合、Microsoft Entra ID は、ユーザーとのやり取りなしではトークンを発行できません (ユーザーがパスワードを変更する、または同意を与えないなど)。 そのため、AcquireTokenSilent はユーザーの操作を必要とするエラーをアプリケーションに返します。 アプリがエラーを受け取ると、AcquireTokenPopup の呼び出しにフォールバックします。

その時点で、Microsoft Entra ID はユーザーとやり取りし、ユーザーを認証し、アプリがユーザーに代わって動作することを承認できます (MFA の実行、パスワードの指定、同意の付与など)。 その後、アプリは、処理を進めるために必要なトークンを取得します。

ゼロ トラストへの企業の取り組みの主なステップは、ユーザー ID とパスワードだけでなく、より強力な認証方法を採用することです。 前のコード例では、企業が選択したより強力な認証方法に移行できます。 たとえば、多要素認証、FIDO2 キーを使用した完全なパスワードレス、Microsoft Authenticator などです。

次のステップ

  • リソースにアクセスするための承認の取得」は、アプリケーション用にリソースのアクセス許可を取得するときにゼロ トラストを確保する最善の方法を理解するのに役立ちます。
  • アプリケーションのアクセス許可戦略の開発」は、資格情報管理に対するアプリケーションのアクセス許可のアプローチを決定するのに役立ちます。
  • トークンのカスタマイズ」では、Microsoft Entra トークンで受け取ることができる情報について説明しています。 最小限の特権でアプリケーションのゼロ トラスト セキュリティを強化しながら、柔軟性と制御性を向上させるようにトークンをカスタマイズする方法について説明しています。
  • トークンでのグループ要求とアプリ ロールの構成」は、アプリ ロール定義を使用してアプリを構成し、セキュリティ グループをアプリ ロールに割り当てる方法を説明しています。 これらの方法は、最小限の特権でアプリケーションのゼロ トラスト セキュリティを強化しながら、柔軟性と制御性を向上させるのに役立ちます。
  • API 保護では、登録を通じて API を保護し、アクセス許可と同意を定義し、ゼロ トラストの目標を達成するためのアクセスを強制するためのベスト プラクティスについて説明します。
  • 別の API からの API の呼び出し」は、ある API で別の API を呼び出す必要がある場合にゼロ トラストを確保し、ユーザーに代わって動作するアプリケーションを安全に開発するのに役立ちます。
  • 承認のベスト プラクティスは、アプリケーションに最適な承認、アクセス許可、および同意モデルを実装するのに役立ちます。
  • ゼロ トラスト ID およびアクセス管理の開発のベスト プラクティス」をアプリケーション開発ライフサイクルで使用して、セキュリティで保護されたアプリケーションを作成します。