2

背景: 私は ASP.NET 4.0 で C# を使用して小さな概念実証 Web アプリケーションに取り組んでおり、Linq To SQL を使用しているのは、迅速かつ簡単だからです。あるユーザーが同じデータベース内の別のユーザーのデータを参照できないように制限する必要があります。そのため、ほとんどのテーブルに「アカウント」列を追加しました。アクセスを許可する前に、現在のユーザーが表示/編集しているデータと同じアカウントのメンバーであることを確認したいと思います。

私があまり満足していない考えられる解決策の 1 つ は、Linq To SQL クエリをすべて調べて、if ステートメントを追加して次のようにチェックすることです。

MyDataContext DB = new MyDataContext();
//get the current user's information from the DB
USER myUser = DB.USERs.Where(j => j.USR_EMAIL == User.Identity.Name).FirstOrDefault();
//get the object to edit
MYOBJECT myObject= DB.MYOBJECTs.Where(j => j.ID == IdFromQueryString).FirstOrDefault();
//compare the user's account with the object's account they are now trying to view
if(myUser.AccountID == myObject.AccountID)
{
    //display the object
}
else
{
    //display error message
}

これは、アプリケーション全体で多くの作業を行う必要があり、繰り返しや間違いの可能性は言うまでもありません。また、維持するのも面倒です。これをクエリに追加するのを忘れると、セキュリティ ホールが開いたままになります。

質問: これをテーブルごとに 1 回行う方法はありますか? Linq To SQL でクエリを実行するたびに自動的にチェックされますか? またはこれについてもっと良い方法はありますか?

4

3 に答える 3

3

リポジトリパターンを使用し、直接アクセスするContest.Usersのではなく、常にアクセスする必要がありRepository.Usersました。次に、リポジトリを公開するように変更してUsersfrom u in InternalContext.Users where u.AccountId = currentAccountId select uスコープを適用することができます。偶然にもRailsではこの手法をスコープと呼んでいますが……

次善の方法DataLoadOptionsは、ラムダ フィルターをエンティティに関連付けるために使用することです。「方法: DataContext レベルでフィルター処理する (LINQ to SQL)」を参照してください。作成するすべてのコンテキストにこれを追加する必要があります。繰り返しになりますが、メソッドからデータ コンテキストを取得するようにコードをリファクタリングする (または、より良い方法として、リポジトリ パターンを実装する...) と、非常に役立ちます。

最後に、バックエンドに移動して、更新可能なビューを介してこれを実装することもできますが、context_info()これは強くお勧めしません。

PS。account_idテーブルのすべてのクラスター化インデックスで一番左のキーを作成し、エンティティのid主キーを非クラスター化したことを願っていますか? そうしないと、パフォーマンスが低下します。

于 2012-07-10T05:22:40.870 に答える
1

申し訳ありませんが、両方のオブジェクトでAccountIDを使用できますか?もしそうなら、あなたが彼らのAccountidに参加できない理由はありますか?

var query = from o in DB.MYOBJECTs.Where(w => w.ID == IdFromQueryString)
            join u in DB.USERs.Where(w => w.USR_EMAIL = User.Identity.Name) on o.AccountID equals u.AccountID
            select o;
于 2012-07-10T05:08:25.687 に答える
0

2つの可能なアプローチ:

  • 直接クエリではなく、ストアドプロシージャを使用してデータにアクセスします。ユーザーにこれらのストアドプロシージャのみへのアクセス許可を与え(つまり、データベースへの一般的な読み取りアクセスを許可しない)、ストアドプロシージャにアクセス制限を適用させます。
  • 別のサービスを介してデータベースへのすべてのアクセスをプロキシします。この場合、データベースへの一般的なアクセス権を持つのはサービスだけであり、アクセス制限を適用できます。

これらは、すべてのクエリをラップするという現在の戦略と基本的にそれほど違いはありませんが、管理が簡単な場合があります。

于 2012-07-10T05:04:11.723 に答える