Mensagem: ID4243: não foi possível criar um SecurityToken. Um token não foi encontrado no cache de token e nenhum cookie foi encontrado no contexto

Estamos recebendo exatamente o mesmo erro deste thread ... em nosso ambiente de produção. [Cache de Token de Segurança WIF

Alguém tem uma correção para esse erro? Mensagem: ID4243: não foi possível criar um SecurityToken. Um token não foi encontrado no cache de token e nenhum cookie foi encontrado no contexto.

Aqui estão algumas informações sobre nossa configuração:

• Estamos usando o Windows Identity Framework integrado com o .NET Framework 4.5.1

• O problema está quase sempre associado à mudança de RelyingParty # X para RelyingParty # Y (por exemplo, no momento em que o usuário clica no RP # Y ele é DESLIGADO sem pedir) - quando ele se conecta novamente após esse evento, ele ' é levado diretamente para a página que ele estava pedindo, dentro do RP # Y

• Estamos usando e.SessionToken.IsReferenceMode = true; // Cache no servidor, para obter um cookie menor

• Ao usar IsReferenceMode = true, nosso cookie FedAuth armazena um “ponteiro” para o Token real que é armazenado dentro do nosso banco de dados.

• Estamos usando nosso próprio DatabaseSecurityTokenCache, que está sobrescrevendo as funções em SessionSecurityTokenCache. Usando o DatabaseSecurityTokenCache ao lado do IsSessionMode = true, somos amigáveis ​​para farm de servidores (mas também garantimos que estaremos no mesmo servidor durante toda a nossa sessão de login), portanto, se o pool de aplicativos morrer por algum motivo, é capaz de obter o token do banco de dados através do DatabaseSecurityTokenCache. Eu verifiquei isso matando completamente o IIS no meio de uma sessão (com "net stop WAS" e reinicie-o novamente com "net start W3SVC" e ainda poderemos obter o token do DatabaseSecurityTokenCache). Eu também tentei fazer o mesmo simplesmente usando o SessionSecurityTokenCache pronto para uso e isso falhará de maneira respeitosa (como esperado)

• O tempo de vida do token padrão é de 20 minutos (mas o usuário pode alterá-lo para 40 ou 60 minutos, se quiser) - isso só será efetivo na próxima vez em que o usuário fizer login (e 90% de nosso usuário minutos de vida)

• Estamos usando um certificado (o mesmo em todos os servidores) para criptografar o cookie FedAuth, NÃO uma chave de máquina (o que seria catastrófico se fosse usado farm de servidores, com diferentes chaves de máquina)

• Assim, todos os servidores podem descriptografar os cookies, que foram criptografados de outro servidor.

• Temos um javascript com uma contagem regressiva em nosso RelyingParty4 e RelyingParty5 (duas partes confiantes diferentes) que é usado como um script de tempo limite no caso de o usuário deixar seu computador desacompanhado ... ele será desconectado quando o token estiver prestes a ser expire - (menos) 30 segundos (por exemplo, 20 minutos - 30 segundos = 19,5 minutos) com o tempo ocioso. Isso protege nossas informações bancárias muito sigilosas, então quando o usuário voltar para a sua máquina ele precisará fazer o login novamente. por exemplo. Também estamos usando sessões deslizantes ([http://www.cloudidentity.com/blog/2013/05/08/sliding-sessions-for-wif-4-5/]) e quando deslizarmos, o tempo no javascript do cliente também é atualizado, para corresponder ao comprimento do token menos 30 segundos. Esses 30 segundos são usados ​​para garantir que a sessão ainda esteja ativa ao sair, portanto, é um pouco menor do que a duração do token / sessão. Estamos atualmente a deslizar se esta condição for cumprida: tempo de vida total / 2 .... por ex. 20/2

• Estamos apenas deslizando se houver alguma atividade acontecendo com o usuário (ou seja, ele está se movimentando, fazendo algum trabalho). Estamos a deslizar no minuto10 + (se a duração do token for 20 minutos), como mostra o exemplo acima

• Depuramos o problema várias vezes e este é o erro WIF que estamos recebendo: Exceção: System.IdentityModel.Tokens.SecurityTokenException Mensagem: ID4243: não foi possível criar um SecurityToken. Um token não foi encontrado no cache de token e nenhum cookie foi encontrado no contexto. Fonte: Microsoft.IdentityModel em Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken (XmlReader reader, SecurityTokenResolver tokenResolver) em Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken (Byte [] token, SecurityTokenResolver tokenResolver) em Microsoft.IdentityModel.Web.SessionAuthenticationModule. ReadSessionTokenFromCookie (Byte [] sessionCookie) em Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie (SessionSecurityToken & sessionToken) em Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest (Object sender, EventArgs eventArgs) em System.Web.HttpApplication.SyncEventExecutionStep.System.Web .HttpApplication.IExecutionStep.Execute () em System.Web.HttpApplication.ExecuteStep (etapa IExecutionStep, Boolean & completedSynchronously)

• Conseguimos reproduzir o bug usando um cookie FedAuth antigo e este plug-in: (atenção! Não temos certeza se isso é a mesma coisa que está acontecendo no PROD, mas pelo menos dá o mesmo erro em nosso sistema de log) Isso é bom, mas eu acho que você deve adicionar as etapas sobre como podemos modificar o conteúdo do cookie FedAuth, para trazer este problema para a vida, localmente.- Você pode usar isto: É ' É simples pegar o valor do cookie FedAuth de algumas sessões anteriores (na mesma máquina! não de outra máquina, isso não funcionará) e colá-lo no valor do cookie FedAuth e atualizar a página.-

Plugin usado para modificar o cookie, no Chrome é chamado "Editar este cookie": - Se mudarmos o conteúdo deste cookie para um valor de uma sessão anterior, e apertar a atualização (CTRL + R no Chrome), obtemos o infame TokenSecurityException O ID4243 e o RP chamam um FederatedSignout de imidação porque não podemos recuperar dessa situação.

Saindo ...

Também devo mencionar que tomamos o artigo do MSDN da Microsoft como "Importante" no IsReferenceMode e o adicionamos também ao nosso

Evento SessionAuthenticationModule_SessionSecurityTokenCreated:

e.SessionToken.IsReferenceMode = true;

tomado do MSDN:

Importante! Para operar no modo de referência, a Microsoft recomenda o fornecimento de um manipulador para o evento WSFederationAuthenticationModule.SessionSecurityTokenCreated no arquivo global.asax.cs e a configuração da propriedade SessionSecurityToken.IsReferenceMode no token passado na propriedade SessionSecurityTokenCreatedEventArgs.SessionToken. Isso garantirá que o token de sessão opere no modo de referência para cada solicitação e seja favorecido apenas pela configuração da propriedade SessionAuthenticationModule.IsReferenceMode no Session Authentication Module.

Abaixo está todo o nosso SessionAuthenticationModule_SessionSecurityTokenReceived, por favor, examine os comentários que eu coloquei nele ... ele explica o que tudo faz:

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!
            }
    }

questionAnswers(2)

yourAnswerToTheQuestion