Как вы вставляете аутентификацию, роли и безопасность в свой 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 безопасности, и никто не остановит вас...