OpenID Connect を使用した Microsoft Entra ID による WebSphere Liberty/Open Liberty アプリケーションの保護
この記事では、OpenID Connect (OIDC) を使用して、Microsoft Entra ID で IBM WebSphere Liberty/Open Liberty アプリケーションを保護する方法を説明します。
この記事では、次のことについて説明します。
- Microsoft Entra ID を使用して、OIDC プロバイダーを設定します。
- OIDC を使用して WebSphere Liberty/Open Liberty アプリを保護します。
- WebSphere Liberty/Open Liberty アプリを実行してテストします。
前提条件
- Azure サブスクリプション。 Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。
- 少なくともクラウド アプリケーション管理者 Microsoft Entra ロールを持つ Azure ID。 詳細については、「Microsoft Entraロールの割り当て一覧表示」および「Microsoft Entra 組み込みロール」を参照してください。
- Microsoft Entra テナント。 既存のテナントがない場合は、「Quickstart: テナントの設定」を参照してください。
- Unix のようなオペレーティング システム (Ubuntu、macOS、Linux 用 Windows サブシステムなど) がインストールされているローカル マシン。
- Git.
- Java SE 実装バージョン 21 以降 (OpenJDK の Microsoft ビルドなど) をインストールします。
- Maven バージョン 3.9.3 以降。
Microsoft Entra ID を使用して、OIDC プロバイダーを設定する
OpenID Connect は、Microsoft Entra ID で十分にサポートされている業界標準の認証プロトコルです。 このセクションでは、Microsoft Entra ID を使用して OIDC を設定し、WebSphere Liberty/Open Liberty アプリで使用します。 後のセクションでは、Microsoft Entra テナントのユーザーを認証および承認するために、OIDC を使用して、WebSphere Liberty/Open Liberty アプリを構成します。
Microsoft Entra テナントにユーザーを作成する
まず、「ユーザーを作成、招待、削除する方法」の手順に従って、Microsoft Entra テナントに 2 人のユーザーを作成します。 必要なのは、「新しいユーザーの作成」セクションだけです。 この記事を読み進める際には、以下の手順に従い、Microsoft Entra テナントにユーザーを作成した後でこの記事に戻ってください。
アプリで「管理者」として機能するユーザーを作成するには、次の手順に従います。
- [新しいユーザーの作成]セクションの [基本] タブに移動したら、次の手順を実行します。
[ユーザー プリンシパル名] に「管理者」と入力します。後でアプリにサインインするときに使用できるように、値を保存します。
[メール ニックネーム] で、[Derive from user principal name] (ユーザー プリンシパル名から派生する) を選択します
[表示名] に「管理者」と入力します。
[パスワード] で、[パスワードの自動生成] を選択します。 後でアプリにサインインするときに使用するパスワード値をコピーして保存します。
[アカウントが有効] を選択します。
[確認と作成]>[作成] の順に選択します。 ユーザーが作成されるまで待ちます。
少し待ってから、更新] を選択します。 新しいユーザーがリストに表示されます。
アプリ内で「ユーザー」として機能するユーザーを作成するには、これらの手順を繰り返しますが、次の値を使用します。
- [ユーザー プリンシパル名] に、「ユーザー」と入力します。
- [表示名] に「ユーザー」と入力します。
Microsoft Entra ID でアプリケーションの登録
次に、以下の手順に従ってアプリケーションを登録するには、「クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する」を参照してください。 この記事を読みながら次の指示に従い、アプリケーションを登録して構成した後でこの記事に戻ってください。
- 「アプリケーションを登録する」セクションにアクセスしたら、次の手順を実行します。
- [サポートされているアカウントの種類] で、 [Accounts in this organizational directory only (Default Directory only - Single tenant)] (この組織ディレクトリのアカウントのみ (既定のディレクトリのみ - シングル テナント)) を選択します。
- 登録が完了したら、アプリケーション (クライアント) ID と ディレクトリ (テナント) ID 値を保存して、後でアプリ構成で使用します。
- [リダイレクト URI の追加] セクションにアクセスしたら、今の時点では手順をスキップします。 この記事では、後でサンプル アプリをローカルで実行してテストするときに、リダイレクト URI を追加します。
- [資格情報の追加] セクションに到達したら、 [クライアント シークレットの追加] タブを選択します。
- クライアント シークレットを追加するときは、後でアプリ構成で使用する [クライアント シークレット] 値を書き留めます。
アプリケーションにアプリ ロールを追加する
次に、「アプリケーションにアプリ ロールを追加し、トークンで受け取る」の手順に従って、アプリケーションにアプリ ロールを追加します。 必要なのは、「アプリケーションのロール宣言」セクションと「ユーザーとグループを Microsoft Entra ロールに割り当てる」セクションだけです。 この記事を読み進める際には次の指示に従い、アプリケーションのロール宣言が完了したらこの記事に戻ってください。
「アプリケーションのロールを宣言する」セクションに到達したら、[アプリ ロール] UI を使用して、管理者と通常のユーザーのロールを作成します。
次の値を使用して管理者ユーザー ロールを作成します。
- [表示名] に「管理者」と入力します。
- [許可されたメンバーの種類] で [ユーザー/グループ] を選択します。
- [値] には、「admin」と入力します。
- [説明] に「管理者」と入力します。
- [Do you want to enable this app role?] (このアプリのロールを有効にしますか?) を選択します。
適用を選択します。 ロールが作成されるまで待ちます。
同じ手順で、次の値を使用して通常のユーザー ロールを作成します。
- [表示名] に「ユーザー」と入力します。
- [値] には、「管理者」と入力します。
- [説明] には、「ユーザー」と入力します。
「Microsoft Entra ロールへのユーザーとグループの割り当て」セクションに到達したら、次の手順を使用します。
[Add user/group](ユーザーまたはグループの追加) を選択します。
[割り当ての追加] ウィンドウの [ユーザー]で、ユーザー [管理者] を選択し、[ロールの選択] を選択して、ロール [管理者] を選択します。次に、[割り当て] を選択します。 アプリケーションの割り当てが成功するまで待ちます。 テーブルを横にスクロールして、[割り当てられたロール] 列を表示する必要がある場合があります。
前の手順を繰り返して、ユーザー ロールをユーザー [ユーザー] に割り当てます。
[更新] を選択すると、[ユーザーとグループ] ペインに割り当てられているユーザーとロールが表示されます。
ビューを画像のように見えるようにするには、列ヘッダーの幅を調整する必要がある場合があります。
「アプリケーションにアプリ ロールを追加し、トークンで受け取る」の手順は実行しないでください。
OpenID Connect を使用して WebSphere Liberty/Open Liberty アプリを保護する
このセクションでは、OIDC を使用して、Microsoft Entra テナント内のユーザーを認証および承認する WebSphere Liberty/Open Liberty アプリを保護します。 また、ロールベースのアクセス制御 (RBAC) を使用して、アプリの特定の部分へのアクセス権をユーザーに付与する方法についても説明します。 このアプリでは、Jakarta Servlet の仕様のプログラムによるセキュリティ ポリシー構成を使用します。 Jakarta EE は、RESTful Web サービスもサポートします。 RESTful Web サービス アプリケーションのセキュリティ保護に関する記事については、「次の手順」セクションを参照してください。
このクイック スタート用のサンプル WebSphere Liberty/Open Liberty アプリは、liberty-entra-id リポジトリの GitHub にあります。
認証と承認を有効にしてアプリのセキュリティを確保する
アプリには、次のコード例に示すように、index.html で定義されたウェルカム ページ リソースがあります。 このページには、認証されていないユーザーがアクセスできます。 ウェルカム ページのルート パスは、/
にあります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Greeting</title>
</head>
<body>
<h1>Hello, welcome to Open Liberty/WebSphere Liberty and Microsoft Entra ID integration!</h1>
<h1>
<a href="/profile/user">Sign in as user</a>
</h1>
<h1>
<a href="/profile/admin">Sign in as admin</a>
</h1>
</body>
</html>
ウェルカム ページから、ユーザーはアプリにサインインしてプロファイル ページにアクセスできます。 ウェルカム ページには、ユーザーまたは管理者としてサインインするためのリンクがあります。リンクはそれぞれ /profile/user
と /profile/admin
にあります。
/profile/user
と /profile/admin
の両方のリンクは、次のコード例に示すように、ProfileServlet.java で定義されている Profile Servlet を指します。 この Servlet には、注釈 jakarta.servlet.annotation.ServletSecurity
と注釈 jakarta.servlet.annotation.HttpConstraint
を使用して認証されたユーザーのみがアクセスできます。 属性 rolesAllowed = {"users"}
は、セキュリティ ロール users
を持つ認証済みユーザーのみが /profile
パスにアクセスできるように指定します。 認証済みユーザーは、Liberty 構成ファイルである server.xml の users
ロールに自動的に割り当てられます。
package com.example;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.ibm.websphere.security.social.UserProfileManager;
import java.util.List;
@WebServlet(name = "ProfileServlet", urlPatterns = {"/profile/user","/profile/admin"})
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"users"},
transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL))
public class ProfileServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<?> roles = UserProfileManager.getUserProfile().getIdToken().getClaims().getClaim("roles",
List.class);
String path = request.getServletPath();
if (path.equals("/profile/admin") && (null == roles || !roles.contains("admin"))) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
String username = request.getUserPrincipal().getName();
request.setAttribute("name", username);
request.setAttribute("roles", roles);
request
.getRequestDispatcher("/profile.jsp")
.forward(request, response);
}
}
Profile Servlet は、ID トークンからユーザーのロールを取得し、ユーザーが /profile/admin
パスにアクセスしようとした際に、ユーザーが admin
ロールを保持しているかを確認します。 ユーザーが admin
ロールを保持していない場合、Servlet は 403 Forbidden エラーを返します。 その他の場合、Servlet はユーザーの名前を取得し、ユーザーの名前とロールを使用して要求をプロファイル・ページに転送します。
プロファイル ページは、次の例に示すように、profile.jsp で定義されます。 このページには、ユーザー名とロールが表示されます。 プロファイル ページには、/logout
のサインアウト リンクもあります。 プロファイル ページは JSP (Jakarta Server Pages) と記述されています。 ページでの ${}
式の使用に注意してください。 ${}
は、Jakarta Expression Language (EL) の使用を示します。 EL 式は、ページがレンダリングされるときに、対応する変数の値に置き換えられます。 EL 仕様の詳細については、「次の手順」を参照してください。
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Profile</title>
</head>
<body>
<h1>Hello, ${name}</h1>
<h2>Roles</h2>
<ul>
<c:forEach var="role" items="${roles}">
<li>${role}</li>
</c:forEach>
</ul>
<h1>
<b><a href="/logout">Sign out</a></b>
</h1>
</body>
</html>
ユーザーがサイン アウトするリンクを選択する際、アプリは、サイン アウト Servlet を呼び出します。これは、次のコード例で示すように LogoutServlet.java で定義されます。 サイン アウト Servlet は、request.logout()
メソッドを呼び出して、ユーザーをサイン アウトし、ユーザーをウェルカム ページにリダイレクトします。
package com.example;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.ServletSecurity;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "LogoutServlet", urlPatterns = "/logout")
@ServletSecurity(value = @HttpConstraint(rolesAllowed = {"users"},
transportGuarantee = ServletSecurity.TransportGuarantee.CONFIDENTIAL))
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
request.logout();
response.sendRedirect("/");
}
}
WebSphere Liberty/Open Liberty アプリを実行してテストする
このセクションでは、WebSphere Liberty/Open Liberty アプリを実行してテストし、OIDC プロバイダーとして Microsoft Entra ID を使用してどのように動作するかを確認します。
アプリケーション登録にリダイレクト URI を追加する
アプリをローカルで正常に実行してテストするには、アプリ登録にリダイレクト URI を追加する必要があります。 「クイック スタート: マイクロソフト ID プラットフォームを使用してアプリケーションを登録する」の「リダイレクト URI を追加する」セクションの手順を実行して、次の値をしっ要します。
- [プラットフォームの構成] で [Web] を選びます。
- [リダイレクト URI] に「
https://localhost:9443/ibm/api/social-login/redirect/liberty-entra-id
」を入力します。
サンプルを準備する
サンプル アプリを準備するには、次の手順を実行します。
次のコマンドを使用して、GitHub からサンプル アプリを複製します。
git clone https://github.com/Azure-Samples/liberty-entra-id cd liberty-entra-id git checkout 2024-09-26
HEAD がデタッチされた状態であることを示すメッセージが表示された場合、このメッセージは無視しても問題ありません。 このメッセージは、タグをチェックアウトしたという意味です。
次のコマンドを使用して、前に書き留めた値で次の環境変数を定義します。
export CLIENT_ID==<application/client-ID> export CLIENT_SECRET=<client-secret> export TENANT_ID=<directory/tenant-ID>
これらの環境変数は、WebSphere Liberty/Open Liberty の OIDC の組み込みサポートの値を提供します。 Liberty server.xml の対応する OIDC 構成を次の例に示します。
<oidcLogin id="liberty-entra-id" clientId="${client.id}" clientSecret="${client.secret}" discoveryEndpoint="https://login.microsoftonline.com/${tenant.id}/v2.0/.well-known/openid-configuration" signatureAlgorithm="RS256" userNameAttribute="preferred_username" />
構成ファイルで変数の値が定義されていない場合、WebSphere Liberty/Open Liberty は、その名前付け規則に従って環境変数から値を読み取ります。 名前付け変換の詳細については、「可変置換の優先順位」を参照してください。
WebSphere Liberty/Open Liberty アプリを実行する
liberty-maven-plugin
を使用してアプリを実行できます。 アプリを実行するには、次のメソッドのいずれかを選択します。
Note
WebSphere Liberty/Open Liberty が Microsoft Entra ID に接続できるようにするには、前のセクションで示した環境変数を定義したシェルでコマンドを必ず実行してください。
開発モードでアプリを実行する:
mvn liberty:dev
ランタイム モードでアプリを実行する:
mvn liberty:run
さまざまなモードを試す場合は、Ctrl+C を使用してアプリを停止し、別のモードでアプリを実行します。
WebSphere Liberty/Open Liberty アプリをテストする
アプリが実行されたら、プライベート タブで Web ブラウザーを開き、https://localhost:9443
に移動します。 証明書は自己署名されているため、証明書に関する警告が表示されることがあります。 警告を正常に無視してサイトに進むことができます。
ウェルカム ページが表示され、ユーザーまたは管理者としてサインインするためのリンクが表示されます。プライベート タブを使用すると、通常のブラウザーで実行されている既存の Microsoft Entra ID アクティビティが汚染されることがなくなります。
2 人のユーザーの資格情報を収集する
この記事では、Microsoft Entra ID はサインイン用のユーザー ID として各ユーザーのメール アドレスを使用します。 管理者ユーザーと通常ユーザーのメール アドレスを取得するには、次の手順に従います。
- クラウド アプリケーション管理者以上として Microsoft Entra 管理センターにサインインします。
- 複数のテナントにアクセスできる場合は、トップ メニューの [設定] アイコン ( ) を使用して、[ディレクトリ + サブスクリプション] メニューからアプリケーションを登録するテナントに切り替えます。
- [ID] > [ユーザー] > [すべてのユーザー] を参照します。
- 一覧で管理者ユーザーを見つけて選択します。
- [ユーザー プリンシパル名] フィールドを見つけます。
- フィールドの値の横にあるコピー アイコンを使用して、ユーザーのメール アドレスをクリップボードに保存します。 後で使用するために値を保存します。
- 通常のユーザーのメール アドレスを取得するには、同じ手順に従います。
管理者ユーザーと、ユーザーの作成時に設定した通常のユーザーのパスワードを使用します。
アプリの機能を実行する
機能を実行するには、次の手順に従います。
[ユーザーとしてサインイン] リンクを選択します。 先ほど作成した通常のユーザーとしてサインインします。 サインインすると、Microsoft Entra ID によってプロファイル ページにリダイレクトされ、名前とロールが表示されます。
初回サインイン時は、パスワードを更新するように求められます。 手順に従ってパスワードを更新します。
メッセージが表示された場合は、組織で追加のセキュリティ情報が必要です。指示に従って Microsoft Authenticator アプリをダウンロードしてセットアップします。[後で質問する] を選択してテストを続行できます。
[要求されているアクセス許可] を求められた場合は、アプリによって要求されたアクセス許可を確認します。 [同意する] を選択してテストを続行します。
[サインアウト] を選択して、アプリからサインアウトします。 サインアウトすると、ウェルカム ページにリダイレクトされます。
[管理者としてサインイン] リンクを選択します。 Microsoft Entra IDは、サインイン ページにリダイレクトします。 先ほど作成した管理者ユーザーとしてサインインします。 サインインすると、Microsoft Entra ID によって、別のロール
admin
を持つ同様のプロファイル ページにリダイレクトされます。もう一度サインアウトし、前に作成した通常のユーザーで管理者としてサインインを試みます。 通常のユーザーには
admin
ロールがないため、エラー メッセージが表示されます。
リソースをクリーンアップする
この記事では、アプリを Azure にデプロイする方法については説明しません。 Microsoft Entra ID リソースはありますが、アプリ用にクリーン アップする Azure リソースはありません。 アプリを Azure にデプロイするには、次のセクションで参照されているガイダンスに従ってください。
このサンプル アプリのリソースの使用が完了したら、次の手順に従って Microsoft Entra ID リソースをクリーンアップします。 使用されていない Microsoft Entra ID リソースを削除することは、重要なセキュリティのベスト プラクティスです。
- 「Microsoft ID プラットフォームに登録されているアプリケーションを削除する」手順に従って、作成したアプリの登録を削除します。 必要なのは、「組織が作成したアプリケーションの削除」セクションの手順に従うだけです。
- アプリの登録を削除すると、エンタープライズ アプリケーションも削除されます。 エンタープライズ アプリケーションの削除の詳細については、「エンタープライズ アプリケーションの削除」を参照してください。
- 「ユーザーを作成、招待、削除する方法」の手順に従って、作成したユーザーを削除します。
次のステップ
このクイック・スタートでは、OIDC を使用して Microsoft Entra ID で WebSphere Liberty/Open Liberty アプリケーションを保護します。 詳細については、次のリソースを参照してください。
- Open Liberty または WebSphere Liberty を使用する Java アプリケーションを Azure Container Apps にデプロイする
- Azure Red Hat OpenShift で WebSphere Liberty と Open Liberty をデプロイする
- Azure Kubernetes Service (AKS) クラスターに、Open Liberty または WebSphere Liberty を使用する Java アプリケーションをデプロイする
- Microsoft Entra ID を使用した OpenID 接続認証
- Microsoft ID プラットフォームと OAuth 2.0 認証コード フロー
- ソーシャル メディア プロバイダーを介してユーザーを認証する
- ソーシャル メディア ログイン 1.0
- OpenID Connect クライアント1.0
- OpenID Connect とは
- プログラムによるセキュリティ ポリシーの構成
- Jakarta EE を使用して RESTful Web サービスをセキュリティで保護する方法
- Jakarta Expression Language