システムには、本質的に制限されているデータが存在する場合があります。特定のエンティティへのアクセスは、ユーザーまたはグループのメンバーシップに基づいて簡単に制限または許可する必要がある場合があります。
これをマイクロサービスアーキテクチャに実装するための最良の方法は何ですか?
アクセス制御、アクセス許可の管理などは、マイクロサービス自体の責任である必要がありますか?開発者は、すべてのサービスのアクセス制御、保存、および更新のアクセス許可を実装する必要があります。あまり堅牢でエラーが発生しやすいアプローチではないようです。
専用のマイクロサービス処理権限管理を作成しますか?このサービスは他のマイクロサービスによって呼び出され、結果を返す前に各エンティティとフィルタリングエンティティのアクセス許可を確認します。一元化されたアクセス許可の保存と管理は利点ですが、マイクロサービスは各エンティティに対して「アクセス許可サービス」を呼び出して、パフォーマンスに悪影響を与える可能性のあるアクセス権を確認する必要があります。また、開発者はアクセスチェックをサービスに統合する必要があり、エラーの余地が残ります。
APIゲートウェイまたはサービスメッシュのアクセス制御の責任を負います。すべてのサービスの応答を自動的にフィルタリングする実装を考えることができます。ただし、マイクロサービスがエンティティのリストを返す場合は、エンティティごとに権限を確認する必要があります。それでも潜在的なパフォーマンスの問題。
次の合成例を考えてみましょう。テスト結果、X線画像などを処理する医療システム。健康情報は非常に機密性が高いため、開示しないでください。
テスト結果は、次の場合にのみ利用できます。
担当医は患者を別の専門医に送ることがあります。新しい医師も検査結果にアクセスできる必要があります。したがって、アクセスを動的に許可できます。
したがって、各エンティティ(テスト結果、X線画像など)には、ユーザーとグループがアクセスを許可される一連のルールがあります。
テスト結果を処理する「テスト結果サービス」と呼ばれるマイクロサービスがあると想像してください。アクセス制御、アクセス許可の管理などを担当する必要がありますか?または、パーミッション管理を抽出してマイクロサービスを分離する必要がありますか?
ヘルスケアシステムは、医師の診察も処理する場合があります。患者の医師の診察に関する情報は、次の人が利用できるようにする必要があります。
これは、ユーザーまたはグループのメンバーシップに基づいてエンティティレベルのアクセス制限を必要とする別のエンティティタイプの例です。
エンティティレベルのアクセス制御が必要な場合、さらに多くの例を想像するのは簡単です。
私は次の一般的な解決策にたどり着きました。
デザインの特徴:
まず、これは(マイクロサービスごとに)個別のセキュリティモデルを用意することは非常に悪い考えです。アクセス管理、アクセス許可の付与、および異なるマイクロサービス内のエンティティ間のマッピングで地獄につながる可能性があるため、常にすべてのアプリケーションを横断する単一の必要があります。
次に、マイクロサービスの編成方法の理解が間違っていると思います。.?機能をマイクロサービスに分割する原則を、機能ごと、ドメインごとなどに捧げます。MSの明確な動作を実現するのに役立つ単一責任、DDD、およびその他のアプローチを検討してください。
したがって、最良の場合、次のことを行う必要があります。
第三に、どのように機能しますか?:
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を追加できます
ここでは、セキュリティはビジネスロジックの一部のようです。どちらの例でも。その場合、セキュリティはデータスキームの一部になる可能性があります。例えば、
患者は自分の検査を見ることができます:select * from test_result where patient_id=*patient_id*
医師は自分の医療部門からのすべての検査を見ることができます:select * from test_result where branch_id=*doctor_branch*
アクセス制御用に個別のMSを使用することは非常に悪い考えであり、深刻なパフォーマンスの問題を引き起こす可能性があると思います。エンティティアクセスがゼロの誰かが毎回すべてのエンティティをフェッチしようとする状況を想像してみてください:)実際に必要なものよりも大きな結果セットを常に処理する必要があります。