Принудительно проверить безопасность в ASP.NET MVC? - PullRequest
0 голосов
/ 05 марта 2011

Я создаю совместную веб-галерею, и у меня есть несколько ролей для каждого пользователя:

  1. Администратор * * 1004
  2. DeleteImage
  3. DeleteOwnImage
  4. и т.д ..

Для любого действия контроллера мы можем применить к ним тег [Authorize] плюс какие роли мы хотим разрешить, верно? Это нормально для Admin / DeleteImage, так как эти два являются глобальными; но мой вопрос, как DeleteOwnImage является своего рода контекстным, чтобы определить, является ли он действительным, нам нужно:

  1. Чтобы узнать, какое изображение оно пытается удалить (из запроса)
  2. Получить владельца этого изображения (из службы или хранилища)
  3. Сравнить текущего пользователя = этого владельца

Очевидно, что [Authorize] недостаточно для этого, но возможно ли это сделать на пользовательских ActionFilters? Любой намек?

Ответы [ 2 ]

4 голосов
/ 05 марта 2011

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

public class OwnImageAuthorizeAttribute : AuthorizeAttribute {
    public string ImageIdKey { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext) {
    bool authorized = false;
    // Get the current user
    var currentUser = ...;
    // Get the image ID, whether it is in the route or querystring
    int imageId
    if(int.TryParse(httpContext.RouteData.Values(ImageIdKey), out imageId)) {
        // From querystring: httpContext.Request.Querystring[ImageIdKey]
        // Authorize the user
        authorized = YourMethodToCheckIfUserIsOwner(currentUser, imageId);
    }

    return authorized;
}

Затем украсьте свой метод:

[OwnImageAuthorize(ImageIdKey = "imageId")]
public ActionResult MyAction() { }

Более подробную информацию вы можете найти здесь .

1 голос
/ 05 марта 2011

Вы можете легко добавить что-то подобное в ActionFilter, просто добавьте фильтр действий с реализованным OnActionExecuting.

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

EDIT: Если вы используете какой-либо контейнер IOC для репозиториев, вам следует поискать новые функции IOC в MVC3 (если вы используете MVC3) для добавления зависимостей в фильтры действий.

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

EDIT2:

Кстати, мне самому не очень нравится делать слишком много бизнес-логики в ActionFilters, особенно при обращении к БД. Даже больше, когда это что-то очень конкретное, что будет использоваться для одного действия.

...