SOA /マイクロサービス:サービス間通信で認証を処理する方法


18

前景

モノリシックプラットフォームから、よりサービス指向のアーキテクチャに移行しています。非常に基本的なDDDの原則を適用し、さまざまな境界のあるコンテキストにドメインを分割しています。各ドメインは配布され、Web API(REST)を介してサービスを公開します。

ビジネスの性質上、予約サービス顧客製品などのサービスを提供しています。

また、主な役割が以下のことを行うIdentity Server(Thinktecture Identity Server 3ベース)をセットアップしました

  • 認証の集中化(トークンを発行する資格情報を指定)
  • 次のようなトークンにクレームを追加します:クライアントのスコープ(クライアントごとに要求を行うアプリケーションを意味する)、顧客識別子(顧客ごとにアプリケーションを使用する人を意味する)

また、サービスへの外部アクセスを集中化するAPI Gatewayの役割も導入しました。API Gatewayは、次のような内部ドメインの深い知識を必要としない機能を提供します。

  • リバースプロキシ:着信要求を適切な内部サービスにルーティングします
  • バージョン管理:API Gatewayのバージョンは、内部サービスの異なるバージョンにマップされます
  • 認証:クライアント要求には、Identity Serverによって発行されたトークンが含まれ、API Gatewayはトークンを検証します(ユーザーが本人であることを確認してください)
  • 調整:クライアントごとの要求数を制限する

認可

認可に関係するものは、これはAPI Gatewayではなく、内部サービス自体で管理されます。現在、主に2種類の承認を行っています。

  • クライアントスコープに基づく承認。例:クライアント(APIを使用する外部アプリケーション)には、予約サービスAPIエンドポイントにアクセスするためのスコープ「bookings」が必要です
  • 顧客に基づいた承認。例:顧客(アプリケーションを使用する実在の人物)が予約の参加者である場合のみ、予約サービスからエンドポイントGET / bookingsにアクセスできます。

内部サービスで認証を処理できるようにするために、API Gatewayは、クライアント(要求を行うアプリケーション)と顧客としての情報の両方を含むトークン(内部サービスに要求をルーティングするとき)を転送するだけです人がクライアントアプリケーションにログインしている場合)。

問題の説明

これまでのところ、サービス間通信(一部のサービスは他のサービスと通信してデータを取得できます)を導入するまではこれで十分です。

質問

サービス間通信の認可にどのようにアプローチすればよいですか?

考慮されるオプション

さまざまなオプションについて説明するには、次のサンプルシナリオを使用します。

  • 予約フローを構築するために、APIにアクセスするExternalAppと呼ばれる外部アプリケーションがあります(ExternalApp はクライアントとして見ることができます
  • ExternalAppBookingsサービスにアクセスする必要があるため、ExternalAppにスコープ「bookings」を付与します
  • 内部的に(これはExternalAppに対して完全に透過的なものです)、予約サービスはサービスサービスにアクセスして、フライト、保険、レンタカーなどの予約のデフォルトサービスを取得します

この問題を内部で議論する際、いくつかのオプションが表示されましたが、どのオプションが最適かはわかりません。

  1. BookingsServicesと通信する場合、API Gatewayから受信した元のトークンを単純に転送する必要があります(クライアントがExternalAppであることを示します)
    • 意味:付与されるべきではないExternalAppにスコープを付与する必要がある場合があります。例:ExternalAppにはスコープ「bookings」と「services」の両方が必要な場合がありますが、「bookings」スコープのみで十分です。
  2. BookingsServicesと通信する場合、クライアントが(ExternalAppの代わりに)Bookingsになったことを示すトークンを転送し、Bookingsが元のクライアントExternalAppになりすましていることを示すクレームを追加します
    • また、元のクライアントがExternalAppであるという情報を含めることにより、サービスサービスは元の呼び出し元に応じて一部のサービスを除外するなどのロジックも実行できます(たとえば、内部アプリの場合はすべての戦いを返し、外部アプリの場合は一部のみ)
  3. サービスは互いに通信すべきではありません(そのため、この質問に直面するべきではありません)

ご意見をお寄せいただきありがとうございます。


1
この問題をどのように解決しましたか?私たちも同様の状況にあります。
VARUNメータ

+1:問題を最終的に解決する方法に興味があります。
ディプソ

ポイント3を実行するには、サービスが相互に通信しないため、複合UIが必要です。参照してくださいparticular.net/blog/secret-of-better-ui-composition
stevie_c

回答:


3

マイクロサービス間の通信の内部チャネルを持つことをお勧めします。

たとえば、RabbitMQのようなメッセージブローカーを内部的に使用して、マイクロサービス間でメッセージを送信/受信またはパブリッシュ/サブスクライブする場合。

次に、「あなたの例では予約サービス」サービスに直面している最初のエンドユーザーは、トークンを検証し、顧客がIdentityServerと通信することによってこの特定の操作を行うことを許可する責任があります。

その後、Message Brokerを介してServicesサービスと通信します。その場合、トークンを再度検証する必要はありません。

このモデルはよりシンプルで、パフォーマンスが向上すると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.