Java Spring Boot アプリによるユーザーのサインインと Microsoft Graph へのアクセスを有効にする
この記事では Spring Boot Web アプリについて、ユーザーのサインインと、Microsoft Graph を呼び出すために必要なアクセス トークンの取得機能を紹介します。 Java 用 Microsoft Entra ID Spring Boot Starter クライアント ライブラリを使用して、認証、承認、トークン取得を行います。 Graph からのデータの取得には、Microsoft Graph SDK for Java を使用します。
次の図は、アプリのトポロジを示しています。
このアプリは Java 用 Microsoft Entra ID Spring Boot Starter クライアント ライブラリを使用して、Microsoft Entra ID から Microsoft Graph のアクセス トークンを取得します。 アクセス トークンにより、ユーザーはスコープで定義されているとおり、Microsoft Graph API エンドポイントにアクセスする権限を持つことが証明されます。
前提条件
- JDK バージョン 15。 このサンプルは Java 15 のシステムで開発されましたが、他のバージョンとも互換性があります。
- Maven 3
- Visual Studio Code でこのサンプルを実行する場合は、Visual Studio Code 向け Java 拡張機能パックをお勧めします。
- Microsoft Entra ID テナント。 詳細については、「Microsoft Entra ID テナントの取得方法」をご覧ください。
- 自分の Microsoft Entra ID テナントのユーザー アカウント。 このサンプルは、個人の Microsoft アカウントでは正しく動作しません。 したがって、個人のアカウントを使用して Azure portal にサインインしたものの、ディレクトリにユーザー アカウントがない場合は、この時点で作成する必要があります。
- Visual Studio Code
- Visual Studio Code 用 Azure ツール
推奨事項
- Spring Framework に関するある程度の知識。
- Linux/OSX ターミナルに関するある程度の知識。
- トークンの検査に必要な jwt.ms。
- ネットワークの活動監視とトラブルシューティングに必要な Fiddler。
- 開発に関する最新の情報について、Microsoft Entra ID ブログを確認してください。
サンプルのセットアップ
次のセクションでは、サンプル アプリケーションを設定する方法を示します。
サンプル リポジトリを複製またはダウンロードする
サンプルを複製するには、Bash ウィンドウを開き、次のコマンドを使用します。
git clone https://github.com/Azure-Samples/ms-identity-msal-java-samples.git
cd 4-spring-web-app/2-Authorization-I/call-graph
または、ms-identity-msal-java-samples リポジトリに移動し、.zip ファイルでダウンロードして、ハード ドライブに展開します。
重要
Windows でファイル パスの長さが制限を超える場合は、ハード ドライブのルート近くのディレクトリにリポジトリを複製または展開してください。
Microsoft Entra ID テナントにサンプル アプリケーションを登録する
このサンプルには、プロジェクトが 1 つ存在します。 以下の各セクションでは、Azure portal を使用してアプリを登録する方法を説明します。
アプリケーションを作成する Microsoft Entra ID テナントを選択する
テナントを選択するには、次の手順に従います。
Azure portal にサインインします。
ご利用のアカウントが複数の Microsoft Entra ID テナントに存在する場合は、Azure portal の隅にあるプロファイルを選択し、ディレクトリの切り替えを選択して、セッションを目的の Microsoft Entra ID テナントに変更します。
アプリを登録する (java-servlet-webapp-call-graph)
アプリを登録するには、次の手順に従います。
Azure portal に移動し、Microsoft Entra ID を選択します。
ナビゲーション ペインでアプリの登録を選択し、新しい登録を選択します。
表示される アプリケーションの登録ページで、アプリケーションの登録情報を入力します。
- 名前セクションに、アプリのユーザーに表示されるわかりやすいアプリケーション名を入力します (例:
java-spring-webapp-call-graph
)。 - [サポートされているアカウントの種類] で、 [この組織のディレクトリ内のアカウントのみ] を選択します。
- [リダイレクト URI (省略可能)] セクションで、コンボボックスの [Web] を選択し、リダイレクト URI 「
http://localhost:8080/login/oauth2/code/
」を入力します。
- 名前セクションに、アプリのユーザーに表示されるわかりやすいアプリケーション名を入力します (例:
[登録] を選択して、アプリケーションを作成します。
アプリの登録ページで、アプリケーション (クライアント) ID の値を見つけてメモします。 この値は、後ほどアプリの構成ファイルで使用します。
アプリの登録ページで、ナビゲーション ペインにある 証明書とシークレットを選択してページを開き、シークレットの生成と証明書のアップロードを行います。
[クライアント シークレット] セクションで、 [新しいクライアント シークレット] を選択します。
キーの説明 (例: アプリのシークレット) を入力します。
1 年、2 年、無期限のいずれかの期間を選びます。
[追加] を選択します。 生成された値が表示されます。
生成した値をコピーしてから保存します。 この値は後ほど、コードの構成ファイルに使用します。 この値は二度と表示されず、他の方法でも取得はできません。 そのため、必ず Azure portal から保存した後に、他の画面やペインに移動してください。
アプリの登録ページで、ナビゲーション ペインから API のアクセス許可を選択してページを開き、アプリケーションで必要となる API にアクセスします。
アクセス許可の追加を選択し、Microsoft API タブが選択されていることを確認します。
[よく使用される Microsoft API] セクションで、 [Microsoft Graph] を選択します。
[委任されたアクセス許可] セクションで、一覧から [User.Read] を選択します。 必要に応じて検索ボックスを使用します。
[アクセス許可の追加] を選択します.
アプリの登録を使用するためにアプリ (java-spring-webapp-call-graph) を構成する
アプリを構成するには、次の手順に従います。
Note
以降の手順では、ClientID
は Application ID
または AppId
と同じです。
IDE でプロジェクトを開きます。
src\main\resources\application.yml ファイルを開きます。
プレースフォルダー
Enter_Your_Tenant_ID_Here
を見つけて、既存の値を Microsoft Entra テナント ID に置き換えます。Enter_Your_Client_ID_Here
のプレースフォルダーを見つけて、既存の値をアプリケーション ID または Azure portal からコピーしたjava-spring-webapp-call-graph
アプリのclientId
に変更します。Enter_Your_Client_Secret_Here
のプレースフォルダーを見つけて、既存の値を Azure portal からコピーした、java-spring-webapp-call-graph
の作成時に保存した値に置き換えます。
サンプルを実行する
以降のセクションでは、サンプルを Azure Container Apps にデプロイする方法を紹介します。
前提条件
- Azure アカウント。 アカウントがない場合は、 無料アカウントを作成してください。 続行するには、Azure サブスクリプションの "共同作成者" または "所有者" のアクセス許可が必要です。 詳細については、Azure portal を使用して Azure ロールを割り当てる方法に関するページを参照してください。
- Azure CLI。
- Azure Container Apps CLI 拡張機能バージョン
0.3.47
以上。 最新バージョンをインストールするには、az extension add --name containerapp --upgrade --allow-preview
コマンドを使用します。 - Java Development Kit バージョン 17 以上。
- Maven。
Spring プロジェクトを準備する
次の手順を実行して、プロジェクトを準備します。
次の Maven コマンドを使用して、プロジェクトをビルドします。
mvn clean verify
次のコマンドを使用して、サンプル プロジェクトをローカルで実行します。
mvn spring-boot:run
セットアップ
CLI から Azure にサインインするには、次のコマンドを実行し、プロンプトに従って認証プロセスを完了します。
az login
最新バージョンの CLI を実行していることを確認するには、upgrade コマンドを実行します。
az upgrade
次に、CLI 用の Azure Container Apps 拡張機能をインストールまたは更新します。
Azure CLI で az containerapp
コマンドを実行するときにパラメーターが見つからないというエラーが表示された場合には、最新バージョンの Azure Container Apps 拡張機能がインストールされていることを確認してください。
az extension add --name containerapp --upgrade
Note
2024 年 5 月以降、Azure CLI 拡張機能では、既定でプレビュー機能が有効になりません。 Container Apps のプレビュー機能にアクセスするには、--allow-preview true
を使用して Container Apps 拡張機能をインストールします。
az extension add --name containerapp --upgrade --allow-preview true
最新の拡張機能またはモジュールがインストールされたので、Microsoft.App
および Microsoft.OperationalInsights
名前空間を登録します。
Note
Azure Container Apps リソースは、Microsoft.Web
名前空間から Microsoft.App
名前空間に移行されました。 詳細については、「2022 年 3 月に Microsoft.Web から Microsoft.App に名前空間を移行する」を参照してください。
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights
Azure Container Apps 環境を作成する
Azure CLI のセットアップが完了したところで、この記事全体で使用される環境変数を定義できます。
bash シェルで次の変数を定義します。
export RESOURCE_GROUP="ms-identity-containerapps"
export LOCATION="canadacentral"
export ENVIRONMENT="env-ms-identity-containerapps"
export API_NAME="ms-identity-api"
export JAR_FILE_PATH_AND_NAME="./target/ms-identity-spring-boot-webapp-0.0.1-SNAPSHOT.jar"
リソース グループを作成する。
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION \
自動生成されたログ分析ワークスペースを使用して環境を作成します。
az containerapp env create \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--location $LOCATION
コンテナー アプリ環境の既定のドメインを表示します。 このドメインは、後のセクションで使用するためにメモしておきます。
az containerapp env show \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--query properties.defaultDomain
アプリのデプロイを準備する
アプリケーションを Azure Container Apps にデプロイすると、リダイレクト URL は、Azure Container Apps にデプロイされたアプリ インスタンスのリダイレクト URL に変更されます。 application.yml ファイルでこれらの設定を変更するには、次の手順に従います。
アプリの src\main\resources\application.yml ファイルに移動し、
post-logout-redirect-uri
の値をデプロイされたアプリのドメイン名に変更します (次の例を参照)。<API_NAME>
と<default-domain-of-container-app-environment>
は実際の値に置き換えてください。 たとえば、前の手順の Azure Container Apps 環境の既定のドメインを使用し、アプリ名にms-identity-api
を使用する場合、post-logout-redirect-uri
値にはhttps://ms-identity-api.<default-domain>
を使用します。post-logout-redirect-uri: https://<API_NAME>.<default-domain-of-container-app-environment>
このファイルを保存した後、次のコマンドを使用してアプリをリビルドします。
mvn clean package
重要
アプリケーションの application.yml ファイルには、クライアント シークレットの値が client-secret
パラメーターに格納されています。 この値をこのファイルに保持しないでください。 また、ファイルを Git リポジトリにコミットすると、リスクが生じる可能性があります。 推奨される方法については、「Azure Container Apps でシークレットを管理する」を参照してください。
Microsoft Entra IDアプリの登録を更新する
リダイレクト URI は Azure Container Apps にデプロイされたアプリに変更されるため、Microsoft Entra ID アプリの登録でも、リダイレクト URI を変更する必要があります。 次の手順に従って、この変更を行います。
開発者用の Microsoft ID プラットフォームの [アプリの登録] ページに移動します。
検索ボックスを使用してアプリの登録を検索します (例:
java-servlet-webapp-authentication
)。名前を選択して、アプリの登録を開きます。
コマンドメニューから 認証 を選択します。
Web - リダイレクト URI セクションで、URI の追加を選択します。
アプリの URI を、
/login/oauth2/code/
を追加して入力します。たとえばhttps://<containerapp-name>.<default domain of container app environment>/login/oauth2/code/
のようになります。[保存] を選択します。
アプリケーションのデプロイ
JAR パッケージを Azure Container Apps にデプロイします。
Note
必要に応じて、Java ビルド環境変数で JDK のバージョンを指定できます。 詳細については、Azure Container Apps の Java 用ビルド環境変数に関する記事を参照してください。
これで、az containerapp up
CLI コマンドを使って WAR ファイルをデプロイできるようになります。
az containerapp up \
--name $API_NAME \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--environment $ENVIRONMENT \
--artifact <JAR_FILE_PATH_AND_NAME> \
--ingress external \
--target-port 8080 \
--query properties.configuration.ingress.fqdn
Note
既定の JDK バージョンは 17 です。 アプリケーションとの互換性のために JDK のバージョンを変更する必要がある場合は、--build-env-vars BP_JVM_VERSION=<YOUR_JDK_VERSION>
引数を使ってバージョン番号を調整できます。
ビルド環境変数の詳細については、Azure Container Apps の Java 用ビルド環境変数に関する記事を参照してください。
アプリを検証する
この例では、containerapp up
コマンドに --query properties.configuration.ingress.fqdn
引数が含まれており、完全修飾ドメイン名 (FQDN) (アプリの URL とも呼ばれます) を返します。 次の手順を使用して、アプリのログをチェックし、デプロイの問題があれば調査します。
デプロイメント セクションの出力ページから出力アプリケーションの URL にアクセスします。
Azure Container Apps インスタンスの[概要] ページのナビゲーション ウィンドウで、[ログ] を選択してアプリのログを確認します。
サンプルの確認
次の手順に従ってサンプルを操作します。
- サインインまたはサインアウトの状態が、画面の中央に表示されます。
- 画面の隅にある状況依存ボタンを選択します。 このボタンは、アプリを最初に実行するときにサインインと表示します。 または、トークンの詳細かGraph を呼び出すを選択します。 このページは保護されており、認証が必要であるため、サインイン ページに自動でリダイレクトされます。
- 次のページに記載された指示に従い、Microsoft Entra ID テナントのアカウントでサインインします。
- 同意画面に、必要となるスコープが表示されます。
- サインイン フローが正常に完了するとホーム ページにリダイレクトされ、どのボタンでサインイン フローをトリガーした化に応じて、サインインの状態ページまたは他のいずれかのページが表示されます。
- 状況依存ボタンの表示がサインアウトに変わり、ユーザー名が表示されます。
- ホーム ページを表示している場合は、IDトークンの詳細を選択して、IDトークンのデコードされた要求の一部を表示します。
- Graph を呼び出すを選択して Microsoft Graph の /me エンドポイント を呼び出し、取得したユーザーの詳細の選択を確認します。
- 隅にあるボタンを使用してサインアウトします。新しい状態が状態ページに反映されます。
コードについて
このサンプルでは、Java 用 Microsoft Entra ID Spring Boot Starter クライアント ライブラリを使用して、Microsoft Entra ID テナントへのユーザーのサインインを行い、Microsoft Graph を呼び出すためにアクセス トークンを取得する方法を示します。 このサンプルでは、Spring Oauth2 クライアントと Spring Web ブート スターターも使用します。
Contents
次の表に、サンプル プロジェクト フォルダーの内容を示します。
ファイル/フォルダー | 説明 |
---|---|
pom.xml | アプリケーションの依存関係。 |
src/main/resources/templates/ | UI 用の Thymeleaf テンプレート。 |
src/main/resources/application.yml | アプリケーションと Microsoft Entra ID Boot Starter ライブラリの構成。 |
src/main/java/com/microsoft/azuresamples/msal4j/msidentityspringbootwebapp/ | このディレクトリには、メイン アプリケーションのエントリ ポイント、コントローラー、および構成のクラスが含まれています。 |
.../MsIdentitySpringBootWebappApplication.java | Main クラス。 |
.../SampleController.java | エンドポイントをマッピングするコントローラー。 |
.../SecurityConfig.java | セキュリティ構成 - たとえば、認証が必要なルートを構成します。 |
.../Utilities.java | ユーティリティ クラス - たとえば、ID トークン要求をフィルター処理します。 |
CHANGELOG.md | サンプルに対する変更の一覧。 |
CONTRIBUTING.md | サンプルに貢献するためのガイドライン。 |
ライセンス | サンプルのライセンス。 |
ID トークン要求
アプリはトークンの詳細を抽出するために、要求マッピングで Spring Security の AuthenticationPrincipal
と OidcUser
のオブジェクトを使用します (次の例を参照)。 このアプリで ID トークン要求を使用する方法については、サンプル コントローラーを参照してください。
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
//...
@GetMapping(path = "/some_path")
public String tokenDetails(@AuthenticationPrincipal OidcUser principal) {
Map<String, Object> claims = principal.getIdToken().getClaims();
}
サインインとサインアウトのリンク
アプリはサインインを行う際に、Java 用 Microsoft Entra ID Spring Boot Starter クライアント ライブラリで自動的に構成された Microsoft Entra ID サインイン エンドポイントに対して要求を行います (次の例を参照)。
<a class="btn btn-success" href="/oauth2/authorization/azure">Sign In</a>
アプリはサインアウトを行う際に、logout
エンドポイントへの POST 要求を行います (次の例を参照)。
<form action="#" th:action="@{/logout}" method="post">
<input class="btn btn-warning" type="submit" value="Sign Out" />
</form>
認証に依存する UI 要素
アプリの UI テンプレート ページに、ユーザーが認証済みかどうかに応じて表示するコンテンツを決定するためのシンプルなロジックがあります (Spring Security Thymeleaf タグを使用した次の例を参照)。
<div sec:authorize="isAuthenticated()">
this content only shows to authenticated users
</div>
<div sec:authorize="isAnonymous()">
this content only shows to not-authenticated users
</div>
AADWebSecurityConfigurerAdapter を使用してルートを保護する
既定では、アプリは ID トークンの詳細ページと Graph の呼び出しページを保護するため、サインインしているユーザーのみがそれらのページにアクセスできます。 アプリは、application.yml ファイルにある app.protect.authenticated
プロパティで、これらのルートを構成します。 アプリの特定の要件を構成するには、いずれのクラスで AADWebSecurityConfigurationAdapter
を拡張します。 例については、このアプリの SecurityConfig クラスを参照してください (次の例を参照)。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends AADWebSecurityConfigurerAdapter{
@Value( "${app.protect.authenticated}" )
private String[] protectedRoutes;
@Override
public void configure(HttpSecurity http) throws Exception {
// use required configuration form AADWebSecurityAdapter.configure:
super.configure(http);
// add custom configuration:
http.authorizeRequests()
.antMatchers(protectedRoutes).authenticated() // limit these pages to authenticated users (default: /token_details, /call_graph)
.antMatchers("/**").permitAll(); // allow all other routes.
}
}
グラフの呼び出し
ユーザーが /call_graph
に移動すると、アプリケーションは Microsoft Entra ID ブート スターターが準備した Oauth2AuthorizedClient
または graphAuthorizedClient
を使用して GraphServiceClient
を作成します。 アプリは /me
エンドポイントの呼び出しを GraphServiceClient
に要求し、現在サインインしているユーザーの詳細を表示します。 GraphServiceClient
は、Microsoft Graph SDK for Java v3 にあります。
Oauth2AuthorizedClient
を正しいスコープで準備する必要があります。 application.yml ファイルと次のスコープセクションを参照してください。 Oauth2AuthorizedClient
はアクセス トークンを表示し、それを GraphServiceClient
要求の Authorization
ヘッダーに入力するために使用されます (次の例を参照)。
//see SampleController.java
@GetMapping(path = "/call_graph")
public String callGraph(@RegisteredOAuth2AuthorizedClient("graph") OAuth2AuthorizedClient graphAuthorizedClient) {
// See the Utilities.graphUserProperties() method for the full example of the following operation:
GraphServiceClient graphServiceClient = Utilities.getGraphServiceClient(graphAuthorizedClient);
User user = graphServiceClient.me().buildRequest().get();
return user.displayName;
}
application.yml ファイルにある次の例は、要求されたスコープを示しています。
# see application.yml file
authorization-clients:
graph:
# Specifies the Microsoft Graph scopes that your app needs access to:
scopes: https://graph.microsoft.com/User.Read
スコープ
スコープはアプリケーションが要求するアクセス レベルを Microsoft Entra ID に通知します。 このアプリケーションが要求する Microsoft Graph のスコープについては、application.yml を参照してください。
既定では、アプリケーションはスコープの値を https://graph.microsoft.com/User.Read
に設定します。 User.Read
のスコープは、現在サインインしているユーザーの情報に /me endpoint からアクセスするためのものです。 /me エンドポイントへの要求には、User.Read
スコープを含める必要があります。
ユーザーがサインインすると、Microsoft Entra ID は、アプリケーションで要求されたスコープに基づいて、ユーザーに同意ダイアログを表示します。 ユーザーが 1 つ以上のスコープに同意してトークンを取得すると、その同意先スコープが結果のアクセス トークンにエンコードされます。
このアプリでは、graphAuthorizedClient
によってアクセス トークンが表示され、ユーザーが同意したスコープが提示されます。 アプリはこのトークンを使用して、Graph 要求を処理する GraphServiceClient
のインスタンスを作成します。
GraphServiceClient.me().buildRequest().get()
を使用すると要求がビルドされ、https://graph.microsoft.com/v1.0/me
に作成されます。 アクセス トークンは、要求の Authorization
ヘッダーに配置されます。
詳細
- Microsoft ID プラットフォームのドキュメント
- Microsoft Authentication Library (MSAL) の概要
- クイック スタート: Microsoft ID プラットフォームにアプリケーションを登録する
- クイック スタート: Web API にアクセスするようにクライアント アプリケーションを構成する
- Microsoft Entra ID アプリケーションの同意エクスペリエンスについて理解する
- ユーザーおよび管理者の同意について
- Microsoft Entra ID のアプリケーションとサービス プリンシパル オブジェクト
- 各国のクラウド
- MSAL コードのサンプル
- Java 用 Azure Active Directory Spring Boot Starter クライアント ライブラリ
- Java 用 Microsoft 認証ライブラリ (MSAL4J)
- MSAL4J Wiki
- ID トークン
- Microsoft ID プラットフォームのアクセス トークン
このシナリオおよびその他のシナリオでの OAuth 2.0 プロトコルの動作の詳細については、「Microsoft Entra ID の認証シナリオ」を参照してください。