次の方法で共有


Node.js Web アプリケーションでロールベースのアクセス制御を使用する

適用対象: 内側に灰色の X 記号がある白い円。 従業員テナント 内側に白いチェック マーク記号がある緑の円。 外部テナント (詳細情報)

ロールベースのアクセス制御 (RBAC) は、アプリケーションにおいて認可を実施するメカニズムです。 Microsoft Entra 外部 ID を使用すると、アプリケーションのアプリケーション ロールを定義し、それらのロールをユーザーとグループに割り当てることができます。 ユーザーまたはグループに割り当てたロールによって、アプリケーション内のリソースと操作へのアクセスのレベルが定義されます。 認証されたユーザーに対して外部 ID からアクセス トークンが発行されると、セキュリティ トークンのロール要求に、ユーザーまたはグループを割り当てたロールの名前が含まれます。

ユーザーのグループ メンバーシップを返すように、外部テナントを構成することもできます。 その後、開発者はアプリケーションに RBAC を実装するためにセキュリティ グループを使用できます。この場合、特定グループ内でのユーザーのメンバーシップが、ロール メンバーシップとして解釈されます。

ユーザーとグループをロールに割り当てると、"ロール" 要求がセキュリティ トークンに出力されます。 ただし、セキュリティ トークンで "グループ" メンバーシップ要求を出力するには、顧客のテナントに追加の構成が必要です。

この記事では、Node.js Web アプリのセキュリティ トークンで、ユーザー ロールまたはグループ メンバーシップ、あるいはその両方を要求として受け取る方法について説明します。

前提条件

Node.js Web アプリでグループとロールの要求を受信する

顧客のテナントを構成したら、クライアント アプリで "ロール" と "グループ" の要求を取得できます。 "ロール" と "グループ" の要求はどちらも ID トークンとアクセス トークンに存在しますが、クライアント アプリでは ID トークンでこれらの要求をチェックするだけで、クライアント側で認可を実装できます。 API アプリでは、アクセス トークンを受け取ったときにこれらの要求を取得することもできます。

次のコード スニペットの例に示すように、"ロール" の要求値をチェックします。

const msal = require('@azure/msal-node');
const { msalConfig, TENANT_SUBDOMAIN, REDIRECT_URI, POST_LOGOUT_REDIRECT_URI } = require('../authConfig');

...
class AuthProvider {
...
    async handleRedirect(req, res, next) {
        const authCodeRequest = {
            ...req.session.authCodeRequest,
            code: req.body.code, // authZ code
            codeVerifier: req.session.pkceCodes.verifier, // PKCE Code Verifier
        };
    
        try {
            const msalInstance = this.getMsalInstance(this.config.msalConfig);
            const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);
            let roles = tokenResponse.idTokenClaims.roles;
        
            //Check roles
            if (roles && roles.includes("Orders.Manager")) {
                //This user can view the ID token claims page.
                res.redirect('/id');
            }
            
            //User can only view the index page.
            res.redirect('/');
        } catch (error) {
            next(error);
        }
    }
...
}

複数のロールにユーザーを割り当てる場合、roles 文字列には、Orders.Manager,Store.Manager,... のように、すべてのロールがコンマで区切られて含まれています。 次の条件を処理するようにアプリケーションをビルドしてください。

  • トークンに roles 要求がない
  • ユーザーがロールに割り当てられていない
  • 複数のロールにユーザーを割り当てる場合の roles 要求内の複数の値

次のコード スニペットの例に示すように、"グループ" の要求値をチェックすることもできます。

const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);
let groups = tokenResponse.idTokenClaims.groups;

グループの要求値は、グループの objectId です。 ユーザーが複数のグループのメンバーである場合、groups 文字列には、7f0621bc-b758-44fa-a2c6-...,6b35e65d-f3c8-4c6e-9538-... のように、すべてのグループがコンマで区切られて含まれています。

Note

ユーザーに Microsoft Entra の組み込みロールまたは一般にディレクトリ ロールと呼ばれるロールを割り当てると、それらのロールはセキュリティ トークンの グループ 要求に表示されます。

グループの超過分の処理

セキュリティ トークンのサイズが HTTP ヘッダー サイズの上限を超えないよう、外部 ID では、"グループ" 要求に含まれるオブジェクト ID の数が制限されます。 超過制限は、SAML トークンの場合は 150、JWT トークンの場合は 200 です。 ユーザーが多数のグループに属していて、すべてのグループに対して要求する場合は、この制限を超える可能性があります。

ソース コードでグループの超過分を検出する

グループの超過分を回避できない場合は、コードで処理する必要があります。 超過制限を超えた場合、トークンには "グループ" 要求は含まれません。 代わりに、トークンには、配列の "グループ" メンバーを含む _claim_names 要求が含まれます。 そのため、超過分が発生したことを伝えるために、_claim_names 要求の存在をチェックする必要があります。 次のコード スニペットでは、グループの超過分を検出する方法を示しています。

const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);

if(tokenResponse.idTokenClaims.hasOwnProperty('_claim_names') && tokenResponse.idTokenClaims['_claim_names'].hasOwnProperty('groups')) {
    //overage has occurred
}

トークンでのグループ要求とアプリ ロールの構成」の記事の手順を使用して、グループの超過分が発生した場合にグループ全体の一覧に対する要求を確認します。

Node.js Web アプリでグループとロールの値を使用する方法

クライアント アプリでは、サインインしているユーザーが保護されたルートにアクセスしたり、API エンドポイントを呼び出したりするために必要なロールを持っているかどうかを確認できます。 これを行うには、ID トークンで roles 要求を確認します。 この保護をアプリに実装するには、カスタム ミドルウェアを使用してガードを構築します。

サービス アプリ (API アプリ) では、API エンドポイントを保護することもできます。 クライアント アプリによって送信されたアクセス トークンを検証した後、アクセス トークンのペイロード要求の "ロール" または "グループ" 要求をチェックできます。

アプリ ロールまたはグループを使用しますか?

この記事では、"アプリ ロール" または "グループ" を使用して、アプリケーションに RBAC を実装できることを学習しました。 アプリケーション レベルでアクセスや権限を管理するときに、よりきめ細かく制御できるので、アプリ ロールを使うことをお勧めします。 アプローチの選択方法について詳しくは、「アプローチの選択」を参照してください。

次の手順