2017-02-05 10 views
0

Ich habe eine Webanwendung, die auf dotnet core + entityframework core, Identity Server und MS SQL Server als Datenbank (Angular 2 am Frontend) aufgebaut ist. Ich habe bereits Benutzerauthentifizierung mit Rollen implementiert. Im Moment benutze ich das Autorize-Attribut, um den Zugriff auf verschiedene Teile meiner Anwendung zu kontrollieren. Hier haben wir ein Beispiel für eine API-Funktion für 3 verschiedene Rollen:Wie können Benutzer den Lese-/Schreibzugriff auf Entitäten steuern?

[Authorize(Roles = "ProductAdministrator, WebEditor, Manager")] 
public IActionResult Get() 
{ 
    IList<Product> products = _service.GetProducts(); 
    return Ok(products); 
} 

Wenn Sie nicht auf Ihrem Benutzer eine dieser Rollen verfügen, dann werden Sie nicht in der Lage sein, diese Liste der Produkte zuzugreifen.

Das Problem, mit dem ich gerade konfrontiert bin, ist, dass der Kunde, für den ich arbeite, in der Lage sein soll, den Rollenzugriff auf jedes Produktobjekt zu steuern. Bei der Erstellung sollte es wahrscheinlich eine Art von Standard-Rollensätzen geben, die dem Objekt zugewiesen sind. Ein "admin" -Benutzer sollte jedoch in der Lage sein, den Zugriff auf jedes Objekt/Objekt zu steuern.

Zum Beispiel könnten wir diese Aufgabe mit einigen Rollen haben:

var carProduct1 = new Product() { 
    Name = "Volvo XE 90", 
    Category = "Car", 
    Price = 51.600, 
    Roles = ["CarSeller", "ProductAdministrator", "Insurance", "VolvoExpert"] 
}; 

Und dann könnte dies ein weiteres Ziel seines

var carProduct2 = new Product() { 
    Name = "Ford Fiesta", 
    Category = "Car", 
    Price = 15000, 
    Roles = ["ProductAdministrator", "CarDealer", "FordExpert", "CarWorkshop"] 
}; 

Sie wahrscheinlich jetzt die Idee. Wie kann ich am besten von der Zugriffssteuerung auf Routerebene auf Objektebene zugreifen? Gibt es etwas dazu (meine Google-Suche war nicht fruchtbar)?

Antwort

1

Zusammenfassung der Erlaubnis Konzept weg von der Product. Möglicherweise möchten Sie später auch Berechtigungen für andere Objekte anwenden.

Die Product ist eine zulässige Entität.

public class Product : IPermissionProtected 
{ 
    ... 

    public Product(..., string[] allowedGroups) 
    { 
     this.AllowedGroups = allowedGroups; 
    } 

    public string[] AllowedGroups { get; private set;} 
} 

Maybe, wenn Sie erstellen die Product Sie die Berechtigungen festlegen. Nichts hält Sie davon ab, später auch diese Berechtigungen zu ändern.

var carProduct1 = new Product(new [] {"CarSeller", "ProductAdministrator", "Insurance", "VolvoExpert"}) { 
    Name = "Volvo XE 90", 
    Category = "Car", 
    Price = 51.600 
}; 

können Sie niemandem gestatten, die Product-Controller zuzugreifen. Von diesem Punkt an ist mir unklar, wie Sie genau gehen möchten, aber zum Beispiel könnten Sie nur die Produkte zurückgeben, zu denen der aktuelle Benutzer berechtigt ist.

public IActionResult Get() 
{ 
    IList<Product> products = _service.GetProducts(currentUserRole); 
    return Ok(products); 
} 

Sie können auch diese haben

public IActionResult Get(int productId) 
{ 
    try 
    { 
    Product product = _service.GetProduct(productId, currentUserRole); 
    return Ok(product); 
    } 
    catch (AuthorizationException ex) 
    { 
    return NotAuthorized(ex); 
    } 
} 

Sie die Service ändern können Sie das Produkt zu geben, auf die der Benutzer die Berechtigung hat.

public class Service 
{ 
    public IList<Product> GetProducts(string currentUserRole) 
    { 
     // compare against Product's AllowedGroups 
     return this.dataRepo.Products.Where(product => product.AllowedGroups.Contains(currentUserRole)).ToList(); 
    } 

    public Product GetProduct(int productId, string currentUserRole) 
    { 
     // compare against Product's AllowedGroups 
     var product = this.dataRepo.Products.FirstOrDefault(product => product.Id == productId); 

     if (!product.AllowedGroups.Contains(currentUserRole)) 
     { 
      throw new AuthorizationException("{0} not allowed on {1}", currentUserRole, product.Name); 
     } 
    } 
} 
Verwandte Themen