2017-02-05 4 views
0

У меня есть веб-приложение, основанное на ядре ядро ​​dotnet, ядре сущности, сервере идентификации и MS SQL Server в качестве базы данных (Angular 2 on frontend). Я уже выполнил авторизацию пользователя с ролями. Сейчас я использую атрибут Authorize для управления доступом к другой части моего приложения. Здесь мы имеем пример функции апи доступной для 3-х различных ролей:Как управлять доступом пользователей к чтению/записи?

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

Если вы не один из этих ролей на ваших пользователей, то вы не сможете открыть список продуктов.

Проблема, с которой я столкнулся сейчас, заключается в том, что клиент, с которым я работаю, хочу иметь возможность контролировать доступ к ролям каждого объекта продукта. При создании должен быть какой-то стандартный набор ролей, назначенных объекту. Но пользователь «admin» должен иметь возможность контролировать доступ к каждому объекту/сущности.

Например, мы могли бы иметь этот объект с некоторыми ролями:

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

И тогда это может быть другой объект

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

Вы, вероятно, получить идею прямо сейчас. Как я могу лучше всего перейти от контроля доступа на уровне маршрута до уровня объекта? Есть ли какие-либо записи об этом (мои поисковые запросы не были плодотворными)?

ответ

1

Аннотация концепция разрешения от Product. Возможно, вы захотите снова применить разрешения для других объектов.

public interface IPermissionProtected 
{ 
    string[] AllowedGroups { get; } 
} 

Product является допустимым объектом.

public class Product : IPermissionProtected 
{ 
    ... 

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

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

Может быть, когда вы создаете Product вы указываете разрешения. Ничто не мешает вам позже изменять эти разрешения.

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

Вы можете позволить любому получить доступ к Product Controller. С этого момента я не понимаю, как вы хотите идти точно, но, например, вы можете вернуть только те продукты, к которым у текущего пользователя есть разрешение.

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

Вы также можете иметь это

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

Вы можете изменить Service дать вам продукт, к которому пользователь имеет разрешение.

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); 
     } 
    } 
} 
Смежные вопросы