2009-08-31 6 views
5

В приложении ASP.net я использую элемент управления Login с пользовательским поставщиком членства, который я написал. То, что я хочу сделать, - установить Thread.CurrentPrincipal в мой пользовательский объект Principal сразу после аутентификации пользователя.Как установить Thread.CurrentPrincipal для использования во всем приложении?

Я использую setter: Thread.CurrentPrincipal, и он устанавливает для меня объект Principal, но на всех последующих потоках этот CurrentPrincipal переопределяется по умолчанию.

Вот мой код для события Authenticate контроля Логин:

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e) 
    { 
     string username = Login1.UserName; 
     string password = Login1.Password; 

     if (Membership.ValidateUser(username, password)) 
     { 
      var login = sender as Login; 
      var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true); 
      var principal = new PhoenixPrincipal(phoenixIdentity); 

      Thread.CurrentPrincipal = principal; 
      AppDomain.CurrentDomain.SetThreadPrincipal(principal); 

      HttpContext.Current.User = principal; 

      e.Authenticated = true; 
     } 
    } 

Например, представьте себе, что я войти в систему с именем пользователя А, все идет хорошо ... проверка проходит, но я жёстко пользователя с именем пользователя B в объекте Identity, который установлен на объект Principal, который я установил как объект CurrentPrincipal.

Когда я проверяю, какой пользователь установлен в CurrentPrincipal Идентичность в конце этого метода, он говорит, что это пользователь B. Но когда я загружаю другую страницу, а затем проверяю, что такое идентификатор , он говорит, что это пользователь А.

Итак, как я могу сделать свой объект CurrentPrincipal постоянным для всех остальных потоков, и где/когда этот элемент управления Login устанавливает объект CurrentPrincipal Thread?

+0

Что вы делаете? Вы хотите, чтобы все были идентифицированы как первый зарегистрированный пользователь? Вам необходимо понять механизмы аутентификации и авторизации веб-приложений, использование файлов cookie и т. Д. Вы не можете установить одного принципала во все многопользовательские потоки приложений. –

+0

Конечно нет. Может быть, я недостаточно выражался. – Goran

ответ

1

Вы можете обработать FormsAuthentication_OnAuthenticate (отправитель объекта, FormsAuthenticationEventArgs e) (в Global.asax) и установить CurrentPrincipal здесь.


void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs e) 
{ 
var phoenixIdentity = new PhoenixIdentity("B", "Forms" , true); 
var principal = new PhoenixPrincipal(phoenixIdentity); 
e.User = principal; 
} 
+0

Позвольте мне пояснить это подробнее ... Я использую аутентификацию Forms уже, если вы не заметили ... Просто я хочу сохранить идентификатор пользователя (вместе с некоторой другой информацией пользователя) в объекте Identity Thread .CurrentPrincipal, поэтому я реализовал свои собственные объекты Principal и Identity и переопределил метод Authenticate элемента управления Login для аутентификации Forms. – Goran

+0

Я попробую это прямо сейчас ... – Goran

2

Tadas не является ошибочным, FormsAuthentication правильно реализована, не вызовет этой проблемы.

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

Это, как работает FormsAuthentication,

  1. Проверяется Auth Cookie установлен или нет, а затем направляет пользователя на страницу входа
  2. страницу Входа должны проверить и установить куки аутентификации, как FormsAuthentication.SetAuthCookie
  3. Перед каждым доступом к странице выполняется Шаг 1.
  4. После успешной проверки Auth Cookie ASP.NET внутренне устанавливает текущий пользователь и все параметры differnet в соответствии с вашим компонентом членства.
  5. Файл ASP.NET Global.asax может предоставить вам некоторые события, в которых вы можете подключить свой код для проверки сразу после успешной аутентификации, вы можете изменить своего текущего пользователя, не забудьте установить текущий принцип на странице входа, не поможет

У нас была аналогичная проблема, когда мы использовали сеанс для хранения определенной важной информации после того, как сеансы аутентификации не были перестроены, поэтому мы написали HTTP-модуль, и в его методе init мы подключили событие AfterRequestAcquired, и в этом случае вы можете написать свой код для создания всех важных переменных, связанных с пользователем.

1

Это то, что я сделал в методе FormsAuthentication_OnAuthenticate:

if (FormsAuthentication.CookiesSupported) 
     { 
      if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) 
      { 
       try 
       { 
        FormsAuthenticationTicket ticket = 
         FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value); 

        var myIdentity = new GenericIdentity("B"); 
        var principal = new GenericPrincipal(myIdentity, new string[]{"rola1"}); 
        e.User = principal; 
       } 
       catch (Exception ex) 
       { 
        // Decrypt method failed. 
       } 
      } 
     } 
     else 
     { 
      throw new HttpException("Cookieless Forms Authentication is not " + 
            "supported for this application."); 
     } 

, кажется, что он работает, что он должен делать ... Это просто, что если я ставлю свою кодовую пару принципал/тождественности в качестве e.User, то У меня проблема сериализации, которую мне нужно исправить следующим ... Спасибо, ребята ...

+0

Проблема сериализации просто исчезла, когда я переключился на IIS вместо использования сервера разработки Visual Studio. – Goran

 Смежные вопросы

  • Нет связанных вопросов^_^