В моих функциях администратора приложения asp.net я пытаюсь объединить аутентификацию AD и авторизацию формы для создания пользователей, ролей и назначения пользователей ролям и т.д. После входа пользователя в систему с использованием аутентификации AD мне нужно переключить / назначить мой объект членства на использование AspNetSqlMembershipProvider, чтобы получить всех пользователей из объекта членства (из таблицы dbo.aspnet_Users). Как переключить провайдера во время выполнения? Я пробовал разные подходы после поиска этой проблемы, и пока что ни один из них не работает для меня. Вот несколько подходов, которые я пробовал: 1. foreach (MembershipProvider mp в Membership.Providers) { if (mp.Name == "MembershipADProvider") { Membership.Providers.Remove (MembershipADProvider ");
Пользователи MembershipUserCollection = Членство.GetAllUsers (); ddlUsers.DataSource = пользователи; ddlUsers.DataBind ();
перерыв; } }

Membership.Providers.Remove (MembershipADProvider "); - не работает, поскольку не поддерживается .. Кроме того, попытался очистить Membership.Providers, а затем добавить только тип AspNetSqlMembershipProvider, который также не поддерживается.

  1. Я не могу установить для Membership.Provider значение из Membership.Providers ["AspNetSqlMembershipProvider"] as Membership.Provider является свойством только для чтения.

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

Пожалуйста, дайте мне знать, успешно ли кто-нибудь внедрил этот подход или вообще правдоподобен. Благодарю вас!

4
ASPnet_user 27 Авг 2011 в 01:05

2 ответа

Лучший ответ

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

Поэтому вместо того, чтобы говорить Membership.GetAllUsers();, вы бы сделали что-нибудь вроде (у меня нет компилятора под рукой):

public UserSerivce : IUserService
{
   private MembershipProvider provider;

   public UserService(MembershipProvider provider)
   {
       this.provider = provider;
   }

   public IEnumerable<MembershipUser> GetUsers()
   {
       return provider.GetAllUsers();
   }

   public void DoSomethingElseUseful()
   {
       ...
   }

}

А затем использовать его для конкретного провайдера:

var service = new UserService(Membership.Providers["mySqlMembershipProvider"]);
var users = service.GetUsers();

Или, если вы используете специальный код AD:

var service = new UserService(Membership.Providers["myADMembershipProvider"]);
var users = service.GetUsers();

Использование DI таким образом также помогает поддерживать тестируемость кода.

2
TheCodeKing 26 Авг 2011 в 23:58

Если вам нужен список пользователей в таблице aspnet_Users, просто подключитесь к своей базе данных с объектами System.Data.SqlClient и запросите таблицу. Нет причин (о которых вы упомянули) вам нужно использовать поставщика членства для получения этих данных.

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

Изменить: я нашел несколько потенциально полезных сообщений об использовании нескольких поставщиков членства. Похоже, что общая идея состоит в том, чтобы реализовать собственный код, обрабатывающий событие Login.Authenticate на вашем элементе управления Login, и использовать Membership.Providers["ProviderName"].ValidateUser для попытки аутентификации с каждым провайдером.

http://www.stevideter.com/2008/03/20/using-two-membership-providers-for-aspnet-logins/ http://forums.asp.net/p/1112089/1714276.aspx

0
pseudocoder 26 Авг 2011 в 21:27