2017-07-05 4 views
2

In meiner Anwendung habe ich zwei Rollen (admin und normal). Im Modell habe ich Klasse (Beispiel):Sicherer Zugriff auf einen Teil der Eigenschaften

public class Foo 
{ 
    [Key] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    public string Extra { get; set; } 
} 

Benutzer können diese Objekte auch bearbeiten und Filter verwenden, um zu suchen. Anwendung basiert auf WebAPI ASP.NET Core mit EF Core.

Es gibt eine Anforderung, die normal sollte nicht sehen (oder etwas damit tun) Extra Eigenschaft. Soll ich die Daten überall in der Anwendung schützen (Dienste, Controller, Datenzugriffsschicht), indem ich die Modellklasse (oder etwas anderes) aufspalte oder die Ausgabe von Endpunkten durch Ignorieren von Eigenschaften formatiere?

Eine meiner Ideen ist, ein Attribut zu erstellen, setzen Sie es auf Extra Eigenschaft und dann ContractResolver Ignorieren Eigenschaften mit diesem Attribut, wenn Benutzer nicht berechtigt ist, diese Eigenschaft zu sehen. Ändern Sie EF-Änderungs-Tracker auch so, dass das Speichern dieser Eigenschaft ignoriert wird (in denselben Fällen).

Gibt es ein Muster oder eine Strategie, wie mit diesem Problem umzugehen ist?

+0

Klingt wie Sie abstrahieren Ihre Klasse müssen aus in mehrere Klassen. – maccettura

Antwort

0

Es gibt keinen eingebauten Mechanismus dafür, nein, weil es viel zu granular ist. Wenn Sie versuchen, dies auf der EF-Ebene zu erzwingen, würde dies bedeuten, dass Sie Ihren HttpContext in Ihre DAL einbringen, was aus verschiedenen Gründen eine schlechte Idee ist.

Meine beste Empfehlung wäre, es mit Vererbung zu modellieren. Mit anderen Worten, schaffen so etwas wie:

public class Foo 
{ 
    [Key] 
    public int Id { get; set; } 

    public string Name { get; set; } 
} 

public class ExtraFoo : Foo 
{ 
    public string Extra { get; set; } 
} 

Standardmäßig wird Entity Framework implementieren diese durch Vererbung Single-Table, so dass Ihre Unterstützung Tisch ziemlich aussehen genau das gleiche. Dies gibt Ihnen dann jedoch die Möglichkeit, mit dem einen oder dem anderen getrennt zu arbeiten.

Dann würde ich empfehlen, völlig separate Controller und/oder Aktionen für die Arbeit mit jedem Typ zu verwenden. Auf diese Weise können Sie für jedes Programm unterschiedliche Berechtigungen verwenden und sicherstellen, dass "normale" Benutzer nur mit Foo (statt ExtraFoo) arbeiten können. Um die offensichtliche Vervielfältigung zu negieren dies bedeuten würde, können Sie einen Basis-Controller unter Verwendung von Generika verwenden, die jeweils typspezifische Controller könnte dann erben von:

public class BaseFooController<TFoo> : Controller 
    where TFoo : Foo, new() 
{ 
    // all your actions here, utilizing generic type, e.g.: 

    [HttpPost] 
    public ActionResult Create(TFoo foo) 
    { 
     ... 
    } 
} 

[Authorize(Roles = "normal")] 
public class FooController : BaseFooController<Foo> 
{ 
} 

[Authorize(Roles = "admin")] 
public class ExtraFooController : BaseFooController<ExtraFoo> 
{ 
} 
+0

Ich versuche zu vermeiden, Modellklasse in zwei Teile zu teilen, weil 'Foo' nicht separat existieren kann. Jedes Objekt sollte den Typ 'ExtraFoo' haben und' Foo' ist eine Art Ansicht für dieses Objekt. Wird es eine bessere Idee sein, die Schnittstellen zu verwenden? – Gullard

Verwandte Themen