Как предотвратить дублирование пользователей членства при использовании нескольких ролевых провайдеров с разными именами приложений? - PullRequest
1 голос
/ 21 июля 2010

У меня есть один провайдер членства, который использует имя приложения по умолчанию '/'. Затем у меня есть несколько приложений, которые используют эту общую конфигурацию поставщика членства. Каждое приложение имеет свою собственную конфигурацию поставщика ролей, все они используют одну и ту же базу данных, что и поставщик членства, но используют разные имена приложений, чтобы изолировать свои роли друг от друга.

Когда я создаю участника, создается отдельная запись пользователя, которая, следовательно, используется всеми приложениями. Затем я создаю особые роли, уникальные для каждого приложения, так как они используют другое имя приложения.

Проблема, с которой я сталкиваюсь, заключается в том, что я вызываю Roles.AddUserToRole для члена, который уже существует. Поставщик ролей не распознает пользователя, так как контекст имени приложения у участников членства и роли различен, и поэтому он продолжает создавать новую запись пользователя для имени приложения, которому принадлежит роль.

Как я могу предотвратить создание этих дубликатов пользовательских записей без разделения имени приложения между поставщиками членства и роли?

1 Ответ

2 голосов
/ 23 июля 2010

Записи на самом деле не являются «дубликатами».

Понимание взаимосвязи между поставщиками и ролью таблицы aspnet_Users может помочь в этом разобраться.

Во-первых, следует понимать, что MembershipProvider и RoleProvider не зависят друг от друга, за небольшим исключением некоторой проблемы с кровотечением в методе MembershipProvider.DeleteUser (), который я объясню позже.

Роль членства заключается в аутентификации пользователя и, с помощью аутентификации, в защите доступа к вашим ресурсам.

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

Это две отдельные проблемы, которые не связаны, независимо от того, что может означать состояние aspnet_Users.

Существенная проблема заключается в том, что для подключения всех провайдеров используется значение username. Guid userid аналогичен, и для любого имени пользователя создается только одна запись aspnet_users, если все провайдеры используют одно и то же имя приложения , потому что первое, что делает каждый провайдер, проверяет aspnet_users на совпадение имени пользователя и имени приложения. Если он находит его, он использует его, если нет, он создает его и назначает guid для идентификатора пользователя.

Хотя может показаться, что guid userId является «глобальным» идентификатором, это не так.

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

(Действительно глупое) нарушение Разделения проблем, о котором я упоминал ранее, включает действия, предпринимаемые SqlMembershipProvider при вызове DeleteUser (deleteRelatedData). Тогда SqlMembershipProvider действует так, как если бы он был единственной собакой в ​​бою, переходит к ролям и профилям для удаления записей, используя только его ключи, и, таким образом, пропускает записи, которые, как вы ожидаете, пропали.

Рассмотрим: (это использует вышеупомянутую настройку одиночного членства, нескольких ролей)

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

«Джон» по какой-то причине становится «уволенным парнем» и удаляется через членство. Как указывалось ранее, в нашем уникальном сценарии записи о членстве удаляются, но информация о ролях остается.

Новый «Джон» нанимается для ответа на телефонные звонки, и для него создается пользователь членства.

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

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

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

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

Кроме того, вы можете просто знать об этом и написать дополнительный код для очистки при удалении пользователя.

И то, и другое гораздо более привлекательный вариант, чем реализация пользовательских провайдеров.

Ура и удачи.

...