2

Ich arbeite an einem ASP.NET MVC5-Projekt mit Repository Muster zum ersten Mal. Es hat viele Rollen und es wird eine Anzahl von Benutzern in jeder Rolle geben. Bis jetzt habe ich verschiedene Model-Entitäten erstellt und hinzufügen, aktualisieren, löschen Szenarien funktionieren gut. Beim Testen der Dinge habe ich festgestellt, dass ein Benutzer die Entitäten aktualisieren kann, die ihm nicht gehören.Einen Benutzer beschränken, um nur auf seine Entitäten zuzugreifen In Entity framework6 Repository pattern

Ich möchte den Benutzer auf den Zugriff beschränken, bearbeiten, aktualisieren, löschen Sie nur die Entitäten (Zeilen in db), die dem Benutzer selbst gehören, nicht die anderen.

Ich weiß, ich muss irgendwo die userId des aktuellen angemeldeten Benutzers überprüfen, aber wo sollte ich dies wo Bedingung im Fall von Repository pattern with Entity Framework setzen.

Zwei Möglichkeiten, die mir in den Sinn kommen: Ändern der Modelle in userId -Eigenschaft in jeder Entität oder Verbinden jeder Entität mit ihrer übergeordneten Entität, um die zugehörigen Benutzerdetails zu erhalten (Die komplette Kette von Entitäten, um die userId zu erhalten).

Was wäre der bevorzugte Weg, dies zu implementieren? Danke!

+0

beginnen am Anfang zuweisen können: Was ist Ihr Wunsch bussiness Zweck. Mit anderen Worten, wie muss die Funktionalität funktionieren? Ist es möglich, den Datenzugriff basierend auf Benutzer/Rolle in der Hierarchie Ihres Domänenmodells zu beschränken? Oder möchten Sie, dass jede Entität über einen verwandten Benutzer (Id) verfügt und daher auf jeder Ebene Ihres Domänenmodells eine Einschränkung aufweist? –

+0

Dies ist auf Rollenbasis nicht möglich, da viele Benutzer dieselbe Rolle innehaben. Nur "userId" kann sicherstellen, dass die Entität mit ihm verwandt ist oder nicht. – vivek

+0

Warum haben sie die Möglichkeit, diese unerlaubten Änderungen zu machen? Meinst du, sie sollten nicht einmal die Daten anderer Benutzer sehen? –

Antwort

1

Sie SaveChanges Methode von DbContext außer Kraft setzen kann und prüfen, ob ein Benutzer nur seine/ihre eigenen Einheiten zu ändern. Diese Lösung funktioniert in jedem Muster, das EntityFramework verwendet.

Zuerst müssen Sie eine Schnittstelle schreiben, die UserId hat und jede Entitäten müssen es implementieren.

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; } 
} 

Dann müssen Sie SaveChanges überschreiben. Wenn in dieser Methode eine Entität geändert oder gelöscht wird, prüfen wir, ob UserId übereinstimmt, andernfalls wird die Ausnahme ausgelöst. und für die Entitäten, die hinzugefügt wird, um Ihnen aktuelle Benutzer-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

Das ist eine sehr späte Warnung. Wenn die Anwendung es Benutzern ermöglicht, die Daten anderer Benutzer zu ändern, kann es für einen Benutzer möglicherweise nicht mehr möglich sein, seinen * gültigen * Teil der Änderungen zu speichern. Ich denke, der Fokus sollte darauf liegen, unerlaubte Änderungen zu verhindern. –

+0

Das scheint gut, aber in meiner Anwendung habe ich einige Rollen (z. B. Support), die einige benutzerbezogene Daten bearbeiten können. Können wir diese Lösung sogar so ändern, dass sie auf Rollenbasis funktioniert, damit einige Rollen die anderen Benutzerdaten bearbeiten und einige Rollen daran hindern können, dies zu tun. – vivek

+0

@vivek Ja, Sie können diese Lösung an Ihre Bedürfnisse anpassen. Alles, was Sie tun müssen, ist, die if-Anweisung 'if (entity.UserId! = GetCurrentUserId())' in die von Ihnen gewünschte Bedingung zu ändern. – Kahbazi

0

Wenn Sie jede Entität mit ihrer übergeordneten Entität verbinden, um die zugehörigen Benutzerdetails abzurufen (die vollständige Kette von Entitäten, um die userId zu erhalten), wäre das gut. Erstellen Sie eine BaseEntity Allgemeingut wie UserId haben -

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

Andere Unternehmen, die Basisentität erben, so dass sie von Natur aus die gemeinsame UserId Eigenschaft haben kann -

public class OtherEntity : BaseEntity { 
    // properties 
} 
Verwandte Themen