基本的なUAAで保護されたJHipsterマイクロサービスの構築
1. 概要
以前の記事では、 JHipster の基本と、それを使用してマイクロサービスベースのアプリケーションを生成する方法について説明しました。
このチュートリアルでは、JHipsterのユーザーアカウントと承認サービス(略してUAA)と、それを使用して本格的なJHispterベースのマイクロサービスアプリケーションを保護する方法について説明します。 さらに良いことに、これはすべて、コードを1行も記述せずに達成できます!
2. UAAコア機能
以前の記事で構築したアプリケーションの重要な機能は、ユーザーアカウントがそれらの不可欠な部分であったことです。 さて、これは単一のアプリケーションがある場合は問題ありませんが、JHipsterで生成された複数のアプリケーション間でユーザーアカウントを共有したい場合はどうでしょうか。 これがJHipsterのUAAの出番です。
JHipsterのUAAは、アプリケーションの他のサービスとは独立して構築、デプロイ、実行されるマイクロサービスです。 それは次のように機能します:
- Spring Bootの実装に基づくOAuth2認証サーバー
- ID管理サーバー。ユーザーアカウントのCRUDAPIを公開します。
JHipster UAAは、自己登録や「rememberme」などの一般的なログイン機能もサポートしています。 そしてもちろん、他のJHipsterサービスと完全に統合されています。
3. 開発環境のセットアップ
開発を開始する前に、まず環境にすべての前提条件が設定されていることを確認する必要があります。 Intro To JHipsterの記事で説明されているすべてのツールに加えて、実行中のJHipsterレジストリが必要です。 簡単に要約すると、レジストリサービスを使用すると、作成するさまざまなサービスを検索して相互に通信できます。
レジストリを生成して実行するための完全な手順は、 JHipster with a Microservice Architectureの記事のセクション4.1で説明されているため、ここでは繰り返しません。 Dockerイメージも利用可能で、代わりに使用できます。
4. 新しいJHipsterUAAサービスの生成
JHipsterコマンドラインユーティリティを使用してUAAサービスを生成しましょう。
$ mkdir uaa
$ cd uaa
$ jhipster
私たちが答えなければならない最初の質問は、どのタイプのアプリケーションを生成したいかです。 矢印キーを使用して、「JHipster UAA(マイクロサービスOAuth2認証用)」オプションを選択します。
次に、アプリケーション名、サーバーポート、サービスディスカバリなど、生成されたサービスに関する特定の詳細に関するいくつかの質問を求められます。
ほとんどの場合、デフォルトの回答で問題ありません。 生成されるアーティファクトの多くに影響を与えるアプリケーションのベース名については、「uaa」(小文字)を選択しました。これはわかりやすい名前です。 必要に応じて他の値を試すこともできますが、生成されたプロジェクトの主な機能は変更されません。
これらの質問に答えた後、JHipsterはすべてのプロジェクトファイルを作成し、 npm パッケージの依存関係(この場合は実際には使用されません)をインストールします。
これで、ローカルのMavenスクリプトを使用して、UAAサービスを構築および実行できます。
$ ./mvnw
... build messages omitted
2018-10-14 14:07:17.995 INFO 18052 --- [ restartedMain] com.baeldung.jhipster.uaa.UaaApp :
----------------------------------------------------------
Application 'uaa' is running! Access URLs:
Local: http://localhost:9999/
External: http://192.168.99.1:9999/
Profile(s): [dev, swagger]
----------------------------------------------------------
2018-10-14 14:07:18.000 INFO 18052 --- [ restartedMain] com.baeldung.jhipster.uaa.UaaApp :
----------------------------------------------------------
Config Server: Connected to the JHipster Registry config server!
----------------------------------------------------------
ここで注意すべき重要なメッセージは、UAAがJHipsterレジストリに接続されていることを示すメッセージです。このメッセージは、UAAが自身を登録でき、他のマイクロサービスやゲートウェイによる検出に使用できることを示します。
5. UAAサービスのテスト
生成されたUAAサービス自体にはUIがないため、直接API呼び出しを使用して、期待どおりに機能しているかどうかをテストする必要があります。
他のパーツやシステムで使用する前に、動作していることを確認する必要がある2つの機能があります。OAuth2トークンの生成とアカウントの取得。
まず、単純な curl コマンド:を使用して、UAAのOAuthエンドポイントから新しいトークンを取得しましょう。
$ curl -X POST --data \
"username=user&password=user&grant_type=password&scope=openid" \
http://web_app:changeit@localhost:9999/oauth/token
ここでは、2組の資格情報を使用して、パスワード付与フローを使用しました。 この種のフローでは、URLに直接エンコードする基本的なHTTP認証を使用してクライアントの資格情報を送信します。
エンドユーザーのクレデンシャルは、標準のユーザー名とパスワードのパラメーターを使用して、本文の一部として送信されます。 テストプロファイルでデフォルトで使用できる「user」という名前のユーザーアカウントも使用しています。
すべての詳細を正しく提供したと仮定すると、アクセストークンと更新トークンを含む回答が得られます。
{
"access_token" : "eyJh...(token omitted)",
"token_type" : "bearer",
"refresh_token" : "eyJ...(token omitted)",
"expires_in" : 299,
"scope" : "openid",
"iat" : 1539650162,
"jti" : "8066ab12-6e5e-4330-82d5-f51df16cd70f"
}
これで、返されたaccess_tokenを使用して、UAAサービスで利用可能なアカウントリソースを使用して、関連付けられたアカウントの情報を取得できます。
$ curl -H "Authorization: Bearer eyJh...(access token omitted)" \
http://localhost:9999/api/account
{
"id" : 4,
"login" : "user",
"firstName" : "User",
"lastName" : "User",
"email" : "user@localhost",
"imageUrl" : "",
"activated" : true,
"langKey" : "en",
"createdBy" : "system",
"createdDate" : "2018-10-14T17:07:01.336Z",
"lastModifiedBy" : "system",
"lastModifiedDate" : null,
"authorities" : [ "ROLE_USER" ]
}
アクセストークンの有効期限が切れる前にこのコマンドを発行する必要があることに注意してください。 デフォルトでは、UAAサービスは5分間有効なトークンを発行します。これは、本番環境に適した値です。
有効なトークンの寿命を簡単に変更するには、 応用-
6. UAA対応ゲートウェイの生成
UAAサービスとサービスレジストリが機能していることを確認したので、これらが相互作用するためのエコシステムを作成しましょう。 最後に、以下を追加します。
- Angularベースのフロントエンド
- マイクロサービスバックエンド
- これらの両方を前面に出すAPIゲートウェイ
認証のためにUAAとネゴシエートするサービスになるため、実際にはゲートウェイから始めましょう。 フロントエンドアプリケーションをホストし、APIリクエストを他のマイクロサービスにルーティングします。
ここでも、新しく作成したディレクトリ内でJHipsterコマンドラインツールを使用します。
$ mkdir gateway
$ cd gateway
$ jhipster
以前と同様に、プロジェクトを生成するためにいくつかの質問に答える必要があります。 重要なものは次のとおりです。
- アプリケーションタイプ:は「マイクロサービスゲートウェイ」である必要があります
- アプリケーション名:今回は「ゲートウェイ」を使用します
- サービスディスカバリ:「JHipsterレジストリ」を選択します
- 認証タイプ:ここで[JHipsterUAAサーバーによる認証]オプションを選択する必要があります
- UIフレームワーク:「Angular6」を選びましょう
JHipsterがすべてのアーティファクトを生成したら、提供されているMavenラッパースクリプトを使用してゲートウェイを構築および実行できます。
$ ./mwnw
... many messages omitted
----------------------------------------------------------
Application 'gateway' is running! Access URLs:
Local: http://localhost:8080/
External: http://192.168.99.1:8080/
Profile(s): [dev, swagger]
----------------------------------------------------------
2018-10-15 23:46:43.011 INFO 21668 --- [ restartedMain] c.baeldung.jhipster.gateway.GatewayApp :
----------------------------------------------------------
Config Server: Connected to the JHipster Registry config server!
----------------------------------------------------------
上記のメッセージで、ブラウザで http:// localhost:8080、を指定すると、アプリケーションにアクセスできます。これにより、デフォルトで生成されたホームページが表示されます。
アカウント>ログインメニュー項目に移動して、アプリケーションにログインしましょう。 admin / admin をクレデンシャルとして使用します。これは、JHipsterがデフォルトで自動的に作成します。 すべてうまくいくと、ウェルカムページにログオンが成功したことを確認するメッセージが表示されます。
ここで何が起こったのかを要約してみましょう。最初に、ゲートウェイはUAAのOAuth2トークンエンドポイントにクレデンシャルを送信しました。これにより、クレデンシャルが検証され、アクセスと更新JWTトークンを含む応答が生成されました。 次に、ゲートウェイはそれらのトークンを取得し、Cookieとしてブラウザに送り返しました。
次に、Angularフロントエンドは / uaa / api / account APIと呼ばれ、ゲートウェイは再びUAAに転送されました。 このプロセスでは、ゲートウェイはアクセストークンを含むCookieを取得し、その値を使用して認証ヘッダーをリクエストに追加します。
必要に応じて、UAAとGatewayの両方のログを確認することで、このすべてのフローを詳細に確認できます。 org.apache.http.wire ロガーレベルをDEBUGに設定することで、完全なワイヤーレベルのデータを取得することもできます。
7. UAA対応のマイクロサービスの生成
アプリケーション環境が稼働しているので、次に簡単なマイクロサービスを追加します。 「見積もり」マイクロサービスを作成します。これにより、一連の株価の作成、クエリ、変更、削除を可能にする完全なRESTAPIが公開されます。 各見積もりには、次の3つのプロパティのみが含まれます。
- 相場の銘柄記号
- その価格、そして
- 最後の取引のタイムスタンプ
ターミナルに戻り、JHipsterのコマンドラインツールを使用してプロジェクトを生成しましょう。
$ mkdir quotes
$ cd quotes
$ jhipster
今回は、JHipsterにマイクロサービスアプリケーションを生成するように依頼します。これを「見積もり」と呼びます。 質問は、以前に回答したものと似ています。 次の3つを除いて、ほとんどの場合、デフォルトを維持できます。
- サービスディスカバリ:「JHipsterレジストリ」を選択します。これは、アーキテクチャですでに使用されているためです。
- UAAアプリケーションへのパス:すべてのプロジェクトディレクトリを同じフォルダーに保持しているため、これは ../ uaa になります(もちろん、変更しない限り)
- 認証タイプ:「JHipsterUAAサーバー」を選択します
この場合、典型的な一連の回答は次のようになります。
JHipsterがプロジェクトの生成を終了したら、先に進んでプロジェクトをビルドできます。
$ mvnw
... many, many messages omitted
----------------------------------------------------------
Application 'quotes' is running! Access URLs:
Local: http://localhost:8081/
External: http://192.168.99.1:8081/
Profile(s): [dev, swagger]
----------------------------------------------------------
2018-10-19 00:16:05.581 INFO 16092 --- [ restartedMain] com.baeldung.jhipster.quotes.QuotesApp :
----------------------------------------------------------
Config Server: Connected to the JHipster Registry config server!
----------------------------------------------------------
... more messages omitted
「JHipsterレジストリ構成サーバーに接続しました!」というメッセージが表示されます。 ここで探しているのはです。 その存在は、マイクロサービスがレジストリに登録されていることを示しています。このため、ゲートウェイは、リクエストを「見積もり」リソースにルーティングし、作成すると素敵なUIに表示できるようになります。 マイクロサービスアーキテクチャを使用しているため、このタスクを2つの部分に分割します。
- 「見積もり」リソースバックエンドサービスを作成する
- フロントエンド(ゲートウェイプロジェクトの一部)で「見積もり」UIを作成します
7.1. 見積もりリソースの追加
まず、quotesマイクロサービスアプリケーションが停止していることを確認する必要があります—以前に実行していたのと同じコンソールウィンドウでCTRL-Cを押すことができます。
それでは、JHipsterのツールを使用して、プロジェクトにエンティティを追加しましょう。 今回はimport-jdlコマンドを使用します。これにより、すべての詳細を個別に提供するという面倒でエラーが発生しやすいプロセスから解放されます。 JDL形式の詳細については、完全なJDLリファレンスを参照してください。
次に、Quoteエンティティ定義といくつかのコード生成ディレクティブを含むquotes.jhというテキストファイルを作成します。
entity Quote {
symbol String required unique,
price BigDecimal required,
lastTrade ZonedDateTime required
}
dto Quote with mapstruct
paginate Quote with pagination
service Quote with serviceImpl
microservice Quote with quotes
filter Quote
clientRootFolder Quote with quotes
これで、このエンティティ定義をプロジェクトにインポートできます。
$ jhipster import-jdl quotes.jh
注:インポート中に、JHipsterはmaster.xmlファイルに変更を適用する際の競合について文句を言います。 この場合、上書きオプションを安全に選択できます。
これで、を使用してマイクロサービスを再度ビルドして実行できます
7.2. 見積もりUIの追加
最後に、見積もりにアクセスするために使用するゲートウェイプロジェクトでCRUDUIを生成しましょう。 「quotes」マイクロサービスプロジェクトからの同じJDLファイルを使用してUIコンポーネントを生成し、JHipsterのimport-jdlコマンドを使用してインポートします。
$ jhipster import-jdl ../jhipster-quotes/quotes.jh
...messages omitted
? Overwrite webpack\webpack.dev.js? <b>y</b>
... messages omitted
Congratulations, JHipster execution is complete!
インポート中に、JHipsterは、競合するファイルに関して実行する必要のあるアクションを数回要求します。 この場合、カスタマイズを行っていないため、既存のリソースを単純に上書きできます。
これで、ゲートウェイを再起動して、何を達成したかを確認できます。 ブラウザをhttp:// localhost:8080 のゲートウェイに向けて、コンテンツを更新します。 エンティティメニューには、Quotesリソースの新しいエントリが含まれているはずです。
このメニューオプションをクリックすると、Quotesリスト画面が表示されます。
予想どおり、リストは空です—まだ引用符を追加していません! この画面の右上にある[新しい見積もりの作成]ボタンをクリックして追加してみましょう。これにより、作成/編集フォームが表示されます。
生成されたフォームには、期待されるすべての機能があることがわかります。
- 必須フィールドは赤いインジケーターでマークされ、入力すると緑色に変わります
- 日付/時刻および数値フィールドは、ネイティブコンポーネントを使用してデータ入力を支援します
- このアクティビティをキャンセルして、データを変更せずに残すか、新しいエンティティまたは変更されたエンティティを保存することができます
このフォームに記入して[保存]をクリックすると、リスト画面に結果が表示されます。 これで、データグリッドに新しいQuotesインスタンスが表示されます。
管理者として、APIメニュー項目にもアクセスできます。これにより、標準のSwaggerAPI開発者ポータルにアクセスできます。 この画面では、実行可能なAPIの1つを選択できます。
- デフォルト:利用可能なルートを表示するゲートウェイ独自のAPI
- uaa :アカウントおよびユーザーAPI
- 引用符:引用符API
8. 次のステップ
これまでに構築したアプリケーションは期待どおりに機能し、さらなる開発のための強固な基盤を提供します。 要件の複雑さに応じて、いくつかの(または多くの)カスタムコードを作成する必要もあります。 いくつかの作業が必要になる可能性が高いいくつかの領域は次のとおりです。
- UIのルックアンドフィールのカスタマイズ:フロントエンドアプリケーションの構造により、これは通常非常に簡単です。CSSをいじって画像を追加するだけで、長い道のりを進むことができます。
- ユーザーリポジトリの変更:一部の組織には、すでに何らかの内部ユーザーリポジトリがあります(例: LDAPディレクトリ)—これにはUAAでの変更が必要になりますが、変更が必要なのは1回だけです。
- エンティティに対するきめ細かい承認: 生成されたエンティティのバックエンドで使用される標準のセキュリティモデルには、インスタンスレベルやフィールドレベルのセキュリティはありません。開発者はこれらの制限を適切なレベルで追加します(場合によってはAPIまたはサービス)
これらの発言があっても、JHispterのようなツールを使用すると、新しいアプリケーションを開発するときに大いに役立ちます。 これにより、強固な基盤がもたらされ、システム(および開発者)が進化するにつれて、コードベースの一貫性を良好なレベルに保つことができます。
9. 結論
この記事では、JHispterを使用して、マイクロサービスアーキテクチャとJHipsterのUAAサーバーに基づいて動作するアプリケーションを作成する方法を示しました。 1行のJavaコードを記述せずにそれを達成しました、これは非常に印象的です。
いつものように、この記事で紹介するプロジェクトの完全なコードは、GitHubリポジトリで入手できます。