Я бы не стал называть исходный комментарий так, как он был сформулирован, но он идентифицирует потенциально законную проблему.
В частности, проблемы, которые требуют разделения, - это аутентификация и авторизация .
Аутентификация относится к процессу входа в систему и получения личности. Это то, как системы узнают, кто вы , и используются для таких вещей, как персонализация, владение объектами и т. Д.
Авторизация относится к тому, что вам разрешено делать , и это (как правило) не определяется тем, кто вы есть . Вместо этого это определяется некоторой политикой безопасности, например ролями или разрешениями, которые не заботятся о таких вещах, как ваше имя или адрес электронной почты.
Эти два могут меняться ортогонально друг к другу. Например, вы можете изменить модель аутентификации, добавив поставщиков OpenID / OpenAuth. И вы можете изменить политику безопасности, добавив новую роль или сменив RBAC на ABAC.
Если все это входит в один класс или абстракцию, то , по иронии судьбы, ваш код безопасности, который является одним из ваших самых важных инструментов для снижения риска , становится, по иронии, высоким.
Я работал с системами, где аутентификация и авторизация были слишком тесно связаны. В одной системе было две параллельные пользовательские базы данных, каждая для одного типа «роли». Человек или команда, которые его разработали, очевидно, никогда не считали, что один физический пользователь может быть в обеих ролях, или что могут быть определенные действия, которые являются общими для нескольких ролей, или что могут быть проблемы с конфликтами идентификаторов пользователей. Это, по общему признанию, крайний пример, но работать с ним было невероятно больно.
Microsoft и Sun / Oracle (Java) называют совокупность информации об аутентификации и авторизации как принципала безопасности . Это не идеально, но работает достаточно хорошо. В .NET, к примеру, у вас есть IPrincipal
, что инкапсулируетIIdentity
- бывшую ЯВЛЯЮЩУЮСЯ политика (авторизация) объект , а последняя является идентичностью (аутентификация). Можно обоснованно ставить под сомнение решение поставить один внутри другого, но главное в том , что большая часть кода вы пишете будет только для одного из абстракций , который означает , что это легко проверить и реорганизовать.
Нет ничего плохого в User.IsAdmin
поле ... если только нет User.Name
поля. Это может указывать на то, что концепция «Пользователь» не определена должным образом, и, к сожалению, это очень распространенная ошибка среди разработчиков, которые немного не понимают, когда речь заходит о безопасности. Как правило, единственной вещью, которая должна совместно использоваться идентификаторами и политиками, является идентификатор пользователя, который, не случайно, является именно тем, как он реализован в моделях безопасности Windows и * nix.
Вполне допустимо создавать объекты-оболочки, которые инкапсулируют как идентичность, так и политику. Например, это облегчит создание экрана панели мониторинга, на котором вам необходимо отобразить «привет» сообщение в дополнение к различным виджетам или ссылкам, к которым у текущего пользователя есть доступ. Пока эта обертка просто оборачивает идентификационную информацию и информацию о политике и не претендует на владение ею. Другими словами, до тех пор, пока он не будет представлен как совокупный корень .
Упрощенная модель безопасности всегда кажется хорошей идеей, когда вы впервые разрабатываете новое приложение, из-за YAGNI и тому подобного, но она почти всегда заканчивается тем, что позже вас кусает, потому что, к удивлению, добавляются новые функции!
Итак, если вы знаете, что лучше для вас, вы будете хранить информацию об аутентификации и авторизации отдельно. Даже если «авторизация» прямо сейчас так же проста, как флаг «IsAdmin», вам все равно будет лучше, если он не входит в тот же класс или таблицу, что и информация аутентификации, так что если и когда ваша политика безопасности должна изменить, вам не нужно делать реконструктивные операции в ваших системах аутентификации, которая уже работает нормально.