JHipster APIゲートウェイ
JHipsterはAPIゲートウェイを生成できます。ゲートウェイは通常のJHipsterアプリケーションであるため、そのプロジェクトでは通常のJHipsterオプションと開発ワークフローを使用できますが、マイクロサービスへの入り口としても機能します。より具体的には、HTTPルーティングとロードバランシング、サービス品質、セキュリティ、およびすべてのマイクロサービスのAPIドキュメントを提供します。
サマリー
アーキテクチャ図
ゲートウェイを使用したHTTPリクエストのルーティング
ゲートウェイとマイクロサービスが起動されると、自身をConsulサービスレジストリに登録します。
ゲートウェイは、アプリケーション名を使用して、すべてのリクエストをマイクロサービスに自動的にプロキシします。たとえば、マイクロサービスapp1
が登録されている場合、ゲートウェイの/services/app1
のURLで利用できます。
たとえば、ゲートウェイがlocalhost:8080
で実行されている場合、http://localhost:8080/services/app1/api/foosの指定で、
マイクロサービスapp1
で提供されているfoos
のリソースを取得できます。Webブラウザでこれを行おうとしている場合は、RESTリソースがJHipsterでデフォルトで保護されていることを忘れないでください。したがって、正しいJWTヘッダーを送信するか(以下のセキュリティのポイントを参照)、以降のセキュリティに関するポイントを確認するか、またはマイクロサービスのSecurityConfiguration
クラスでそれらのURLのセキュリティを削除する必要があります。
同じサービスの複数のインスタンスが実行されている場合、ゲートウェイはそれらのインスタンスをサービスレジストリから取得し、Consul を使用してHTTPリクエストをロードバランスします。IPアドレス、Gitのバージョン、ステータスなどを含む実行中のマイクロサービスの詳細なリストにアクセスするには、http://localhost:8080/api/gateway/routes にアクセスしてください。このエンドポイントは保護されています。
各ゲートウェイには特定の"admin > gateway"メニューがあり、オープンされたHTTPルートとマイクロサービスインスタンスを監視できます。
セキュリティ
標準のJHipsterセキュリティオプションについては、このセキュリティドキュメントページで詳しく説明されています。ただし、マイクロサービスアーキテクチャのセキュリティ保護には、いくつかの特定のチューニングとオプションがあります。これらについては、ここで詳しく説明します。
JWT (JSON Web Token)
JWT (JSON Web Token)は、マイクロサービスアーキテクチャでアプリケーションを保護するための、業界標準の使いやすい方法です。
JHipsterは、Okta社が提供するJJWTライブラリのJWT実装を使用します。
トークンはゲートウェイによって生成され、基盤となるマイクロサービスに送信されます。共通のシークレットキーを共有するため、マイクロサービスはトークンを検証し、そのトークンを使用するユーザを認証できます。
これらのトークンは自己充足的であり、認証情報と認可情報の両方を持っているため、マイクロサービスはデータベースや外部システムに問い合わせる必要がありません。これは、スケーラブルなアーキテクチャを確保するために重要です。
セキュリティーを機能させるためには、JWTのシークレットトークンをすべてのアプリケーションで共有する必要があります。
- 各アプリケーションのデフォルトトークンは固有であり、JHipsterによって生成されます。これは
.yo-rc.json
ファイルに格納されます。 - トークンは、
src/main/resources/config/application.yml
ファイル内のjhipster.security.authentication.jwt.secret
キーで構成されます。 - このキーをすべてのアプリケーション間で共有するには、ゲートウェイからすべてのマイクロサービスにキーをコピーするか、JHipster固有のConsul K/Vストアの設定を使用してキーを共有します。これが、中央構成サーバが使用される主な理由の1つです。
- 開発と本番で異なるキーを使用することをお勧めします。
OpenID Connect
JHipsterはOpenID Connectのサポートを提供しており、詳細はOpenID Connectのドキュメントに記載されています。
このオプションを選択すると、デフォルトでKeycloakが使用され、Docker Composeを使用して完全なマイクロサービスアーキテクチャを実行することになります。Docker Composeドキュメントを必ず読み、Keycloak用に/etc/hosts
を正しく設定してください。
OpenID Connectを使用する場合、JHipsterゲートウェイはOAuth2トークンをマイクロサービスに送信し、マイクロサービスはKeycloakにも接続されているトークンを受け入れます。
JWTとは異なり、これらのトークンは自己充足的ではなく、ステートフルである必要があるため、次のような問題が発生します。
- マイクロサービスのパフォーマンスの問題:現在のユーザのセキュリティ情報を探すことは非常に一般的なため(そうでなければ最初からセキュリティオプションを使用することはありません)、各マイクロサービスはOpenID Connectサーバを呼び出してデータを取得します。そのため、通常のセットアップでは、これらの呼び出しは、リクエストを受け取るたびに各マイクロサービスによって行われ、これはすぐにパフォーマンスの問題を引き起こします。
- JHipsterマイクロサービスを生成するときに、キャッシュオプション(「キャッシュの使用」のドキュメントを参照)を選択した場合、これらの呼び出しをキャッシュする固有の
CachedUserInfoTokenServices
Spring Beanが生成されます。適切にチューニングされれば、パフォーマンスの問題は解消されます。 - この「ユーザー情報」リクエストに関する詳細が必要な場合は、
src/main/resources/application.yml
構成ファイル内の標準のSpring Boot構成キーsecurity.oauth2.resource.userInfoUri
を使用して構成されます。
- JHipsterマイクロサービスを生成するときに、キャッシュオプション(「キャッシュの使用」のドキュメントを参照)を選択した場合、これらの呼び出しをキャッシュする固有の
自動ドキュメンテーション
ゲートウェイは、proxifiesのサービスのSwagger API定義を公開するため、Swagger UIやswagger-codegenなどのすべての有用なツールの恩恵を受けることができます。
ゲートウェイの「admin>API」メニューには、ゲートウェイのAPIと登録されたマイクロサービスのすべてのAPIを示す、固有のドロップダウンリストがあります。
このドロップダウンリストを使用すると、すべてのマイクロサービスAPIが自動的に文書化され、ゲートウェイからテスト可能になります。
セキュアなAPIを使用すると、セキュリティトークンがSwagger UIインタフェースに自動的に追加されるため、すべてのリクエストがすぐに機能するようになります。
レート制限
これは、Bucket4jとHazelcastを使用して、マイクロサービスのQoSを提供する高度な機能です。
ゲートウェイはレート制限機能を提供するため、RESTリクエストの数を制限できます。
- IPアドレスによる制限(匿名ユーザの場合)
- ユーザログインによる制限(ログインユーザの場合)
JHipsterは、Bucket4jとHazelcastを使用してリクエスト数を計算し、制限を超えた場合にHTTP 429(過大なリクエストが発生)エラーを送信します。ユーザごとのデフォルトの制限は、1時間あたり100,000 APIコールです。
これは、特定のユーザのリクエストの洪水からマイクロサービスアーキテクチャを保護するための重要な機能です。
ゲートウェイはRESTエンドポイントを保護するため、ユーザのセキュリティ情報に完全にアクセスできるので、ユーザのセキュリティロールに応じて特定のレート制限を提供するように拡張できます。
レート制限を有効にするには、application-dev.yml
またはapplication-prod.yml
ファイルを開き、enabled
をtrue
に設定します。
jhipster:
gateway:
rate-limiting:
enabled: true
データはHazelcastに格納されるため、Hazelcast分散キャッシュが設定されていれば、ゲートウェイの拡張が可能であり、すぐに動作するはずです。
- すべてのゲートウェイには、デフォルトでHazelcastが設定されています。
さらにルールを追加する場合、または既存のルールを変更する場合は、それらをRateLimitingFilter
クラスでコーディングする必要があります。変更の例は次のとおりです。
- HTTP呼び出しの制限を下げる
- 1分または1日あたりの制限を追加
- "admin"ユーザーの制限をすべて削除
アクセス制御ポリシー
デフォルトでは、登録されたすべてのマイクロサービスがゲートウェイを通じて利用可能です。ゲートウェイを通じて公開される特定のAPIを除外する場合は、ゲートウェイ固有のアクセス制御ポリシーフィルタを使用できます。これは、application-*.yml
ファイルのjhipster.gateway.authorized-microservices-endpoints
キーを使うことで設定可能です。
jhipster: gateway: authorized-microservices-endpoints: # アクセス制御ポリシー。ルートに対して空のままにすると、すべてのエンドポイントがアクセス可能になります。 app1: /api,/v2/api-docs # 開発時の推奨設定
たとえば、マイクロサービスbar
の/api/foo
エンドポイントのみを使用可能にする場合は、次のように入力します。
jhipster: gateway: authorized-microservices-endpoints: bar: /api/foo
ゲートウェイのセキュリティを強化するためのTLSの有効化
デフォルトでは、ゲートウェイは非セキュアなHTTPで動作します。プロダクション環境では、セキュリティを強化するためにTLSを有効にすることを推奨します。これを行うには、application-prod.yml
にある提供されたコードスニペットのコメントを解除してください。これにより、config/tls
にある自己署名TLS証明書(ファイル名はkeystore.p12
)を使用するか、あらかじめ定義されたパスワードで独自のキーストアを指定することができます。
server: port: 443 ssl: key-store: classpath:config/tls/keystore.p12 key-store-password: password key-store-type: PKCS12 key-alias: selfsigned
この暗号スイートは、古くて非推奨のSSL暗号を無効にすることでセキュリティを強化します。このリストはSSL Labs(https://www.ssllabs.com/ssltest/)でテストされています。
ciphers: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
サーバーでTLSを有効にすると、パフォーマンスのオーバーヘッドが発生する可能性があることを念頭に置いてください。可能であれば、ゲートウェイの外部にSSL終端を持つロードバランサーを使用して暗号化を処理することを検討してください。これにより、このパフォーマンスの影響を軽減することができます。