AuthorizeAttribute MVC - ограничить доступ к пользовательскому контенту
Поэтому я прочитал о том, как плохо реализованы ваши собственные процедуры авторизации!
И я испугался, потому что я реализовывал свои действия как таковые (например, предотвращение доступа к данным учетной записи, если аутентифицированный пользователь не вошел в систему)
public ActionResult DisplayAccount(int someid){
Account a = context.Accounts.Single(a => a.id == someid);
// currentUserId() returns userid from FormsAuthentication
if (!a.owner == currentUserId()){
/* Not Authorised! */
}
}
Что, очевидно, означает, что он сломается, если ASP решит кэшировать мое действие (поэтому действие даже не будет выполнено).
Так что теперь я изучаю использование AuthorizeAttribute, чтобы сделать то, что мне нужно, что
- запретить доступ к действию, если он не прошел проверку подлинности
- проверить, имеет ли аутентифицированный пользователь доступ к полученному ресурсу
Однако всякий раз, когда я думаю об этом, я не могу думать о том, как реализовать 2-й пункт. Роли не работают, потому что это на уровне сайта, но внутри приложения пользователи также имеют роли (например, владелец, модератор, участник, пользователь и т. Д.), И они имеют эти роли только в своих соответствующих частях приложения (например, владелец темы, автор вики, модератор форума и т. д.)
Я столкнулся с несколькими примерами переопределения AuthorizeCore. Я могу себе представить создание нескольких подклассов AuthorizeAttribute для каждого имеющегося у меня ресурса (к счастью, не многих), но означает ли это, что мне приходится запрашивать базу данных каждый раз, когда я нажимаю на это действие, чтобы гарантировать, что зарегистрированный пользователь должен получить доступ к этим данным, а затем запросить базу данных в моем действии, чтобы получить модель, вместо того, чтобы делать это в моем запросе?
Так что мои вопросы
- я слишком беспокоюсь о кешировании? Произойдет ли что-либо из следующего
- веб-сайт кэширует данные пользователя A, которые отображаются на экране пользователя B?
- веб-сайт кэширует версию страницы администратора (с элементами управления редактированием), а обычный пользователь видит кэшированную версию?
- Использование AuthorizeAttribute само собой разумеющееся, но как мне добиться того, что мне нужно сделать в пункте 2, не обращаясь к базе данных перед действием? Или каков наилучший способ добиться этого в любом случае.
- Или я использую только AuthorizeAttribute, чтобы определить, вошел ли пользователь в систему, и выполнить другую логику проверки в моих действиях?
Во всяком случае, я надеюсь, что этот пост не идет по каким-либо старым путям (я не мог найти ничего по этому, что я нашел окончательным)
Изменить: Я думаю, если я не включаю кэширование, эта проблема не возникнет, это правильно?
Изменить: сейчас я собираюсь использовать vanilla AuthorizeAttribute, затем проверять доступ к уровню ресурсов в моих действиях, а затем убедиться, что я не использую кэширование для любых аутентифицированных действий. Надеюсь, получит больше ответов на это в течение недели.
1 ответ
Я использовал следующий подход в недавнем проекте, создавая DataRightsAttribute, который использовал перечисление для каждого поддерживаемого типа модели. Он работает, сначала извлекая идентификатор из данных маршрута, formcollection или строки запроса. Затем он запросил тип модели, определенный в enum, и провел соответствующую проверку, чтобы проверить, авторизован ли текущий пользователь к нему.
Использование было так:
[DataRights(ModelType.Customer)]
Он использовался вместе с AuthorizeAttribute (который мы переопределили) и никогда не замечал никаких проблем с кэшированием.