次の方法で共有


アプリ ロールとロール要求を使用して Java WebSphere アプリをセキュリティで保護する

この記事では、OpenID Connect を使用してユーザーのサインインを行い、Microsoft Entra ID アプリケーション ロール (アプリ ロール) で認証を行う WebSphere アプリについて説明します。

このアプリケーションは、Microsoft Entra ID のアプリケーション ロールとロール要求機能を使用して、ロールベースのアクセス制御 (RBAC) を実装します。 もう 1 つの方法は、Microsoft Entra ID のグループとグループ要求を使うことです。 Microsoft Entra ID グループとアプリケーション ロールは相互に排他的ではありません。 両方を使用して、アクセスをきめ細かく制御することができます。

また、RBAC にアプリケーション ロールとロール要求を使用することで、認証ポリシーをセキュアに適用することもできます。

このシナリオとサンプルを紹介するビデオ、「アプリ ロール、セキュリティ グループ、スコープ、ディレクトリ ロールを使用した承認をアプリケーションに実装する」をご覧ください。

このシナリオやその他のシナリオでのプロトコルの使用について詳しくは、「認証と承認」を参照してください。

このアプリケーションでは、MSAL for Java (MSAL4J) を使用してユーザーのサインインを行い、Microsoft Entra ID から ID トークンを取得します。

このサンプルは、最初に MSAL for Java (MSAL4J) を使用してユーザーのサインインを行います。 ホーム ページには、ユーザーが ID トークン内の要求を確認するためのオプションが表示されます。 このアプリケーションでは、ユーザーが割り当てられているアプリ ロールに応じて、特権管理者ページまたは通常のユーザー ページを表示することもできます。 これを例示する目的は、アプリケーション内で、ユーザーによる特定の機能やページへのアクセスを、所属するロールに基づいて一部のユーザーに制限する方法を示すことです。

このような承認は、RBAC を使用して実装されます。 RBAC を使用する場合、管理者は、個々のユーザーまたはグループではなく、ロールにアクセス許可を付与します。 その後、管理者はロールをさまざまなユーザーやグループに割り当てて、コンテンツや機能に誰がアクセスできるかを制御します。

このサンプル アプリケーションには、次の 2 つのアプリケーション ロールを定義します。

  • PrivilegedAdmin: 管理者のみページと通常のユーザー ページへのアクセスが許可されます。
  • RegularUser: 通常のユーザー ページへのアクセスが許可されます。

これらのアプリケーション ロールは Azure portal でアプリケーションの登録マニフェストに定義されます。 ユーザーがアプリケーションにサインインすると、Microsoft Entra ID はロール メンバーシップの形式でユーザーに個別に付与された各ロールに対し、ロール要求を出力します。

Azure portal を通じて、ユーザーとグループをロールに割り当てることができます。

Note

https://login.microsoftonline.com/common/ エンドポイントがユーザーのサインイン権限として使用されている場合、テナント内の ゲスト ユーザーにはロール要求が存在しません。 次のような https://login.microsoftonline.com/tenantidテナント ID エンドポイントにユーザーをサインインさせる必要があります。

前提条件

推奨事項

  • Java / Jakarta Servlets に関するある程度の知識。
  • Linux/OSX ターミナルに関するある程度の知識。
  • トークンの検査に必要な jwt.ms
  • ネットワークの活動監視とトラブルシューティングに必要な Fiddler
  • 開発に関する最新の情報について、Microsoft Entra ID ブログを確認してください。

サンプルのセットアップ

次のセクションでは、サンプル アプリケーションを設定する方法を示します。

サンプル リポジトリを複製またはダウンロードする

サンプルを複製するには、Bash ウィンドウを開き、次のコマンドを使用します。

git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 3-java-servlet-web-app/3-Authorization-II/roles

または、ms-identity-msal-java-samples リポジトリに移動し、.zip ファイルでダウンロードして、ハード ドライブに展開します。

重要

Windows でファイル パスの長さが制限を超える場合は、ハード ドライブのルート近くのディレクトリにリポジトリを複製または展開してください。

Microsoft Entra ID テナントにサンプル アプリケーションを登録する

このサンプルには、プロジェクトが 1 つ存在します。 以下の各セクションでは、Azure portal を使用してアプリを登録する方法を説明します。

アプリケーションを作成する Microsoft Entra ID テナントを選択する

テナントを選択するには、次の手順に従います。

  1. Azure portal にサインインします。

  2. ご利用のアカウントが複数の Microsoft Entra ID テナントに存在する場合は、Azure portal の隅にあるプロファイルを選択し、ディレクトリの切り替えを選択して、セッションを目的の Microsoft Entra ID テナントに変更します。

アプリを登録する (java-servlet-webapp-roles)

最初に、クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録するに記載された説明に従って Azure portal に新しいアプリを登録します。

次の手順を実行して、登録を完了します。

  1. 開発者用の Microsoft ID プラットフォームの [アプリの登録] ページに移動します。

  2. [新規登録] を選択します。

  3. 表示される アプリケーションの登録ページで、アプリケーションの登録情報を入力します。

    • 名前セクションに、アプリのユーザーに表示されるわかりやすいアプリケーション名を入力します (例: java-servlet-webapp-roles)。

    • サポートされているアカウントの種類で、次のオプションのいずれかを選択します。

      • 自分のテナントのユーザーのみが使用するアプリケーションをビルドしている場合は (シングルテナント アプリケーション)、この組織のディレクトリ内のアカウントのみを選択します。
    • リダイレクト URI セクションで、コンボ ボックスの Web を選択し、リダイレクト URI: http://localhost:8080/msal4j-servlet-roles/auth/redirect を入力します。

  4. [登録] を選択して、アプリケーションを作成します。

  5. アプリの登録ページで、アプリケーション (クライアント) ID の値を見つけてメモします。 この値は、後ほどアプリの構成ファイルで使用します。

  6. [保存] を選択して変更を保存します。

  7. アプリの登録ページで、ナビゲーション ペインにある 証明書とシークレットを選択してページを開き、シークレットの生成と証明書のアップロードを行います。

  8. [クライアント シークレット] セクションで、 [新しいクライアント シークレット] を選択します。

  9. キーの説明 (例: アプリのシークレット) を入力します。

  10. 1 年2 年無期限のいずれかの期間を選びます。

  11. [追加] を選択します。 生成された値が表示されます。

  12. 生成した値をコピーしてから保存します。 この値は後ほど、コードの構成ファイルに使用します。 この値は二度と表示されず、他の方法でも取得はできません。 そのため、必ず Azure portal から保存した後に、他の画面やペインに移動してください。

アプリケーション ロールの定義

次の手順に従って、アプリのロールを定義します。

  1. 同じアプリの登録で、ナビゲーション ペインからアプリ ロールを選択します。

  2. アプリ ロールの作成を選択し、次の値を入力または選択します。

    • 表示名で、PrivilegedAdmin などのわかりやすい名前を入力します。
    • 許可されるメンバーの種類で、ユーザーを選択します。
    • PrivilegedAdmin と入力します。
    • 説明管理ページを表示する権限を持つ管理者と入力します。
  3. アプリ ロールの作成を選択し、次の値を入力または選択します。

    • 表示名に、RegularUser などのわかりやすい名前を入力します。
    • 許可されるメンバーの種類で、ユーザーを選択します。
    • RegularUser と入力します。
    • 説明ユーザー ページを表示できる通常のユーザーと入力します。
  4. [適用] を選択して変更を保存します。

アプリケーション ロールにユーザーを割り当てる

先ほどに定義したアプリ ロールにユーザーを追加するには、「ロールにユーザーとグループを割り当てる」のガイドラインに従ってください。


アプリの登録を使用するためにアプリ (java-servlet-webapp-roles) を構成する

アプリを構成するには、次の手順に従います。

Note

以降の手順では、ClientIDApplication ID または AppId と同じです。

  1. IDE でプロジェクトを開きます。

  2. authentication.properties ファイルを開きます。

  3. {enter-your-tenant-id-here} という文字列を見つけます。 既存の値を Microsoft Entra ID のテナント ID に置き換えます。

  4. {enter-your-client-id-here} という文字列を見つけて、既存の値をアプリケーション ID または Azure portal からコピーした java-servlet-webapp-call-graph アプリケーションの clientId に変更します。

  5. {enter-your-client-secret-here} という文字列を見つけて、既存の値を、Azure portal で java-servlet-webapp-roles アプリを作成するときに保存した値に置き換えます。

  6. app.roles プロパティを見つけて、値が app.roles=admin PrivilegedAdmin, user RegularUser に設定されていることを確認するか、指定したロールの名前に置き換えます。

サンプルをビルドする

Maven を使用してサンプルをビルドするには、サンプルの pom.xml ファイルが含まれているディレクトリに移動して、次のコマンドを実行します。

mvn clean package

このコマンドを実行すると、.war ファイルが作成されます。これはさまざまなアプリケーション サーバーで実行できます。

サンプルを実行する

以降の手順では、WebSphere をインストールし、サーバーが設定されていることを前提としています。 サーバーのセットアップの基本について、「Azure 仮想マシンで (従来の) WebSphere Application Server クラスターをデプロイする」のガイダンスを参照してください。

WebSphere にデプロイする前に、次の手順を使用してサンプル本体の構成を変更してから、パッケージをビルドまたはリビルドする必要があります。

  1. アプリの authentication.properties ファイルに移動し、app.homePage の値を、使用を計画しているサーバーの URL とポート番号に変更します (次の例を参照)。

    # app.homePage is by default set to dev server address and app context path on the server
    # for apps deployed to azure, use https://your-sub-domain.azurewebsites.net
    app.homePage=https://<server-url>:<port-number>/msal4j-servlet-auth/
    
  2. このファイルを保存した後、次のコマンドを使用してアプリをリビルドします。

    mvn clean package
    
  3. コードのビルドが終了したら、.war ファイルをターゲット サーバーのファイル システムにコピーします。

また、Azure アプリの登録でも同じ変更を行う必要があります。Azure portal で、認証タブのリダイレクト URI の値に対し、これを設定してください。

  1. 開発者用の Microsoft ID プラットフォームの [アプリの登録] ページに移動します。

  2. 検索ボックスを使用してアプリの登録を検索します (例: java-servlet-webapp-authentication)。

  3. 名前を選択して、アプリの登録を開きます。

  4. コマンドメニューから 認証 を選択します。

  5. Web - リダイレクト URI セクションで、URI の追加を選択します。

  6. アプリの URI を、/auth/redirect を追加して入力します (例: https://<server-url>:<port-number>/auth/redirect)。

  7. [保存] を選択します。

WebSphere の Integrated Solutions Console を使用してサンプルをデプロイするには、次の手順に従います。

  1. アプリケーション タブで、新しいアプリケーションを選択し、新しいエンタープライズ アプリケーションを選択します。

  2. ビルドした .war ファイルを選択し、Web モジュールのマップ コンテキスト ルートのインストール手順が表示されるまで次へを選択します。 その他の既定の設定はそのままで問題ありません。

  3. コンテキスト ルートの場合は、サンプル構成/Azure アプリの登録で設定した 'リダイレクト URI' のポート番号の後と同じ値に設定します。 つまり、リダイレクト URI が http://<server-url>:9080/msal4j-servlet-auth/ である場合、コンテキスト ルートはmsal4j-servlet-auth になります。

  4. 完了 を選択します。

  5. アプリケーションのインストールが完了したら、アプリケーションタブの WebSphere エンタープライズ アプリケーション セクションに移動します。

  6. アプリケーションの一覧からインストールした .war ファイルを選択し、開始を選択してデプロイします。

  7. デプロイが完了したら、http://<server-url>:9080/{whatever you set as the context root} に移動します。アプリケーションが表示されます。

サンプルの確認

次の手順に従ってサンプルを操作します。

  1. サインインまたはサインアウトの状態が、画面の中央に表示されます。
  2. 画面の隅にある状況依存ボタンを選択します。 このボタンは、アプリを最初に実行するときにサインインと表示します。
  3. 次のページに記載された指示に従い、Microsoft Entra ID テナントのアカウントでサインインします。
  4. 同意画面に、必要となるスコープが表示されます。
  5. 状況依存ボタンの表示がサインアウトに変わり、ユーザー名が表示されます。
  6. ID トークンの詳細を選択すると、ID トークンのデコードされた要求の一部が表示されます。
  7. 管理者のみを選択し、/admin_onlyページを表示します。 このページを表示できるのは、PrivilegedAdmin のアプリ ロールを持つユーザーだけです。 それ以外のユーザーには、承認エラー メッセージが表示されます。
  8. 通常のユーザーを選択し、/regular_userページを表示します。 このページを表示できるのは、RegularUser または PrivilegedAdmin のアプリ ロールを持つユーザーだけです。 それ以外のユーザーには、承認エラー メッセージが表示されます。
  9. 画面隅のボタンを使用してサインアウトします。

コードについて

このサンプルでは、MSAL for Java (MSAL4J) を使用してユーザーがサインインし、ロール要求を含む ID トークンを取得します。 存在するロール要求に基づいて、サインインしているユーザーは、Admins OnlyRegular Users の保護されたページのいずれにもアクセスできないか、1 つ、または両方にアクセスできます。

このサンプルの動作をレプリケートする場合は、src/main/java/com/microsoft/azuresamples/msal4j フォルダーにある pom.xml ファイルと、helpers フォルダーおよび authservlets フォルダーの内容をコピーします。 authentication.properties ファイルも必要です。 これらのクラスとファイルには、さまざまなアプリケーションで使用できる汎用コードが含まれています。 サンプルの残りもコピーできますが、他のクラスとファイルは、このサンプルの目的に合わせて特別にビルドされたものです。

Contents

次の表に、サンプル プロジェクト フォルダーの内容を示します。

ファイル/フォルダー 説明
src/main/java/com/microsoft/azuresamples/msal4j/roles/ このディレクトリには、アプリの基幹業務ロジックを定義するクラスが含まれています。
src/main/java/com/microsoft/azuresamples/msal4j/authservlets/ このディレクトリには、サインインとサインアウトのエンドポイントに使用されるクラスが含まれています。
____Servlet.java 使用可能なすべてのエンドポイントは、末尾が ____Servlet.java である .java クラスに定義されます。
src/main/java/com/microsoft/azuresamples/msal4j/helpers/ 認証に使用するヘルパー クラス。
AuthenticationFilter.java 認証されていない要求を、保護されたエンドポイントの 401 ページにリダイレクトします。
src/main/resources/authentication.properties Microsoft Entra ID とプログラム構成。
src/main/webapp/ このディレクトリには UI - JSP テンプレートが含まれています
CHANGELOG.md サンプルに対する変更の一覧。
CONTRIBUTING.md サンプルに貢献するためのガイドライン。
ライセンス サンプルのライセンス。

ID トークンのロール要求を処理する

トークンのロール要求には、サインインしているユーザーが割り当てられているロールの名前が含まれます (次の例を参照)。

{
  ...
  "roles": [
    "Role1",
    "Role2",]
  ...
}

ConfidentialClientApplication

ConfidentialClientApplication インスタンスが AuthHelper.java ファイルに作成されます (次の例を参照)。 このオブジェクトにより Microsoft Entra 認証 URL の作成と、アクセス トークンの認証トークンの交換が行われます。

// getConfidentialClientInstance method
IClientSecret secret = ClientCredentialFactory.createFromSecret(SECRET);
confClientInstance = ConfidentialClientApplication
                     .builder(CLIENT_ID, secret)
                     .authority(AUTHORITY)
                     .build();

インスタンス化には次のパラメーターが使用されます。

  • アプリのクライアント ID。
  • クライアント シークレット。機密クライアント アプリケーションに必要です。
  • Microsoft Entra ID 認証機関。Microsoft Entra テナント ID が含まれます。

上記の例では、Config.java ファイルにあるプロパティ リーダ0を使用して、値が authentication.properties ファイルから読み取られます。

ステップバイステップのチュートリアル

次の手順で、アプリの機能をチュートリアルで紹介します。

  1. サインイン プロセスの最初のステップでは、Microsoft Entra ID テナントの /authorize エンドポイントに要求を送信します。 承認要求の URL を作成するには、MSAL4J の ConfidentialClientApplication インスタンスを利用します。 アプリでブラウザーをこの URL にリダイレクトし、ユーザーはそこでサインインします。

    final ConfidentialClientApplication client = getConfidentialClientInstance();
    AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters.builder(Config.REDIRECT_URI, Collections.singleton(Config.SCOPES))
            .responseMode(ResponseMode.QUERY).prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build();
    
    final String authorizeUrl = client.getAuthorizationRequestUrl(parameters).toString();
    contextAdapter.redirectUser(authorizeUrl);
    

    このコードの機能を次の一覧で示します。

    • AuthorizationRequestUrlParameters: AuthorizationRequestUrl を作成するために設定する必要があるパラメーター。
    • REDIRECT_URI: Microsoft Entra ID がユーザー資格情報を収集した後、認証コードと共にブラウザーをリダイレクトする場所。 これは Azure portal にある Microsoft Entra ID アプリ登録のリダイレクト URI と一致する必要があります。
    • SCOPES: スコープはアプリケーションで要求されるアクセス許可です。
      • 通常、ID トークンの応答を受信するには、openid profile offline_access の 3 つのスコープがあれば十分です。
      • authentication.properties ファイルに、アプリで要求されるすべてのスコープの一覧が入力されています。 User.Readなど、その他のスコープを追加できます。
  2. Microsoft Entra ID により、ユーザーにサインイン プロンプトが表示されます。 サインインが成功すると、ユーザーのブラウザーはアプリのリダイレクト エンドポイントにリダイレクトされます。 このエンドポイントへの有効な要求には、、認証コードが含まれています。

  3. その後、この承認コードは、ConfidentialClientApplication のインスタンスによって、Microsoft Entra ID の ID トークンとアクセス トークンに交換されます。

    // First, validate the state, then parse any error codes in response, then extract the authCode. Then:
    // build the auth code params:
    final AuthorizationCodeParameters authParams = AuthorizationCodeParameters
            .builder(authCode, new URI(Config.REDIRECT_URI)).scopes(Collections.singleton(Config.SCOPES)).build();
    
    // Get a client instance and leverage it to acquire the token:
    final ConfidentialClientApplication client = AuthHelper.getConfidentialClientInstance();
    final IAuthenticationResult result = client.acquireToken(authParams).get();
    

    このコードの機能を次の一覧で示します。

    • AuthorizationCodeParameters: ID トークンやアクセス トークンと承認コードを交換するために設定する必要があるパラメーター。
    • authCode: リダイレクト エンドポイントで受信された承認コード。
    • REDIRECT_URI: 前のステップで使用したリダイレクト URI を、再度渡す必要があります。
    • SCOPES: 前のステップで使用したスコープを、再度渡す必要があります。
  4. acquireToken が成功すると、トークン クレームが抽出されます。 nonce チェックに合格すると、結果は context (IdentityContextData のインスタンス) に配置されて、セッションに保存されます。 その後、アプリケーションでそれにアクセスする必要があるときは常に、セッションから (IdentityContextAdapterServlet のインスタンスを使用して) IdentityContextData をインスタンス化できます。

    // parse IdToken claims from the IAuthenticationResult:
    // (the next step - validateNonce - requires parsed claims)
    context.setIdTokenClaims(result.idToken());
    
    // if nonce is invalid, stop immediately! this could be a token replay!
    // if validation fails, throws exception and cancels auth:
    validateNonce(context);
    
    // set user to authenticated:
    context.setAuthResult(result, client.tokenCache().serialize());
    

ルートを保護する

サンプル アプリでルートへのアクセスをフィルター処理する方法については、「AuthenticationFilter.java」を参照してください。 authentication.properties ファイルを見ると、認証済みのユーザーだけがアクセスできるルートが app.protect.authenticated プロパティにコンマで区切って入力されていることがわかります (次の例を参照)。

# for example, /token_details requires any user to be signed in and does not require special roles claim(s)
app.protect.authenticated=/token_details

app.protect.roles でコンマ区切りのルール セットに入力されたすべてのルートでは、認証されていないユーザーに対する制限がないこともわかります (次の例を参照)。 ただし、これらのルートには、アプリ ロール メンバーシップのリストもスペース区切りで入力されています。認証後に、対応するロールの少なくとも 1 つを持つユーザーのみがこれらのルートにアクセスできます。

# local short names for app roles - for example, sets admin to mean PrivilegedAdmin (useful for long rule sets defined in the next key, app.protect.roles)
app.roles=admin PrivilegedAdmin, user RegularUser

# A route and its corresponding <space-separated> role(s) that can access it; the start of the next route & its role(s) is delimited by a <comma-and-space-separator>
# this says: /admins_only can be accessed by PrivilegedAdmin, /regular_user can be accessed by PrivilegedAdmin role and the RegularUser role
app.protect.roles=/admin_only admin, /regular_user admin user

スコープ

スコープはアプリケーションが要求するアクセス レベルを Microsoft Entra ID に通知します。

Microsoft Entra ID は、要求されたスコープに基づいて、サインイン時にユーザーに同意ダイアログを表示します。 ユーザーが 1 つ以上のスコープに同意してトークンを取得すると、同意先のスコープが結果の access_token にエンコードされます。

アプリケーションで要求されるスコープについては、authentication.properties を参照してください。 これらの 3 つのスコープは MSAL で要求され、既定で Microsoft Entra ID によって指定されます。

詳細

次のステップ

Azure Virtual Machines にある従来の WebSphere に Java WebSphere アプリをデプロイする