Как установить Thread.CurrentPrincipal для использования во всем приложении? - PullRequest
5 голосов
/ 31 августа 2009

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

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

Вот мой код для события Authenticate элемента управления Login:

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;
        }
    }

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

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

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

Ответы [ 3 ]

2 голосов
/ 31 августа 2009

Тадас не ошибается, корректная реализация FormsAuthentication не вызовет этой проблемы.

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

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

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

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

1 голос
/ 31 августа 2009

Это то, что я сделал в методе 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, то у меня возникнет проблема с сериализацией, которую мне нужно исправить дальше ... Спасибо, ребята. ..

1 голос
/ 31 августа 2009

Вы можете обработать 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...