Где авторизация вписывается в многоуровневую архитектуру?

24

Как правило, я размещаю решения об авторизации в своих контроллерах на стороне сервера. В последнее время это были конечные точки RESTful, но я думаю, что то же самое относится и к архитектуре типов MVC. Ради аргумента предположим, что это авторизация на основе ролей. Защищенный метод будет аннотирован или проверен и при необходимости вернет 403.

Теперь, учитывая, что авторизация на самом деле является бизнес-правилом - например, «только администраторы могут перечислять X», я думаю, что они должны быть перемещены вниз на уровень. Когда контроллер просит бизнес-уровень выполнить операцию, сервисный или бизнес-уровень сообщает контроллеру, что он не авторизован.

Это разумный подход? Есть ли недостатки в этом?

Я не хочу иметь AuthorisationService, который по существу содержит кучу статических процедурно-кодированных правил для этого, но, возможно, имеет смысл хранить всю логику доступа в одном месте. Является ли это сквозной проблемой, которую следует хранить отдельно?

Поэтому я спрашиваю, сделал ли кто-нибудь это и как они добились этого чистым способом или есть ли какие-нибудь хорошие ресурсы, которые я мог бы прочитать. Я использую Java fwiw, но это не зависит от языка.

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

Я читаю весенние документы по безопасности, которые приводят некоторые веские аргументы в пользу того, что это междисциплинарная проблема, но я боюсь, что это всего лишь «весенний путь» и хотел бы иметь более широкие перспективы. Это также связывает ваше приложение с конкретной структурой.

Том
источник
1
Статус 403 не подходит для проблем авторизации. Используйте 401.
gnasher729
@ gnasher729 Я думаю, что это задом наперед. 401 означает, что аутентификация не пройдена или не предоставлена, 403 означает, что у вас нет прав доступа: stackoverflow.com/questions/3297048/…
JimmyJames
@JimmyJames, есть еще одна школа мысли, что вам следует использовать только одну из них для всех сбоев аутентификации и авторизации, поскольку она не позволяет автоматизированным инструментам легко выводить бизнес-логику. Есть некоторая свобода действий.
Берин Лорич
1
@BerinLoritsch Извините, вы говорите, что идея состоит в том, чтобы усложнить понимание проблемы аутентификации или авторизации? RFC кажется довольно ясным, но утверждает, что вы можете использовать 404 вместо 403, если вы не хотите раскрывать слишком много информации. Можете ли вы дать ссылку на аргумент для использования 401 вместо 403?
Джимми Джеймс
@JimmyJames, да. Этот мыслительный процесс исходит от специалистов по безопасности, а не разработчиков. И я также видел вашу рекомендацию 404 полностью скрыть информацию, чтобы скрыть, что ресурс даже существует.
Берин Лорич

Ответы:

9

Рекомендуется выставлять только те параметры, на которые авторизован пользователь.

Это заставляет разрешение быть сквозной проблемой. «Представление» должно знать, что пользователю разрешено делать, прежде чем он сможет создавать параметры и меню для отображения.

Серверная часть не должна доверять интерфейсной части для принятия решений по безопасности, поэтому должна проверять саму авторизацию.

Могут существовать бизнес-правила, которые влияют на авторизацию в зависимости от данных, например, «Только пользователи с балансом более 5000 долларов США могут осуществлять перевод в иностранной валюте» или «Только пользователь, расположенный в головном офисе, может просматривать эти учетные записи». Поэтому в бизнес-логике требуется некоторая логика авторизации.

Существуют также технические полномочия для рассмотрения - кому разрешено просматривать журналы, кто может выполнять резервное копирование / восстановление базы данных и т. Д.

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

Джеймс Андерсон
источник
7

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

Теперь о том, как этого добиться «чистым способом». Мне не нравится идея засорять бизнес-логику проверками авторизации, поэтому может помочь некоторая конкретная реализация подхода аспектно-ориентированного программирования: это может быть украшение методов службы специальными атрибутами или использование динамических прокси с перехватами.

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

ialekseev
источник
7

Мне нравится опускать авторизационные проверки настолько низко, насколько это возможно! (Но не дальше!)

Вы все еще можете писать автоматические тесты авторизации для слоев "выше" этого. А некоторые правила могут быть применимы или иметь смысл только на более высоких уровнях, таких как уровень обслуживания (CanView / CanSerialize?). Но, как правило, я считаю, что самой безопасной стратегией авторизации является также стратегия «DRY-est»: держите авторизацию как можно ниже, в самом «общем» или «общем» коде, насколько это возможно (без чрезмерного усложнения правил аутентификации).

Подумай об альтернативе. Если ваши правила авторизации тестируются и применяются только на уровне сервиса, и ваши плохие доменные объекты подчиняются воле ненадежных сервисных объектов, вам часто придется применять каждое отдельное правило более одного раза, в нескольких объектах и ​​нескольких места в каждом объекте и в более сложном коде.

Кроме того, когда ваша аналитическая команда нанимает консалтинговую фирму для написания отчетов с использованием ваших доменных объектов, вам не нужно доверять этим разработчикам! (Или что угодно. Вы создаете дополнительные сервисы или звонки на одни и те же объекты для любого Вы не хотите , чтобы взломать большую книгу бизнеса - правила и разума.) Надежд для обеспечения соблюдения этих правил должным образом снова ; Вы хотите, чтобы ваш домен уже знал их и применял их.

svidgen
источник
@ Если я понимаю вашу озабоченность - вот в чем дело. Если только «администратор» имеет разрешение, согласно бизнес-правилам, на создание Widget, то же правило применяется везде. (Так что не рискуйте позволять кому-либо игнорировать его!) Если правило не применяется повсеместно, это не совсем правило, Widgetsа только Widgets . , Оттолкнуть правила настолько, насколько они (отдельные правила) могут пойти; но не настолько, насколько «правила» могут зайти ... Я чувствую, что не очень хорошо провожу различие. Но там должно быть различие.
svidgen
По моему опыту, правила авторизации часто являются частью бизнес-правил. Таким образом, «как можно ниже» часто является моим доменным слоем. Но я подозреваю, что то, где ваши правила «должны» попасть, является лишь следствием вашего домена, характера правил и того, как бизнес говорит о них.
svidgen