Проблемы с хранением пользовательского принципала в сеансе для ASP.NET MVC - PullRequest
1 голос
/ 04 марта 2010

Я столкнулся с проблемой ASP.NET MVC, из-за которой пользователь вынужден снова входить в систему примерно через 20 минут бездействия.

Я использую проверку подлинности с помощью форм и увеличил время ожидания в файле конфигурации как:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" timeout="9999999" />
</authentication>

Я также устанавливаю время ожидания сеанса в файле конфигурации как:

<sessionState timeout="120"></sessionState>

Я основываюсь на примере Rockford Lhotka CSLA ASP.NET MVC, и в моем global.asax есть следующее:

    protected void Application_AcquireRequestState(object sender, EventArgs e)
    {
        if (HttpContext.Current.Handler is IRequiresSessionState)
        {
            if (Csla.ApplicationContext.AuthenticationType == "Windows")
                return;
            System.Security.Principal.IPrincipal principal;
            try
            {
                principal = (System.Security.Principal.IPrincipal)
                    HttpContext.Current.Session[MyMembershipProvider.SESSION_KEY];
            }
            catch
            {
                principal = null;
            }
            if (principal == null)
            {
                if (this.User.Identity.IsAuthenticated && this.User.Identity is FormsIdentity)
                {
                    // no principal in session, but ASP.NET token
                    // still valid - so sign out ASP.NET
                    FormsAuthentication.SignOut();
                    this.Response.Redirect(this.Request.Url.PathAndQuery);
                }
                // didn't get a principal from Session, so
                // set it to an unauthenticted PTPrincipal
                BusinessPrincipal.Logout();
            }
            else
            {
                // use the principal from Session
                Csla.ApplicationContext.User = principal;
            }
        }
    }

Из того, что я могу сказать, это должно происходить ТОЛЬКО по истечении времени ожидания после 120 минут бездействия ... но по какой-то причине оно всегда кажется перерывом после 20 минут бездействия. У меня есть идея, почему это происходит, есть идеи?

Я играю с идеей простого сброса проверки подлинности с помощью форм и выполнения ее самостоятельно через сеанс, но боюсь, что я потеряю функциональность, такую ​​как атрибуты [Authorize] и так далее. Стараясь не идти по этому пути.

Можно ли сохранить мой пользовательский основной объект в виде файла cookie? Я просто не хочу аутентифицировать / авторизовывать пользователя для каждой отдельной страницы или действия.

Я теряю волосы ... быстро! =) * * 1 018

Ответы [ 4 ]

4 голосов
/ 05 марта 2010

Смешивать проблемы FormsAuthentication с SessionState - это просто плохая идея на многих уровнях, поскольку вы замечаете по полученным ответам.

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

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

Многие проблемы решены, и код мучо устранен.

Здесь - это вспомогательный класс, который может помочь вам с вашим билетом.

ПРЕДУПРЕЖДЕНИЕ: на практике максимальный размер файла cookie http просто стесняется официального4k предел и шифрование сокращает это примерно вдвое.

Если вы можете быть уверены, что ваш билет, включая основные данные, уместится в <2k, вы должны быть готовы.Может помочь создание настраиваемой сериализации для вашего принципала, например, пары имя = значение отлично работают, если ваши данные будут взаимодействовать. </p>

Удачи.

2 голосов
/ 06 сентября 2010

Надеюсь, вы уже решили эту проблему, но в случае, если кто-то другой столкнется с такими же проблемами, я отвечал за отладку некоторого кода, написанного с использованием того же шаблона, и вот несколько соображений:

1) Билет формы имеет тайм-аут в своем значении. Большая часть примера кода там жестко кодирует этот тайм-аут вместо извлечения из конфигурации проверки подлинности форм, поэтому, если вы просто просматриваете свой web.config, все может выглядеть хорошо, но ваш специальный код безопасности игнорирует значение web.config. Просмотрите свой код для «нового FormsAuthenticationTicket» и посмотрите, что вы делаете в течение срока действия.

2) В cookie-файле формы установлен таймаут. Некоторые из примеров кода там жесткие коды этого тайм-аута. Посмотрите, не установлено ли у вас cookie. Истекает срок действия файла cookie безопасности. (Пользовательская аутентификация имеет тенденцию собирать вручную больше кода, чем вы ожидаете, потому что методы FormsAuthentication не предоставляют метод make-a-cookie-with-userdata, и вы обычно хотите использовать userdata для хранения некоторой информации, например ролей в)

3) Некоторые клиенты не будут устанавливать cookie при перенаправлении ответа. И иногда, даже если они это сделают, вы получите печенье, отличное от того, которое вы установили. Например, если вы в какой-то момент изменили путь к приложению или домен, у пользователя может быть два действительных файла cookie, и вы удаляете только один из них, когда пытаетесь снова войти в него здесь. Теперь этот код в основном гласит: «У пользователя есть некоторая информация о сеансе, и он вошел в систему, но в его сеансе не было участника, которого я ожидал, поэтому я перенаправляю его для повторного входа». Что ж, если они не слушают ваш файл cookie для проверки подлинности или имеют файл cookie для проверки подлинности, которого вы не ожидаете (возможно, вы изменили значения своего домена или пути в какой-то момент, и у них все еще установлен файл cookie / oldpath), это может привести к бесконечному циклу , Я рекомендую обнулить серверную часть сеанса, как только вы обнаружите, что в ней нет нужных вам данных: Session.Clear () - это снижает вероятность того, что вы окажетесь в такой ситуации после перенаправления. (С точки зрения восстановления на стороне сервера без доверия клиенту к поведению на самом деле немного безопаснее пойти дальше и реконструировать основной объект и поместить его в сеанс, но я вижу, как это будет меньше ненадежно.)

Также безопаснее просто выполнить Server.Transfer на страницу входа в систему, а не полагаться на перенаправление изменения cookie для правильной работы. Если вы попадете в цикл перенаправления, server.transfer гарантированно завершит его.

2 голосов
/ 04 марта 2010

Обработка через сеанс может быть недостаточной. Поскольку это может быть IIS, перерабатывающий ваше приложение, поэтому все сеансы будут отменены.

См

0 голосов
/ 04 марта 2010

Вы также используете провайдера для авторизации?Если это так, вы можете посмотреть на атрибут userIsOnlineTimeWindow .По умолчанию это также составляет 20 минут.

...