web-dev-qa-db-ja.com

ユーザーまたはグループのメンバーシップに基づくマイクロサービスアーキテクチャのエンティティレベルのアクセス制限

システムには、本質的に制限されているデータが存在する場合があります。特定のエンティティへのアクセスは、ユーザーまたはグループのメンバーシップに基づいて簡単に制限または許可する必要がある場合があります。

これをマイクロサービスアーキテクチャに実装するための最良の方法は何ですか?

#1

アクセス制御、アクセス許可の管理などは、マイクロサービス自体の責任である必要がありますか?開発者は、すべてのサービスのアクセス制御、保存、および更新のアクセス許可を実装する必要があります。あまり堅牢でエラーが発生しやすいアプローチではないようです。

#2

専用のマイクロサービス処理権限管理を作成しますか?このサービスは他のマイクロサービスによって呼び出され、結果を返す前に各エンティティとフィルタリングエンティティのアクセス許可を確認します。一元化されたアクセス許可の保存と管理は利点ですが、マイクロサービスは各エンティティに対して「アクセス許可サービス」を呼び出して、パフォーマンスに悪影響を与える可能性のあるアクセス権を確認する必要があります。また、開発者はアクセスチェックをサービスに統合する必要があり、エラーの余地が残ります。

#3

APIゲートウェイまたはサービスメッシュのアクセス制御の責任を負います。すべてのサービスの応答を自動的にフィルタリングする実装を考えることができます。ただし、マイクロサービスがエンティティのリストを返す場合は、エンティティごとに権限を確認する必要があります。それでも潜在的なパフォーマンスの問題。

次の合成例を考えてみましょう。テスト結果、X線画像などを処理する医療システム。健康情報は非常に機密性が高いため、開示しないでください。

テスト結果は、次の場合にのみ利用できます。

  • 患者
  • 医師
  • 実験室

担当医は患者を別の専門医に送ることがあります。新しい医師も検査結果にアクセスできる必要があります。したがって、アクセスを動的に許可できます。

したがって、各エンティティ(テスト結果、X線画像など)には、ユーザーとグループがアクセスを許可される一連のルールがあります。

テスト結果を処理する「テスト結果サービス」と呼ばれるマイクロサービスがあると想像してください。アクセス制御、アクセス許可の管理などを担当する必要がありますか?または、パーミッション管理を抽出してマイクロサービスを分離する必要がありますか?

ヘルスケアシステムは、医師の診察も処理する場合があります。患者の医師の診察に関する情報は、次の人が利用できるようにする必要があります。

  • 患者
  • 医師
  • クリニック受付

これは、ユーザーまたはグループのメンバーシップに基づいてエンティティレベルのアクセス制限を必要とする別のエンティティタイプの例です。

エンティティレベルのアクセス制御が必要な場合、さらに多くの例を想像するのは簡単です。

11
Evgeniy Khyst

私は次の一般的な解決策にたどり着きました。

  1. ACLセキュリティモデルが使用されます。システム内の各オブジェクトには、関連付けられた一連の権限があります。権限は、オブジェクトに対して誰がどのアクションを実行できるかを定義します。
  2. マイクロサービスは、エンティティレベルの承認を担当し、オブジェクトのアクセス許可に基づいて応答でオブジェクトをフィルタリングします。
  3. 中央アクセス制御サービスは、システム内のすべてのオブジェクトのアクセス許可の作成、更新、および削除を担当します。アクセス制御サービスデータベースは、オブジェクトのアクセス許可のプライマリストアです。
  4. マイクロサービスデータベースに保存されているアクセス許可は、 event-carried state transfer を使用してAccess ControlServiceデータベースと同期されます。権限が変更されるたびに、イベントがメッセージブローカーに送信されます。マイクロサービスはこれらのイベントをサブスクライブして、アクセス許可を同期できます。
  5. API Gatewayは、追加の保護レイヤーとして使用できます。 API Gatewayは、アクセス制御サービス(RPC)を直接呼び出して、応答オブジェクトのアクセス許可を確認したり、最近取り消されたアクセス許可をロードしたりできます。

デザインの特徴:

  1. システム内の各オブジェクトを一意に識別する方法が必要です(例:UUID)。
  2. マイクロサービスでのアクセス許可の同期は結果整合性があります。メッセージブローカーとマイクロサービスの間でパーティションを作成する場合、アクセス許可は同期されません。権限の取り消しに問題がある可能性があります。この問題の解決策は別のトピックです。
4
Evgeniy Khyst

まず、これは(マイクロサービスごとに)個別のセキュリティモデルを用意することは非常に悪い考えです。アクセス管理、アクセス許可の付与、および異なるマイクロサービス内のエンティティ間のマッピングで地獄につながる可能性があるため、常にすべてのアプリケーションを横断する単一の必要があります。

次に、マイクロサービスの編成方法の理解が間違っていると思います。.?機能をマイクロサービスに分割する原則を、機能ごと、ドメインごとなどに捧げます。MSの明確な動作を実現するのに役立つ単一責任、DDD、およびその他のアプローチを検討してください。

したがって、最良の場合、次のことを行う必要があります。

  • 適切なセキュリティモデルを選択してください [〜#〜] abac [〜#〜] または [〜#〜] rbac [〜#〜] -他にもたくさんのオプションがありますが、あなたの例を見ると、ABACが最適だと思います
  • アクセス管理用に個別のMSを作成します-このMSの主な責任は、CRUDとグループ/ロール/権限/属性のピープルアカウントへの割り当てです。
  • 許可された健康情報のみを提供するための個別のMSを作成します。

第三に、どのように機能しますか?

  1. ABACを使用すると、(グループ/属性に基づいて)階層的な役割/権限を設定できます-データに許可されているユーザーの委任パスを解決するのに役立ちます
  2. (auth-MSを介して)認証を設定し、アクセス許可のリストを(セッション、Cookieなどに)保存します
  3. Health-info-MSで必要なデータについて、特定のユーザーのアクセスを確認します。これを行う方法にはいくつかのオプションがあります。

    • メモリグリッド(ヘーゼルキャスト、コヒーレンス)を使用する場合、セキュリティ属性に基づく述語を使用してフィルターを簡単に作成できます。

    • SQL(Hibernate、プレーンSQLなど)を使用している場合は、許可されたデータのみを返すクエリを生成する必要があります-セキュリティ固有の基準をwhere句に追加します

セキュリティチェックインwhereを使用したSQLクエリに関する詳細:SQL実行前(休止状態およびspringはspring-method-authフックを使用して簡単に実行できます)ユーザーに割り当てられたすべてのアクセス許可を解決する必要があります-auth-MSを呼び出すことでこれを実行できます。

TestResultエンティティ-VIEW、EDIT、DELETEのCRUD権限を作成しました。

ロールDOCTORは、任意のTestResultを表示できます。したがって、ロールにはVIEW権限があります。

役割PATIENTは、自分のTestResultsのみを表示できます。

したがって、各ビジネスロールに正しいwhere句を提供するビジネスルールを作成します(DOCTOR、 PATIENT、LABなど)そして最後にSQLリクエストは次のようになります:

VIEW権限を割り当てた患者の場合:

select * from test_result where id=*patient_id* and 1=1

VIEW権限を割り当てていない患者の場合:

select * from test_result where id=*patient_id* and 1!=1

注:ビジネスルールでは、クエリ結果を許可/制限するために1 = 1または1!= 1を追加できます

0

ここでは、セキュリティはビジネスロジックの一部のようです。どちらの例でも。その場合、セキュリティはデータスキームの一部になる可能性があります。例えば、
患者は自分の検査を見ることができます:
select * from test_result where patient_id=*patient_id*
医師は自分の医療部門からのすべての検査を見ることができます:
select * from test_result where branch_id=*doctor_branch*

アクセス制御用に個別のMSを使用することは非常に悪い考えであり、深刻なパフォーマンスの問題を引き起こす可能性があると思います。エンティティアクセスがゼロの誰かが毎回すべてのエンティティをフェッチしようとする状況を想像してみてください:)実際に必要なものよりも大きな結果セットを常に処理する必要があります。

0
Bullet-tooth