Как отследить просроченные WIF-файлы cookie?

У меня есть интересная проблема с попыткой отследить истекшие сеансы аутентификации WIF / куки.

В качестве предыстории: сайт MVC 3, использует Windows Identity Foundation (WIF), который имеет доверие к серверу ADFS в качестве STS. Весь сайт защищен SSL. STS имеет срок действия токена 60 минут.

Когда пользователь выходит из системы вручную, мы просто вызываем метод SignOut в модуле FedAuth:

FederatedAuthentication.WSFederationAuthenticationModule.SignOut(false);

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

Я понимаю, что это выполняется с привилегированной позиции браузера, принявшего fiddler в качестве прокси-сервера... но клиент обеспокоен тем, что эти файлы cookie, срок действия которых на самом деле не истек, представляют значительную угрозу безопасности. Они не уверены, что SSL в достаточной степени защищает сайт, и что если злоумышленник может выполнить атаку MITM, он может использовать эти файлы cookie после того, как пользователь решит, что он вышел из системы.

Я объяснил, что если они уязвимы после выхода из системы, они уязвимы во время входа, но им все равно...

Поэтому я искал способы быть уверенным, что после того, как пользователь выйдет из системы, cookie-файлы fedauth, связанные с этим сеансом входа, будут считаться просроченными. В обработчиках WIF, похоже, нет встроенного механизма для отслеживания просроченных токенов, и я не нашел ничего другого, связанного с этим.

Я предполагаю, что это на самом деле более широкая проблема -> как вообще определить просроченные куки? Действительный файл cookie - это действительный файл cookie!

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

Кто-нибудь знает какие-либо стандартные решения в ASP.NET для этой проблемы?

Заранее спасибо.

2 ответа

Решение

Вы не можете без серверного списка недавно отозванных токенов. Вот почему обычно мы полагаемся на врожденное истечение срока действия, а также HTTPS для предотвращения утечки / кражи токена.

Мне была поручена аналогичная просьба нашей службы безопасности. Я решил сохранить идентификатор сеанса asp.net в файле cookie OWIN, и при каждом запросе, который содержал идентификатор сеанса в файле cookie, я проверяю, что он совпадает с идентификатором активного сеанса.

Сохраните идентификатор сеанса в файле cookie ( адаптированный из этого ответа) в конце первого запроса, который аутентифицирован и у которого еще нет идентификатора сеанса в файле cookie:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
    { 
        base.OnActionExecuted(filterContext);

        bool authenticated = User.Identity.IsAuthenticated;

        var sessionGuid = (User as ClaimsPrincipal).FindFirst("sessionID")?.Value;

        //put the SessionID into the cookie.
        if (authenticated && string.IsNullOrEmpty(sessionGuid))
        {
            var id= Session.SessionID;

            //update the guid claim to track with the session
            var authenticationManager = HttpContext.GetOwinContext().Authentication;

            // create a new identity from the old one
            var identity = new ClaimsIdentity(User.Identity);

            // update claim value
            identity.RemoveClaim(identity.FindFirst("sessionID"));
            identity.AddClaim(new Claim("sessionID", id));

            // tell the authentication manager to use this new identity
            authenticationManager.AuthenticationResponseGrant =
                new AuthenticationResponseGrant(
                    new ClaimsPrincipal(identity),
                    new AuthenticationProperties { IsPersistent = true }
                );
        }
    } 

Затем по каждому будущему запросу, если я найду сеанс в куки, сравните его с активным сеансом. Если они не совпадают, выйдите из системы:

protected override void OnActionExecuting( ActionExecutingContext filterContext)
    {
        var claim = (User as ClaimsPrincipal).FindFirst("sessionID")?.Value;

        //does the owin cookie have a sessionID?
        if (!string.IsNullOrEmpty(claim))
        {
            string session = Session.SessionID;

            //does it match the one stored in the session?
            if(session != claim)
            {
                //no? log the user out again..
                Session.Abandon();

                //redirect to logged out page
                this.Request.GetOwinContext().Authentication.SignOut();

                //tell them its over..
                Response.Write("Expired Session");

                Response.End();
            }
        }

        base.OnActionExecuting(filterContext);
    }
Другие вопросы по тегам