Как точно настроить поставщика членства? - PullRequest
2 голосов
/ 30 апреля 2010

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

Хорошо, во-первых, уточнить: я знаю, что такое провайдер членства, ролей и профилей, как реализовать свои собственные и как их настраивать, а также большинство вещей о них.
Реализация поставщика ролей и профилей довольно проста, поскольку большую часть времени они требуют простого CRUD. (Одной строки LINQ достаточно для примерно половины методов RoleProvider.)

Тем не менее, поставщик членства является другим зверем. Многие из вас могут понять, что это нарушает принцип SR (Single Responsibility), потому что он должен делать ВСЕ, что связано с управлением пользователями. Хотя это оставляет много места для настроек, у него есть и свои недостатки. В Интернете нет информации о том, каково их ТОЧНОЕ ожидаемое поведение, например, когда они должны выдавать исключения или просто возвращать ноль, и тому подобное.

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

  • Например, он использует свой собственный метод ValidateUser для проверки учетных данных в методе ChangePassword. Но ValidateUser также обновляет LastLoginDate пользователя до текущей даты. Итак, ожидает ли фреймворк, что я установлю его и в моем собственном провайдере, или это просто ошибка в образце?
  • Другое: метод ChangePassword каждый раз выдает исключение при проверке нового пароля, но CreateUser никогда не выдает исключение, он просто возвращает false.
  • И последнее, но не менее важное: он считает попытки ввода неверного пароля пользователя и блокирует их, если он превышает пороговое значение. Хотя это хорошо, но требует ручного действия, чтобы разблокировать пользователей. Это проблема, если мой провайдер автоматически разблокирует пользователя через определенное время?

  • (EDIT) Я почти забыл: метод CreateUser в образце вставляет идентификатор из параметра метода. Я на самом деле считаю, что это плохая практика, потому что я использую в качестве идентификаторов inters с автоматическим вводом, поэтому вставка их из какого-либо параметра метода не подходит. Стоит ли просто игнорировать параметр или требовать, чтобы его значение было нулевым, и выдавать исключение, если это не так?

В общем, есть ли у ASP.NET какие-либо предположения о поведении MembershipProvider?
Есть ли документация, описывающая, когда следует выдавать исключение или просто возвращать ноль?

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

Заранее всем спасибо!

1 Ответ

4 голосов
/ 30 апреля 2010

Вы можете обратиться к MSDN за руководством. Например, RoleProvider.RemoveUsersFromRoles предоставляет следующее руководство:

RemoveUsersFromRoles вызывается RemoveUserFromRole, RemoveUsersFromRole, RemoveUserFromRoles и RemoveUsersFromRoles методы Роли класса для удаления указанного пользователи из указанных ролей на источник данных. Только роли для настроенные ApplicationName являются модифицировано.

Если какое-либо из указанных имен ролей не найден для настроенного applicationName, мы рекомендуем ваш провайдер бросает ProviderException.

Если любое из указанных имен пользователей не связано ни с одним из указанные имена ролей для настроил applicationName, мы рекомендую вашему провайдеру бросить ProviderException.

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

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

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

А RoleProvider.GetRolesForUser говорит:

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

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

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

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

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

Если вы используете отражатель и изучаете SqlMembershipProvider, вы заметите некоторые существенные различия ...

Например:

  • ValidateUser обновляет дату входа в систему, потому что пользователь входит в систему и делает это, вызывая .CheckPassword со значением true для UpdateLastLoginTime. Смена пароля вызывает тот же метод, но предоставляет false.

  • Метод CreateUser принимает ProviderUserKey, поскольку SPROC также будет принимать параметр UserId. Это необходимо для воссоздания и синхронизации между таблицами членства и пользователей. Как пользователь API вы обычно не используете эту функциональность, но стек провайдера используется внутренне.

  • Относительно локаута. Это зависит от вас. Вот в чем заключается реализация пользовательских провайдеров: получить желаемое поведение. Как я уже сказал, систематических требований очень мало.

Итак, это подводит нас к последней части вашего вопроса (оба параграфа ссылаются на одну и ту же проблему): ожидаемое поведение и модульное тестирование ...

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

В качестве заключительного замечания я предлагаю вам найти и загрузить образцы инструментария провайдера Asp.Net. Он предоставляет вам рабочий исходный код для полного стека поставщиков Sql и даст вам некоторое представление о том, как реализованы «настоящие» поставщики.

* 1066 запоздалые мысли *:

В данный момент я реализую полный стек поставщиков SQLite, который на 100% совместим со стеком Sql по умолчанию. Набор тестов проверяет поведенческий паритет между моим стеком и asp.net. Если вы зайдете в мой блог через мой профиль и свяжетесь со мной, я сообщу вам, когда тесты будут завершены, и вы сможете использовать их в качестве эталона того, что именно ожидается от стека по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...