Сообщение: ID4243: не удалось создать токен безопасности. Токен не найден в кеше токена, и в контексте не найдены файлы cookie

Мы получаем ту же ошибку, что и в этой теме ... в нашей производственной среде. [Кэширование токенов безопасности WIF

У кого-нибудь есть исправление этой ошибки? Сообщение: ID4243: не удалось создать токен безопасности. Токен не найден в кеше токена, и в контексте не найдены файлы cookie.

Вот некоторая информация о нашей установке:

• Мы используем встроенную Windows Identity Framework с .NET Framework 4.5.1

• Проблема почти всегда связана с переходом с RelyingParty # X на RelyingParty # Y (например, в тот момент, когда пользователь щелкает RP # Y, он ПОДПИСАЛСЯ, не прося об этом) - когда он снова входит в систему после этого события, он ' взяты прямо на страницу, о которой он просил, внутри RP # Y

• Мы используем e.SessionToken.IsReferenceMode = true; // Кэшируем на сервере, чтобы получить меньший куки

• Используя IsReferenceMode = true, наш файл cookie FedAuth хранит «указатель» на фактический токен, который хранится в нашей базе данных.

• Мы используем наш собственный DatabaseSecurityTokenCache, который переопределяет функции в SessionSecurityTokenCache. Используя DatabaseSecurityTokenCache вместе с IsSessionMode = true, мы дружественны к ферме серверов (но мы также гарантируем, что будем находиться на одном и том же сервере в течение всего сеанса входа в систему), поэтому, если пул приложений по какой-либо причине умрет, мы Вы можете получить токен из базы данных через DatabaseSecurityTokenCache. Я подтвердил это, полностью убив IIS в середине сеанса (с помощью «net stop WAS» и перезапустив его снова с «net start W3SVC», и мы все еще можем получить токен из DatabaseSecurityTokenCache). Я также попытался сделать то же самое, просто используя готовый SessionSecurityTokenCache, и это приведет к ошибке соответственно (как и ожидалось)

• Срок действия токена по умолчанию составляет 20 минут (но пользователь может изменить его на 40 или 60 минут, если он этого хочет) - это будет действовать только при следующем входе пользователя в систему (а 90% нашего пользователя просто используют значение по умолчанию 20). минут жизни)

• Мы используем сертификат (одинаковый на всех серверах) для шифрования файла cookie FedAuth, а НЕ машинный ключ (который был бы катастрофическим, если использовать серверную ферму с разными машинными ключами)

• чтобы все серверы могли расшифровывать файлы cookie, которые были зашифрованы с другого сервера.

• У нас есть javascript с обратным отсчетом в наших RelyingParty4 и RelyingParty5 (две разные проверяющие стороны), который используется в качестве «сценария тайм-аута» на случай, если пользователь оставит свой компьютер без присмотра ... он выйдет из системы, когда токен собирается истекает - (минус) 30 секунд (например, 20 минут - 30 секунд = 19,5 минут) с временем простоя. Это защищает нашу очень конфиденциальную банковскую информацию, поэтому, когда пользователь возвращается на свою машину, ему нужно будет снова войти в систему. например Мы также используем скользящие сессии ([http://www.cloudidentity.com/blog/2013/05/08/sliding-sessions-for-wif-4-5/]) и когда мы скользим, время в javascript клиента также обновляется, чтобы соответствовать длине токена минус 30 секунд. Эти 30 секунд используются, чтобы убедиться, что сеанс все еще жив при выходе из системы, поэтому он немного короче, чем время жизни токена / сеанса. Мы в настоящее время скользим, если выполняется это условие: общее время жизни / 2 .... например. 20/2

• Мы скользим только в том случае, если с пользователем происходит какое-либо действие (то есть он перемещается, выполняет какую-то работу). Мы скользим в минуте 10+ (если время жизни токена равно 20 минутам), как показано в примере выше

• Мы отладили проблему несколько раз, и это ошибка WIF, которую мы получаем: Исключение: System.IdentityModel.Tokens.SecurityTokenException Сообщение: ID4243: Не удалось создать SecurityToken. Токен не найден в кеше токена, и в контексте не найдены файлы cookie. Источник: Microsoft. ReadSessionTokenFromCookie (Byte [] sessionCookie) в Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie (SessionSecurityToken & sessionToken) в Microsoft.IdentityModel.Webest. .HttpApplication.IExecutionStep.Execute () в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, булево и завершено синхронно)

• Мы смогли воспроизвести ошибку, используя старый файл cookie FedAuth и этот плагин: (внимание! Мы не уверены, что это то же самое, что происходит в PROD, но, по крайней мере, оно дает то же самое ошибка в нашей системе ведения журналов) Это хорошо, но я думаю, что вы должны добавить шаги о том, как мы можем изменить содержимое файла cookie FedAuth, чтобы локально решить эту проблему. - Вы можете использовать это: это просто, взяв значение файла cookie FedAuth из некоторых предыдущих сеансов (на том же компьютере, а не с другого компьютера, который не будет работать), вставив его в значение файла cookie FedAuth и обновив страницу.

Плагин, используемый для изменения файла cookie, в Chrome называется «Редактировать этот файл cookie»: - Если мы изменим содержимое этого файла cookie на значение из предыдущего сеанса и нажмем на обновление (CTRL + R в Chrome), мы получим печально известную исключительную ситуацию TokenSecurityException ID4243 и RP требуют непосредственного FederatedSignout, потому что мы не можем выйти из этой ситуации.

Выписка....

Я должен также, вероятно, упомянуть, что мы серьезно относились к статье Microsoft MSDN, помеченной как «Важная» на IsReferenceMode, и добавили ее также в нашу

Событие SessionAuthenticationModule_SessionSecurityTokenCreated:

e.SessionToken.IsReferenceMode = true;

взято из MSDN:

Важный! Для работы в справочном режиме Microsoft рекомендует предоставить обработчик для события WSFederationAuthenticationModule.SessionSecurityTokenCreated в файле global.asax.cs и установить свойство SessionSecurityToken.IsReferenceMode для токена, переданного в свойстве SessionSecurityTokenCreatedEventArgs.SessionToken. Это будет гарантировать, что маркер сеанса работает в опорном режиме для каждого запроса и предпочитать просто установив свойство SessionAuthenticationModule.IsReferenceMode на модуле сеанса аутентификации.

Ниже приведен весь наш SessionAuthenticationModule_SessionSecurityTokenReceived. Пожалуйста, изучите комментарии, которые я в него вставил ... он объясняет, что все делает

void SessionAuthenticationModule_SessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        if (e.SessionToken.ClaimsPrincipal != null)
        {
            DateTime now = DateTime.UtcNow;
            DateTime validTo = e.SessionToken.ValidTo;
            DateTime validFrom = e.SessionToken.ValidFrom;
            TimeSpan lifespan = new TimeSpan(validTo.Ticks - validFrom.Ticks);

            double keyEffectiveLifespan = new TimeSpan(e.SessionToken.KeyExpirationTime.Ticks - e.SessionToken.KeyEffectiveTime.Ticks).TotalMinutes;
            double halfSpan = lifespan.TotalMinutes / 2;

            if (validFrom.AddMinutes(halfSpan) < now && now < validTo)
            {
                SessionAuthenticationModule sam = sender as SessionAuthenticationModule;

                // This will ensure a re-issue of the token, with an extended lifetime, ie "slide". Id deletes the current token from our databasetoken cache (with overriden Remove of the SessionSecurityTokenCache ) and writes a new one into the cache with the overriden AddOrUpdate of the SessionSecurityTokenCache. 
                // it will also write the token back into the cookie ( just the pointer to the cookie, because it's stored in database-cache ) because the IsReferenceMode = True is set
                e.ReissueCookie = true; // Will force the DatabaseSecurityTokenCache'ið to clean up the cache with this, handler.Configuration.Caches.SessionSecurityTokenCache.Remove(key); internally in WIF's SessioAuthenticationModule

                e.SessionToken = sam.CreateSessionSecurityToken(
                    e.SessionToken.ClaimsPrincipal,
                    e.SessionToken.Context,
                    now,
                    now.AddMinutes(lifespan.TotalMinutes),
                    false); // Make persistent, þannig að kakan lifir EKKI af browser-close / tab-lokun:
                {
                    e.SessionToken.IsReferenceMode = true; // Cache on server
                }

                // Not needed, because if ReissueCookie = true;  is set, it WILL to a WriteSessionTokenToCookie internally in WIF
                //FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(e.SessionToken); // <---- er þetta e.t.v. bara það sem við þurfum ? Nei, á ekki að þurfa, er gert þegar tóki er búinn til með CreateSessionSecurityToken
            }
            else if (validTo < now)
            {
                // Fix
                // http://blogs.planbsoftware.co.nz/?p=521                    

                var sessionAuthenticationModule = (SessionAuthenticationModule)sender;
                sessionAuthenticationModule.DeleteSessionTokenCookie(); // <--- is this really needed like the article says ? http://blogs.planbsoftware.co.nz/?p=521
                e.Cancel = true; // This will allow a silent-login if the STS cookie is still valid, e.g. switching between RP's where we're switching from an active RP to a RP which has it's cookie outdated, but the STS's session is still alive. We don't want to prompt the user for a new login, beucase the STS session is still OK!
            }
    }

Ответы на вопрос(2)

Ваш ответ на вопрос