Кэширование маркера безопасности WIF

У меня есть сайт, который является полагающейся стороной нашего пользовательского STS на основе WIF. Недавно мы реализовали кеш маркера безопасности, как описано здесь: Azure/web-farm ready SecurityTokenCache. Основное различие между нашей реализацией и тем, что описано в этой ссылке, заключается в том, что мы используем Azure AppFabric Caching в качестве хранилища резервных копий для долговременного кеша, а не для хранения таблиц. Это помогло нам избавить нас от проблемы усечения токенов в некоторых браузерах, но ввела новую проблему (мы видим проблему усечения в первую очередь на страницах, которые содержат cookie Google Analytics + antiforgery cookie в дополнение к cookie fedauth). Мы получаем следующее исключение несколько тысяч раз в день:

System.IdentityModel.Tokens.SecurityTokenException
ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.

System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a       SecurityToken. A token was not found in the token cache and no cookie was found in the context.
   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
   at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Это исключение, похоже, происходит в цикле переадресации, поэтому мы увидим сотни из них в течение 1-2 минут.

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

Мы не смогли воспроизвести проблему внутренне и знаем только, что она существует из-за того, что тысячи записей заполняют наши таблицы Elmah. Любая помощь или понимание будут очень оценены.

Мы оттолкнули то, что, как мы думали, могут помочь решить проблему (код ниже), но это не повлияло:

HttpContext.Current.Response.Cookies.Remove("FedAuth");
WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule;
string signoutUrl = (WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(authModule.Issuer, authModule.Realm, null));
Response.Redirect(signoutUrl);

Ответ 1

У меня одностраничное приложение MVC как полагающаяся сторона, использующая WSO2 4.5 в качестве IDP, и получала ту же ошибку - "System.IdentityModel.Tokens.SecurityTokenException ID4243: Не удалось создать SecurityToken. Токен не был найден в кеше маркера, и в контексте не было найдено ни одного файла cookie.... "Прошел поиск и нашел заявления ниже Брок Аллена о репутации Thinktecture.

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

Полная статья: http://brockallen.com/2012/10/22/dealing-with-session-token-exceptions-with-wif-in-asp-net/

В той же статье он предлагает следующий фрагмент кода, который решил проблему в моем случае. В Global.asax:

void Application_OnError()
{
    var ex = Context.Error;
    if (ex is SecurityTokenException)
    {
        Context.ClearError();
        if (FederatedAuthentication.SessionAuthenticationModule != null)
        {
            FederatedAuthentication.SessionAuthenticationModule.SignOut();
        }
        Response.Redirect("~/");
    }
}

Ответ 2

Эта проблема вызвана кэшированием SessionSecurityToken. Назначение кэша находится в локальном домене пула приложений, поэтому, когда .NET нуждается в памяти, он автоматически будет уничтожен. Лучшее решение - это два варианта отмены кэширования для обеспечения безопасности или реализация собственной подсистемы для кэширования.

решение 1

AppFabric для Windows Server memcached - система кеширования распределенной памяти

решение 2

var sessionSecurityToken = new SessionSecurityToken(principal, TimeSpan.FromHours(Convert.ToInt32(System.Web.Configuration.WebConfigurationManager.AppSettings["SessionSecurityTokenLifeTime"])))
{
    IsPersistent = false, // Make persistent
    IsReferenceMode = true // Cache on server
};
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);

Ответ 3

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

Наше приложение является "нормальным" веб-приложением, перенаправляющим на AD FS с использованием WIF без каких-либо специальных кеш-кеш-кеш-ключей, насколько я знаю. Однако мы используем "режим сеанса" для WIF файлов (см., Например, "Ваши файлы cookie FedAuth на диете: IsSessionMode = true" ), которые делает WIF файлы намного меньше.

Ответ 4

В настоящее время мы сталкиваемся с одной и той же проблемой, хотя наша ситуация немного отличается. Мы пытаемся использовать WIF для предоставления SSO Shibboleth для Outlook Web App (OWA). У нас есть несколько хостов OWA за балансировщиком нагрузки.

WIF генерирует файл cookie FedAuth (и FedAuth1) размером более 2,5 кБ. Наш балансировщик нагрузки усекает куки. Поэтому мы устанавливаем свойство IsSessionMode-true в файл OWA global.asax. Теперь размер печенья уменьшается до ок. 600 байт, что хорошо. OWA работает.

Однако панель управления Exchange (ECP), которая работает на том же сервере, больше не работает. ECP работает в том же пуле приложений IIS и также имеет свойство IsSessiobnMode-Property в файле global.asax. Всякий раз, когда вызывается ECP, приложение не отправляет ответ, но отчеты WIF:

Current user: 'User not set'
   Request for URL 'http://owa.ourdomain.com/ecp/' failed with the following error:
   System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.

Ответ 5

Это должно быть сделано, если количество претензий в токене или общий размер токена слишком велико, чтобы передавать их в куки. Если это не так, упростите свое решение и просто используйте настройку по умолчанию, в которой используются файлы cookie. Однако вы shuold используете шифрование cookie на основе сертификатов, поэтому оно по-прежнему "подходит для фермы". По умолчанию WIF будет enrcrypt с использованием DPAPI, который имеет сродство к машине.