2

私はリポジトリパターンで初めてASP.NET MVC5プロジェクトを作成しています。それには多くの役割があり、各役割には多数のユーザーがいます。今まで、私は様々なモデルエンティティを作成し、追加、更新、削除シナリオが正常に動作しています。テスト中に、ユーザーは自分に属していないエンティティを更新できることがわかりました。Entity framework6リポジトリパターン

私は、ユーザ自身に属するエンティティ(DB内の行)のみにアクセス、編集、更新、削除するように制限したいと考えています。

は、私が知っている、私はどこかでログインしているユーザーの現在のuserIdをチェックする必要がありますが、どこでRepository pattern with Entity Frameworkの場合には、この場所の条件をつけなければなりません。 各エンティティでプロパティを持つようにモデルを変更するか、または各エンティティを親エンティティと結合して、関連するユーザの詳細(userIdを取得するエンティティの完全なチェーン)を取得します。

これを実装するには、どのような方法が適していますか? ありがとう!

+0

スタートを割り当てることができます追加されているエンティティのため:あなたの希望商務目的は何ですか。言い換えれば、機能はどのように機能する必要がありますか?ドメインモデルの階層のどこかでユーザ/ロールに基づいてデータアクセスを制限することは可能ですか?または、各エンティティが関連するユーザー(Id)を持つようにしたいので、ドメインモデルのあらゆるレベルに制限がありますか? –

+0

同じロールに多数のユーザーが存在するため、ロールベースでは不可能です。 'userId'だけがエンティティが関係しているかどうかを確認できます。 – vivek

+0

なぜこれらの不許可の変更を始める可能性がありますか?他のユーザーのデータを見たりすべきではないということを意味しますか? –

答えて

1

あなたはDbContextからSaveChangesメソッドをオーバーライドして、ユーザーが唯一の彼/彼女の自身のエンティティを変更しているかどうかを確認することができます。このソリューションは、EntityFrameworkを使用している任意のパターンで動作します。

まず、UserIdを持つインターフェイスを作成する必要があり、すべてのエンティティで実装する必要があります。

public interface IEntity 
{ 
    int UserId { get; set; } 
} 

public Blog : IEntity 
{ 
    public int BlogId { get; set; } 
    public string Url { get; set; } 
    public int UserId { get; set; } 
} 

次に、SaveChangesを上書きする必要があります。このメソッドでは、エンティティが変更または削除されている場合、UserIdが一致するかどうかをチェックし、そうでなければ例外をスローします。 、あなたが最初に現在のユーザーIDに

public class ApplicationDbContext : DbContext 
{ 
    public override int SaveChanges() 
    { 

     var ModifiedDeletedEntities = ChangeTracker.Entries() 
       .Where(E => E.State == EntityState.Deleted || 
          E.State == EntityState.Modified).ToList(); 
     foreach (IEntity entity in ModifiedDeletedEntities) 
     { 
      if (entity.UserId != GetCurrentUserId()) 
      { 
       throw new Exception("Access Denied!"); 
      } 
     } 



     var AddedEntities = ChangeTracker.Entries() 
       .Where(E => E.State == EntityState.Added).ToList(); 
     foreach (IEntity entity in AddedEntities) 
     { 
      entity.UserId = GetCurrentUserId(); 
     } 



      return base.SaveChanges(); 

    } 
+1

これは非常に遅い警告です。アプリケーションでユーザーが他のユーザーのデータを変更できるようにすると、ユーザーが変更の*有効な*部分を保存できなくなることがあります。私は焦点が不許可の変更を防ぐことであるべきだと思います。 –

+0

これは良いようですが、私のアプリケーションでは、一部のユーザー関連データを編集できるいくつかの役割(サポートなど)があります。ロールベースで作業するようにこのソリューションを変更して、一部のロールが他のユーザーデータの編集を継続し、一部のロールがそうしないようにすることもできます。 – vivek

+0

@vivekはいあなたはあなたのニーズに合わせてこのソリューションを変更することができます。 if文(entity.UserId!= GetCurrentUserId())を必要な条件に変更するだけです。 – Kahbazi

0

関連するユーザーの詳細を取得するために、各エンティティに親エンティティを追加します(ユーザーIDを取得する完全なエンティティのチェーン)。

public class OtherEntity : BaseEntity { 
    // properties 
} 
0

別の解決策を使用することです - 彼らは本質的に、共通のユーザーIDプロパティを持つことができるように

public class BaseEntity { 
    public int UserId {get;set;} 
} 

他のエンティティベースのエンティティを継承します - ユーザーIDは、のような一般的な性質を持つことになりますBaseEntityを作成します。新しいSQL Server 2016の機能:行レベルのセキュリティ。 (Azureでも利用可能)

これにより、データベースレベルでクエリ結果をフィルタリングできます。

このための良い出発点:https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-entity-framework-row-level-security/

関連する問題