Реализация поставщика членства

Visual Studio 2010

Обновлен: Ноябрь 2007

Членство ASP.NET разработано для того, чтобы обеспечить простое использование нескольких различных поставщиков членства для приложений ASP.NET. Можно использовать предоставленных поставщиков членства, входящих в платформу .NET Framework, или реализовать собственных поставщиков.

Существует две главные причины для создания пользовательского поставщика членства.

  • Необходимо хранить информацию членства в источнике данных, который не поддерживается поставщиками членства, входящими в платформу .NET Framework, таком как базы данных FoxPro и Oracle, или других источниках данных.

  • Необходимо управлять информацией членства с использованием схемы базы данных, которая отличается от той, которую применяют поставщики, поставляемые вместе с платформой .NET Framework. В качестве типичного примера такого случая можно привести данные членства, которые уже существуют в базе данных SQL Server для компании или веб-узла.

Для реализации поставщика членства создается класс, наследующий абстрактный класс MembershipProvider от пространства имен System.Web.Security. Абстрактный класс MembershipProvider наследует абстрактный класс ProviderBase от пространства имен System.Configuration.Provider, поэтому также необходимо реализовать требуемые члены класса ProviderBase. В таблицах ниже указаны необходимые свойства и методы, которые должны быть реализованы из абстрактных классов ProviderBase и MembershipProvider, и приведены их описания. С реализацией каждого члена можно ознакомиться, просмотрев пример кода в разделе Пример реализации поставщика членства.

Член

Описание

Метод Initialize

Входные данные: имя поставщика и объекта NameValueCollection параметров конфигурации. Используется для задания значений параметров экземпляра поставщика, включая связанных с реализацией значений и параметров, указанных в файле конфигурации (Machine.config или Web.config), поставляемом в конфигурации.

Обязательные члены MembershipProvider

Член

Описание

Свойство EnablePasswordReset

Логическое значение (Boolean), указанное в файле конфигурации (Web.config).

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

Это свойство доступно только для чтения.

Свойство EnablePasswordRetrieval

Логическое значение (Boolean), указанное в файле конфигурации (Web.config).

Свойство EnablePasswordRetrieval указывает, могут ли пользователи извлекать свои пароли с помощью метода GetPassword.

Это свойство доступно только для чтения.

Свойство RequiresQuestionAndAnswer

Логическое значение (Boolean), указанное в файле конфигурации (Web.config).

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

Это свойство доступно только для чтения.

Свойство RequiresUniqueEmail

Логическое значение (Boolean), указанное в файле конфигурации (Web.config).

Свойство RequiresUniqueEmail определяет необходимость предоставления пользователем уникального значения адреса электронной почты при создании пользователя. Если пользователь уже существует в источнике данных для текущего свойства ApplicationName, то метод CreateUser возвращает значение null (в Visual Basic — Nothing) и значение состояния в виде поля DuplicateEmail.

Это свойство доступно только для чтения.

Свойство PasswordFormat

Значение MembershipPasswordFormat, указанное в файле конфигурации (Web.config).

Свойство PasswordFormat указывает формат, в котором хранятся пароли. Пароли могут храниться в форматах Clear, Encrypted и Hashed. Пароли в формате Clear хранятся в виде обычного текста, что увеличивает производительность механизма сохранения и извлечения паролей, но снижает безопасность, поскольку пароли легко считываются в случае несанкционированного доступа к данным. Пароли в формате Encrypted шифруются при сохранении и могут быть дешифрованы при сравнении или извлечении паролей. При этом требуется дополнительная обработка при сохранении и извлечении паролей, но обеспечивается большая безопасность, поскольку в случае несанкционированного доступа к данным пароли невозможно легко определить. Пароли в формате Hashed при сохранении в базе данных хэшируются с использованием однонаправленного хэш-алгоритма и формируемого случайным образом расширяющего значения. При проверке пароль хэшируется с использованием расширяющего значения. Хэшированные пароли не могут быть извлечены.

Можно использовать виртуальные методы EncryptPassword и DecryptPassword класса MembershipProvider или пользовательский код для шифрования и расшифровки значений паролей. При использовании виртуальных методов EncryptPassword и DecryptPassword класса MembershipProvider пароли формата Encrypted шифруются с использованием сведений о ключе, предоставляемых элементом Элемент machineKey (схема параметров ASP.NET) в пользовательской конфигурации.

Это свойство доступно только для чтения.

Свойство MaxInvalidPasswordAttempts

Значение Integer, указанное в файле конфигурации (Web.config).

Свойство MaxInvalidPasswordAttempts в сочетании со свойством PasswordAttemptWindow используется для предотвращения нелегального подбора пароля или контрольного ответа для пароля пользователя членства посредством повторяющихся попыток. Если количество выполненных пользователем членства попыток ввода недействительных пароля или контрольного ответа для пароля превысит значение, заданное свойством MaxInvalidPasswordAttempts, в пределах количества минут, определяемого свойством PasswordAttemptWindow, то пользователь членства блокируется путем присвоения свойству IsLockedOut значения true до тех пор, пока посредством вызова метода UnlockUser не будет снята блокировка. Если предоставляется допустимые пароль или контрольный ответ для пароля до достижения значения свойства MaxInvalidPasswordAttempts, то счетчик, который отслеживает количество недопустимых попыток, обнуляется.

Свойство RequiresQuestionAndAnswer имеет значение false, то попытки ввода недействительного контрольного ответа для пароля не отслеживаются.

Попытки ввода недействительных пароля и контрольного ответа для пароля отслеживаются в методах ValidateUser, ChangePassword, ChangePasswordQuestionAndAnswer, GetPassword и ResetPassword.

Это свойство доступно только для чтения.

Свойство PasswordAttemptWindow

Значение Integer, указанное в файле конфигурации (Web.config).

Описание этого свойства см. в описании свойства MaxInvalidPasswordAttempts.

Это свойство доступно только для чтения.

Свойство ApplicationName

Имя приложения, использующего сведения о членстве, содержащиеся в файле конфигурации (Web.config). Свойство ApplicationName хранится в источнике данных со связанной с ним информацией о пользователе и используется при запросе этой информации. Дополнительные сведения о свойстве ApplicationName см. в этом разделе ниже.

Это свойство доступно для чтения и записи. Значение по умолчанию: ApplicationPath, если явно не указано.

Метод CreateUser

Принимает в качестве входных данных имя нового пользователя, пароль и адрес электронной почты и вставляет нового пользователя для приложения в источник данных. Метод CreateUser возвращает объект MembershipUser, заполненный информацией для вновь созданного пользователя. Метод CreateUser также описывает параметр out (в Visual Basic можно использовать ByRef), который возвращает значение MembershipCreateStatus, указывающее, что пользователь успешно создан, или причину неудачи при создании пользователя.

Метод CreateUser вызывает событие ValidatingPassword, если указан обработчик событий MembershipValidatePasswordEventHandler, и продолжает или отменяет действие по созданию пользователя в зависимости от результатов события. Можно использовать виртуальный метод OnValidatingPassword для выполнения указанного обработчика событий MembershipValidatePasswordEventHandler.

Метод UpdateUser

Принимает в качестве входных данных объект MembershipUser, заполненный информацией о пользователе, и обновляет источник данных предоставленными значениями.

Метод DeleteUser

Принимает в качестве входных данных имя пользователя и удаляет информацию этого пользователя из источника данных. Метод DeleteUser возвращает значение true если пользователь успешно удален; в противном случае — значение false. Включается дополнительный параметр Boolean, указывающий, удалена ли также связанная с пользователем информация, такая как роль или профиль.

Метод ValidateUser

Принимает в качестве входных данных имя пользователя и пароль и проверяет их наличие в источнике данных. Метод ValidateUser возвращает значение true в случае существования указанных имени пользователя и пароля; в противном случае — значение false.

Метод GetUser

Принимает в качестве входных данных уникальный идентификатор пользователя и логическое значение Boolean, указывающее, нужно ли обновлять значение свойства LastActivityDate для пользователя, чтобы показать, что пользователь находится в интерактивном режиме. Метод GetUser возвращает объект MembershipUser, заполненный текущими значениями из источника данных для указанного пользователя. Если имя пользователя не найдено в источнике данных, то метод GetUser возвращает значение null (в Visual Basic — Nothing).

Метод GetUser

Принимает в качестве входных данных имя пользователя и логическое значение Boolean, указывающее, нужно ли обновлять значение свойства LastActivityDate для пользователя, чтобы показать, что пользователь находится в интерактивном режиме. Метод GetUser возвращает объект MembershipUser, заполненный текущими значениями из источника данных для указанного пользователя. Если имя пользователя не найдено в источнике данных, то метод GetUser возвращает значение null (в Visual Basic — Nothing).

Метод GetAllUsers

Возвращает значение MembershipUserCollection, заполненное объектами MembershipUser, для всех пользователей в источнике данных.

Результаты, возвращаемые методом GetAllUsers, ограничиваются параметрами pageIndex и pageSize. Параметр pageSize идентифицирует максимальное количество объектов MembershipUser, возвращаемых коллекцией MembershipUserCollection. Параметр pageIndex определяет возвращаемую страницу результатов, причем «1» указывает первую страницу. Параметр totalRecords является выходным параметром (out) и задается в соответствии с общим количеством пользователей членства в базе данных. Например, если имеется 13 пользователей в базе данных, и параметру pageIndex присвоено значение 2, а параметр pageSize имеет значение 5, то возвращаемая коллекция MembershipUserCollection будет содержать с шестого по десятого пользователей. Параметру totalRecords будет присвоено значение 13.

Метод GetNumberOfUsersOnline

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

Метод ResetPassword

Принимает в качестве входных данных имя пользователя и контрольный ответ для пароля и случайным образом формирует новый пароль для указанного пользователя. Метод ResetPassword обновляет информацию о пользователе в источнике данных новым значением пароля и возвращает новый пароль в виде string. Удобным механизмом формирования пароля случайным образом является метод GeneratePassword класса Membership.

Метод ResetPassword обеспечивает присвоение свойству EnablePasswordReset значения true перед выполнением любого действия. Если свойство EnablePasswordReset имеет значение false, то возникает исключение NotSupportedException. Метод ResetPassword также проверяет значение свойства RequiresQuestionAndAnswer. Если свойству RequiresQuestionAndAnswer присвоено значение true, то метод ResetPassword сравнивает значение предоставленного параметра контрольного ответа для пароля с хранящимся в источнике данных. Если они не совпадают, возникает исключение MembershipPasswordException.

Метод ResetPassword вызывает событие ValidatingPassword, если указано MembershipValidatePasswordEventHandler, чтобы проверить вновь сформированный пароль и продолжает или отменяет действие по сбросу пароля в зависимости от результатов события. Можно использовать виртуальный метод OnValidatingPassword для выполнения указанного обработчика событий MembershipValidatePasswordEventHandler.

Метод GetPassword

Принимает в качестве исходных данных имя пользователя и контрольный ответ для пароля и извлекает из источника данных пароль для указанного пользователя, который возвращается в виде строки (string).

GetPassword обеспечивает, чтобы свойству EnablePasswordRetrieval перед выполнением какого-либо действия было присвоено значение true. Если свойству EnablePasswordRetrieval присвоено значение false, то возникает исключение ProviderException.

Метод GetPassword также проверяет значение свойства RequiresQuestionAndAnswer. Если свойству RequiresQuestionAndAnswer присвоено значение true, то метод GetPassword сравнивает значение предоставленного параметра контрольного ответа для пароля с хранящимся в источнике данных. Если они не совпадают, возникает исключение MembershipPasswordException.

Метод GetUserNameByEmail

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

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

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

Метод ChangePassword

Принимает в качестве входных данных имя пользователя, текущий пароль и новый пароль и обновляет пароль в источнике данных в случае допустимых имени пользователя и текущего пароля. Метод ChangePassword возвращает значение true, если пароль был успешно обновлен; в противном случае — false.

Метод ChangePassword вызывает событие ValidatingPassword, если указан обработчик событий MembershipValidatePasswordEventHandler, и продолжает или отменяет действие по изменению пароля в зависимости от результатов события. Можно использовать виртуальный метод OnValidatingPassword для выполнения указанного обработчика событий MembershipValidatePasswordEventHandler.

Метод ChangePasswordQuestionAndAnswer

Принимает в качестве входных данных имя пользователя, пароль, контрольный вопрос и ответ и обновляет контрольный вопрос и ответ в источнике данных в случае допустимого имени пользователя и текущего пароля. Метод ChangePasswordQuestionAndAnswer возвращает значение true если контрольный вопрос и ответ были успешно обновлены; в противном случае — false.

Если предоставлено недопустимое имя пользователя и пароль, то возвращается значение false.

Метод FindUsersByName

Возвращает список пользователей членства, содержащих совпадения с предоставленным usernameToMatch для настроенного свойства ApplicationName. Например, если параметру usernameToMatch присвоено значение «user», тогда возвращаются пользователи «user1», «user2», «user3» и т. д. Поддерживаются подстановочные знаки на основе источника данных. Имена пользователей возвращаются в алфавитном порядке.

Результаты, возвращаемые методом FindUsersByName, ограничиваются параметрами pageIndex и pageSize. Параметр pageSize идентифицирует количество объектов MembershipUser, возвращаемых коллекцией MembershipUserCollection. Параметр pageIndex определяет возвращаемую страницу результатов, причем «1» указывает первую страницу. Параметр totalRecords является выходным параметром (out) и задается в соответствии с общим количеством пользователей членства, которые соответствуют значению usernameToMatch. Например, если найдено 13 пользователей, в чьих полных именах имеется часть, совпадающая с параметром usernameToMatch, и параметру pageIndex присвоено значение 2, а параметр pageSize имеет значение 5, то возвращаемая коллекция MembershipUserCollection будет содержать с шестого по десятого пользователей. Параметру totalRecords будет присвоено значение 13.

Метод FindUsersByEmail

Возвращает список пользователей членства, содержащих совпадения с предоставленным emailToMatch для настроенного свойства ApplicationName. Например, если параметру emailToMatch присвоено значение «address@example.com», то возвращается информация для пользователей с адресами электронной почты «address1@example.com», «address2@example.com» и т. п. Поддерживаются подстановочные знаки на основе источника данных. Имена пользователей возвращаются в алфавитном порядке.

Результаты, возвращаемые методом FindUsersByEmail, ограничиваются параметрами pageIndex и pageSize. Параметр pageSize идентифицирует количество объектов MembershipUser, возвращаемых коллекцией MembershipUserCollection. Параметр pageIndex определяет возвращаемую страницу результатов, причем «1» указывает первую страницу. Параметр totalRecords является выходным параметром (out) и задается в соответствии с общим количеством пользователей членства, которые соответствуют значению emailToMatch. Например, если найдено 13 пользователей, в чьих полных именах имеется часть, совпадающая с параметром emailToMatch, и параметру pageIndex присвоено значение 2, а параметр pageSize имеет значение 5, то возвращаемая коллекция MembershipUserCollection будет содержать с шестого по десятого пользователей. Параметру totalRecords будет присвоено значение 13.

Метод UnlockUser

Принимает в качестве входных данных имя пользователя и обновляет поле в источнике данных, в котором хранится свойство IsLockedOut, значением false. Метод UnlockUser возвращает значение true, если запись для пользователя членства обновлена успешно; в противном случае — значение false.

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

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

SELECT Username FROM MyUserTable 
  WHERE Email = 'someone@example.com' AND ApplicationName = 'MyApplication'

Можно расширить интерфейсы поставщика членства дополнительными функциями, не предоставляемыми абстрактными классами ProviderBase и MembershipProvider. Любой открытый член, добавляемый к поставщику членства, будет доступен при помощи свойства Provider или Providers класса Membership.

Примером этого может служить метод LockUser, присваивающий свойству IsLockedOut значение true. В следующем примере показано, как привести свойство Provider, предоставляющее приложению доступ к поставщику членства по умолчанию, к типу пользовательского поставщика, для вызова пользовательского метода LockUser.

MyCustomProvider p = (MyCustomProvider)Membership.Provider;
p.LockUser(username);

Для каждого поставщика членства, указанного в конфигурации для приложения, ASP.NET создает экземпляр поставщика членства, который используется для всех запросов, обслуживаемых объектом HttpApplication. Таким образом, несколько запросов могут выполняться одновременно. Сама среда ASP.NET не гарантируется потокобезопасность вызовов поставщика. Для обеспечения потокобезопасности необходимо писать код поставщика так, чтобы он был потокобезопасным. Например, подключаться к базе данных или открывать файл для редактирования следует в вызываемом члене, например, CreateUser, а не путем открытия файла или подключения к базе данных при вызове метода Initialize.

Показ: