Symfonyにおけるシングルデータベースマルチテナンシー:... ノート

Symfonyにおけるシングルデータベースマルチテナンシー:31行のDoctrineフィルターと、それが決して実行されない5つの場所

シングルデータベースマルチテナンシーは、データ分離を強制するためにorganization_idカラムに依存していますが、開発者はクエリにそれを含めることを忘れないようにする必要があります。DoctrineのSQLFilterはこれを自動化できますが、その有効性は、実装場所と省略場所によって異なります。organizationフィルターは、フィクスチャ、マイグレーション、および修復スクリプトの問題を防ぐために、Doctrineの設定でデフォルトで意図的に無効になっています。認証されたユーザーとその組織にアクセスするために、リクエストライフサイクルの後半、特にファイアウォールの後にリスナーによって有効になります。しかし、このフィルターには、適用されない、またはバイパスされるいくつかの盲点があります。コンソールコマンドとメッセージキューワーカーはリクエストリスナーの恩恵を受けないため、フィルターが無効な状態で実行されます。これは、すべてのテナントにわたるバッチ処理のようなタスクでは意図的なものですが、テナントデータに触れるコマンドには明示的なスコープが必要です。管理パネルも、テナントをまたいだデータを表示できるようにパスプレフィックスによって意図的に免除されているため、これらの免除はセキュリティ上非常に重要です。クエリが実行される前にDoctrineのアイデンティティマップにあるエンティティは、SQLが生成されないため、フィルターを完全にバイパスします。同様に、getReference()はデータベースインタラクションなしでプロキシを作成するため、プロキシが初期化されるまでフィルターは参照されません。DBALを通じて実行されるネイティブSQLクエリは、Doctrineのフィルターを完全に無視するため、レポートおよびエクスポート機能にリスクをもたらします。organization_idとマーカーインターフェイスがルートエンティティにない場合、結合継承もフィルターの漏れにつながる可能性があります。俗説に反して、フィルターはバルクUPDATEおよびDELETE DQLステートメントに適用されますが、これはDQLパスのみをカバーします。フィルターの信頼性を確保し、リグレッションを検出するには、徹底的な自動テストが不可欠です。