MVC Защита пользовательских данных безопасности - PullRequest
3 голосов
/ 26 ноября 2009

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

, например

SalesData/Edit/14

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

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

Ответы [ 3 ]

1 голос
/ 26 ноября 2009

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

Тогда вам нужен общий сервис, который его обрабатывает. Удивительно, но я бы назвал это 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();
    }
}
1 голос
/ 26 ноября 2009

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

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

0 голосов
/ 26 ноября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...