Как вы вставляете аутентификацию, роли и безопасность в свой DDD?
Как вы реализуете роли и безопасность в своих проектах С# Domain Driven Design? У нас есть некоторые дискуссии о том, следует ли это реализовать вызывающему приложению (ASP.NET MVC) или в самой модели домена (моделирование объектов и служб). Некоторые утверждают, что это должно быть на самом веб-сайте, так как там, где аутентификация уже существует. Но это означает, что вам необходимо повторно внедрять защиту каждый раз, когда вы интегрируетесь с основными бизнес-системами.
В качестве примера: Администратор должен иметь возможность выполнять практически любые действия в системе, такие как редактирование и удаление записей (т.е. они могут удалить пользовательский порядок). Пользователь, с другой стороны, должен иметь возможность редактировать и удалять свои собственные записи (т.е. Они могут добавлять/удалять элементы из своей корзины покупок).
Кстати, вот хороший тезис по теме, который охватывает 7 различных сценариев DDD и безопасности:
Безопасность в доменном дизайне
- Глава 4 Сценарии проектирования служб безопасности
- 4.1 Сценарий 1: Служба безопасности как регулярная служба
- 4.2 Сценарий 2. Безопасность, встроенная в пользовательский интерфейс
- 4.3 Сценарий 3: служба безопасности, инкапсулирующая модель домена
- 4.4 Сценарий 4: Служба безопасности как шлюз для пользовательского интерфейса
- 4.5 Сценарий 5: Служба безопасности в качестве адаптера для пользовательского интерфейса
- 4.6 Сценарий 6: Служба безопасности, интегрированная АОП с адаптерами
- 4.7 Сценарий 7: Служба безопасности, интегрированная с AOP
Я бы лично склонялся к AOP, используя PostSharp, но не делал много с ним раньше, я не решаюсь совершить прыжок.
Ответы
Ответ 1
Не забывайте, что среда исполнения уже имеет встроенную систему безопасности/пользователя - основной (см. этот существующий ответ - обратите внимание, что GenericIdentity
- это просто один вариант, довольно тривиально написать свой собственный).
Пользовательский интерфейс может обрабатывать создание и назначение принципала на основе конкретной реализации (действительно, IIRC ASP.NET и WCF делают это автоматически, или для winforms/wpf вы можете использовать идентификатор Windows или (через веб-сервис) тот же вход в ASP.NET).
Затем ваша бизнес-логика проверяет Thread.CurrentPrincipal
; из этого вы можете получить имя, метод проверки подлинности и проверить наличие ролей (без необходимости знать, как выполняются роли).
Время выполнения также обеспечивает встроенные проверки:
[PrincipalPermission(SecurityAction.Demand, Role = Roles.Admin)]
public void Foo() {...}
(где Roles.Admin
- строковая константа вашего имени роли). Это будет проверять доступ автоматически, бросая SecurityException
, если нет в роли. Вы также можете проверить код (полезно, если роль не фиксирована во время компиляции).
Очевидно, что ваш пользовательский интерфейс должен проверять роли (чтобы отключить/скрыть функциональность), но хорошо, чтобы бизнес-код обеспечивал выполнение ролей, не зная о пользовательском интерфейсе.
(добавлено)
Я должен упомянуть, что GenericIdentity
удобен для модульных тестов. Конечно, вы можете использовать собственный API безопасности, и никто не остановит вас...