2016-08-02 9 views
-1

Azure DocumentDbをストレージとして使用するマルチテナントAngular Web Appを開発しています。アプリケーションのすべてのテナントからのドキュメントで、同じコレクションに格納され、ドキュメントのtenantId属性によって区別されます。 DocumentDbのマスターキーを保持する中間層の.NETサービスと、Web AppによるCRUD操作のREST APIエンドポイントを公開します。 Webアプリケーションのユーザーは、oAuthプロバイダ(Google、Facebook、Microsoft)によって認証されます。あるテナントのユーザーが他のテナントのデータにアクセスできないようにテナントデータを保護するためのベストプラクティスは何ですか?マルチテナントSPAからDocumentDBへのアクセスを保護

+0

残念なことに、このタイプの質問は、これを達成するための単一の「ベストプラクティス」方法ではないため、StackOverflowの話題にはなりません。これはかなり幅広く意見集めの質問であり、潜在的に多くの回答があります。 –

答えて

1

私はベストプラクティスそれを呼び出すのに十分な自信を持ってないんだけど、私たちはあなたが行うように、中間層のREST APIを持っているし、ここで私たちは何をすべきかです:

  1. クライアント(でも、ブラウザのコード)は、任意のクエリを送信することができます。私たちはsql-from-mongoを使用しています。これらはmongoのような構文であり、javascriptクライアントがクエリを構築する方が簡単ですが、変数をパラメータ化して許可しない限り、生のSQLクエリを使用すると安全ですあなたのSELECT句の任意の予測。この最後の部分はsql-from-mongoの変換で実現しますが、投影を取り除く(句をSELECT *に置き換える)か、SELECT *で始まらなかったクエリを拒否することができます。それがなければ、悪い俳優たちが自分自身のtenentIDまたはuserIDを投影して、これらのコントロールのキーをオフにすることができるので、これは非常に重要です。

  2. 私たちのRESTミドルウェアは、各クライアントのテナントとユーザコンテキストをキャッシュします。これらは、私たちの認可仕様(Firebaseの概念と似ています)を含んでいます。最も単純な形式では、ユーザーは1人のテナントに縛られており、そのユーザーはそのテナントのすべてのデータに対する読み取りアクセス権を持ちますが、何も指定できます。

  3. クエリが実行されると、返されたデータセットが承認仕様と照合されます。状況によっては、許可されていないドキュメントのリクエストが完全に拒否されるか、または許可されないドキュメントが返された結果セットから除外されます。

  4. 物事の書き込み側では、私たちは似たようなことをします。私たちは承認仕様と照合し、遵守していないものは拒否します。私たちはすべての書き込みにsprocを使用しており、インプレース更新のためのmongoのような構文を持っているため、(sprocを使用して)すべての書き込みに対してクロスドキュメントACIDを実装しています。私はそれがなければ何も示唆していない。

希望します。コメントで質問をしてください。

+0

Larry、詳細な対応をありがとうございます。私がしようとしていることは次のとおりです: 1.OAuthプロバイダでログインした後、クライアントはoAuthプロバイダIDをAuthサーバに送信します。 2.Authサーバーは、データベースから対応するtenantIdとuserRoleを取得します。 3.AuthサーバーはtenantIdとuserRoleでJWTを生成し、それをClientに返します。 4.Clientには、REST APIサービスに対するすべてのリクエストに対してJWTがHTTP Authorizationヘッダーに組み込まれています –

+1

テナントIDとロールのクライアントからの送信を受け入れるのではなく、oauthトークンをキーとして使用し、トークンをクライアントに/から渡します。さもなければ、クライアントがそれらのものを偽装することは可能です。 –

+1

また、サーバー上にキャッシュしないで、すべての要求に対して認可情報を参照してください。効率は低下しますが、サーバーはステートレスのままで、キャッシュの無効化の問題を回避できます。 –

2

これは、中間層の要求を論理的に傍受して、読み取りの両方で&の書き込みを行い、各文書にtenantIdタグを保持することで実現できます。

読み込みパスから始めましょう。各文書にtenantIdプロパティが、文書が属するユーザの対応するテナントに設定されていると仮定します。データを読み取るには、パラメータ化されたSQLクエリ(https://azure.microsoft.com/en-us/blog/announcing-sql-parameterization-in-documentdb/)を使用し、クエリにtenantIdフィルタがあることを必ず確認します。これにより、ユーザーの要求は、要求が参照する予定のテナントIDのみを処理することになります。パラメータ化は注入を避けるために重要であり、そこでは他のテナントのデータにアクセスすることが重要です。

書き込みパスで、各ドキュメントにtenantIdプロパティが正しく設定されていることを確認する必要があります。エンドクライアントが設定されていない場合でも、中間層がこれを解析して、OAuthプロバイダから返されたユーザの認証トークンに対応するテナントと一致することを確認する必要があります。

この場合、tenantIdのパーティションキーは、単一のテナントのすべてのデータをまとめておくのに役立つことに注意してください。これは、クエリがtenantIdフィルタを持っている限り、単一のパーティションでのゼロ化に関して効率的なクエリに役立ちます。

関連する問題