Мы получаем ту же ошибку, что и в этом потоке ... в нашей производственной среде. [Кэширование токена безопасности WIF
У кого-нибудь есть исправление этой ошибки? Сообщение: ID4243: не удалось создать SecurityToken. Токен не был найден в кэше токенов, и в контексте не было найдено ни одного файла cookie.
Вот некоторая информация о нашей установке:
• Мы используем встроенную платформу Windows Identity Framework с .NET Framework 4.5.1.
• Проблема почти всегда связана с переходом с RelyingParty#X на RelyingParty#Y (например, в тот момент, когда пользователь щелкает RP#Y, он ВЫХОДИТ, не запрашивая этого) — когда он снова входит в систему после этого события, он s попадает прямо на страницу, которую он просил, внутри 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, а НЕ машинный ключ (что было бы катастрофой при использовании серверной фермы с разными машинными ключами).
• чтобы все серверы могли расшифровывать куки, которые были зашифрованы с другого сервера.
• У нас есть javascript с обратным отсчетом в RelyingParty4 и RelyingParty5 (две разные проверяющие стороны), который используется в качестве «скрипта тайм-аута» на случай, если пользователь оставит свой компьютер без присмотра... он выйдет из системы, когда токен будет готов. expire – (минус) 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.IdentityModel в Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) в Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) в Microsoft.IdentityModel.Web.SessionAuthentication. ReadSessionTokenFromCookie(Byte[] sessionCookie) в Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) в Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(отправитель объекта, EventArgs eventArgs) в System.Web.Stepvent.SyncApecution .HttpApplication.IExecutionStep.Execute() в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое значение и завершено синхронно)
• Мы смогли воспроизвести ошибку, используя старый файл cookie FedAuth и этот плагин: ( внимание! Мы не уверены, что это то же самое, что происходит в PROD, но, по крайней мере, это дает то же самое. ошибка в нашей системе ведения журналов) Это хорошо, но я думаю, вам следует добавить шаги о том, как мы можем изменить содержимое файла cookie FedAuth, чтобы локально решить эту проблему. это просто: взять значение файла cookie FedAuth из некоторых предыдущих сеансов (на том же компьютере! не с другого компьютера, это не сработает) и вставить его в значение файла cookie FedAuth и обновить страницу.
Плагин, используемый для изменения файла cookie, в Chrome называется «Редактировать этот файл cookie». 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!
}
}