2009-11-26 3 views
3

Я начинаю искать ASP.Net MVC. Один из вопросов, который у меня есть, - это рекомендации по защите пользовательских данных. Например, в сценарии продавцов, они должны иметь возможность просматривать свои собственные данные.MVC Защита пользовательских данных Защита данных

например.

SalesData/Edit/14 

Это очень легко изменить «14» для просмотра других данных, которые они могут/или могут не иметь доступа.

На данный момент я думаю о своих контролерах, чтобы проверить, кто вошел в систему, и проверить, есть ли у них доступ к запрашиваемому «id». Проблема, которую я вижу в этом, заключается в том, что это будет широкое применение, и я ищу лучшие практики по тому, как подойти к этому. Должен ли я смотреть на CustomControllers? Фильтры? или что? Любые статьи/ссылки для того, как справиться с этим, будут оценены.

ответ

1

Настройте методы извлечения данных из репозитория базы данных таким образом, чтобы вы могли передать UserID текущего пользователя в качестве параметра. Затем вы можете использовать таблицу разрешений для фильтрации данных только для тех данных, для которых пользователь имеет доступ.

Таблица разрешений имела бы два поля: UserID и ContentID. Как только это настроено, довольно просто настроить экраны CRUD, чтобы кто-то с правами администратора мог устанавливать разрешения на контент.

+0

Хорошее предложение. Re: таблица разрешений, какой будет ContentID? Допустим, у меня есть Orders, OrderItems, SalesSlips и т. Д. ... многие объекты. Что будет contentId быть? и как я узнаю, что такое ID-карты? – zzz

+0

В этом случае вам нужно другое поле в таблице разрешений, которая является табличным идентификатором. Было бы неплохо иметь таблицу, содержащую имена таблиц и идентификаторы таблиц. –

+0

Или вы можете просто перейти к объекту, к которому у пользователя есть доступ, который включает в себя записи, о которых идет речь. Например, если продавец имеет доступ к определенному заказу, он также имеет доступ ко всем OrderItems в этом порядке. –

0

Я использую атрибут IPrincipal и Authorize (Roles = '...') для ограничения доступа к действиям. Затем IPrincipal вводится в сервисный уровень, а пользовательский идентификатор используется для фильтрации данных.

Пример: пользователи создают задачи. Каждый пользователь может видеть свои задачи. Метод GetTask (int taskId) сначала фильтрует поле CreatedBy с использованием идентификатора из IIdentity, а затем принимает задание с указанным идентификатором. Если у пользователя нет доступа к данным, метод не будет возвращать строки.

1

Проблема, которую я вижу с этим, что это будет широкое применение,

Затем вам нужно общий сервис, который обрабатывает его. Удивительно, но я бы назвал это IAuthorisationService.

и я ищу лучшие практики о том, как подойти к этому. Должен ли я искать на CustomControllers? Фильтры? или что?

Какой бы способ вы ни выбрали, вы должны использовать общий сервис IAuthorisationService.
Из моего опыта я могу сказать, что легче внедрить услугу в контроллер и использовать его на каждом действии:

/* Interfaces */ 
public interface IAuthorisationService { 
    bool CanEdit(YourItem item); 
} 

public interface ICurrentUserProvider { 
    YourUserEntity GetCurrentUser(); 
} 

/* Implementations */ 
public class HttpUserProvider : ICurrentUserProvider { 
    public YourUserEntity GetCurrentUser() { 
     return HttpContext.Current.User.Principal as YourUserEntity; 
    } 
} 

public calss RolesAuthorisationService : IAuthorisationService { 
    ICurrentUserProvider userProvider 
    public RolesAuthorisationService(ICurrentUserProvider userProvider) { 
     this.userProvider = userProvider; 
    } 

    public bool CanEdit(YourItem item) { 
     var u = userProvider.GetCurrentUser(); 
     if (u == null) 
      return false; 
     return item.Owner == u && u.IsInRole("EditYourItem"); 
    } 
} 

/* Controller */ 

public class MyController: Controller { 
    IAuthorisationService authorisation; 

    public MyController(IAuthorisationService authorisation) { 
     this.authorisation = authorisation; 
    } 

    public ActionResult Edit(int id) { 
     var item = GetTheItembyIdSomehow(); 
     if (!authorisation.CanEdit(item)) 
      return new HttpUnauthorizedResult(); 

     // Can do this 
    } 
} 

Затем вы можете использовать ControllerFactory вводить необходимые зависимости автоматически в контроллеры:

class DependencyInjectionContainer : WindsorContainer { 
    public DependencyInjectionContainer() { 
     RegisterDependencies(); 
    } 

    private void RegisterDependencies() { 

     // Services 
     Register(
      AllTypes.Of<IDiscoverableService>() 
       .FromAssembly(typeof(IDiscoverableService).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
       .WithService.FromInterface() 
      ); 

     // Controllers 
     Register(
      AllTypes.Of<IController>() 
       .FromAssembly(typeof(DependencyInjectionContainer).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
      ); 
    } 
} 

class WindsorControllerFactory : DefaultControllerFactory, IDisposable { 
    private readonly IWindsorContainer container; 

    public WindsorControllerFactory() { 
     container = new DependencyInjectionContainer(); 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     if (controllerType == null) 
      return base.GetControllerInstance(controllerType); 
     return (IController) container.Resolve(controllerType); 
    } 

    public void Dispose() { 
     container.Dispose(); 
    } 
} 
+0

Глядя на свой код, кажется, что вы указываете только такие роли, как «редактировать», а не разрешения для определенных элементов. –

+0

Ох. Да. Сожалею. Я обновлю его. –

Смежные вопросы