Não é possível definir FormsAuthenicationTicket.UserData em cookieless modo
-
06-07-2019 - |
Pergunta
Eu estou tentando implementar o "gravar Informações UserData" seção de este artigo, mas ele não funcionar corretamente quando o cookie é parte de uma URI.
O meu código:
// Create the cookie that contains the forms authentication ticket
HttpCookie authCookie = FormsAuthentication.GetAuthCookie( userName, createPersistantCookie );
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt( authCookie.Value );
// Create a new FormsAuthenticationTicket that includes our custom User Data
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket( ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, "foo");
// Update the authCookie's Value to use the encrypted version of newTicket
authCookie.Value = FormsAuthentication.Encrypt( newTicket );
// Manually add the authCookie to the Cookies collection
HttpContext.Current.Response.Cookies.Add( authCookie );
// Determine redirect URL and send user there
string redirUrl = FormsAuthentication.GetRedirectUrl( userName, createPersistantCookie );
HttpContext.Current.Response.Redirect( redirUrl, false );
Quando cookieless é usado, a página redireciona mas não consegue corrigir a URI com a informação de cookie, e assim ele volta para a minha página de Login onde Solicitação.IsAuthenticated retorna false.Um loop infinito se segue.
Como faço para redirecionar para o bom URI?
Solução
Eu encontrei este para ser um problema interessante, então comecei a fazer alguns trabalhos de escavação de teste, e um pouco de depuração para o .net framework de origem.
Basicamente, o que você está tentando fazer não vai funcionar.Qualquer coisa que você colocar na Resposta.Coleção de Cookies será apenas ignorado se o browser não suporta cookies.Você pode verificar o Pedido.Navegador.Cookies para ver se os cookies são suportados.
No asp.net tanto o estado da sessão e suporte de autenticação de um cookieless modo, mas isso não se estende a outros cookies.Na verdade, parece que a sessão e autenticação pode ser definida para diferentes modos de operação em si mesmo.
O sistema de autenticação pode armazenar dados na URI, mas o faz, manipulando diretamente o URI si.Infelizmente, a Microsoft não parece ter exposto estas capacidades para o código fora o módulo de autenticação.
Basicamente, se você usar os métodos como FormsAuthentication.GetAuthCookie() e FormsAuthentication.SetAuthCookie (), em seguida, o sistema de autenticação irá cuidar de colocar essa informação para o URI para você automaticamente...mas ele não permite que você para fornecer um personalizados tíquete de autenticação para esses métodos...então, você está preso com o padrão de autenticação de passagem.Nesses casos, você está no seus próprios para o armazenamento de quaisquer dados personalizados.
Enfim...
Realmente não há muita vantagem para o armazenamento de dados personalizados diretamente em um tíquete de autenticação se o sistema de autenticação foi cookieless...em cookieless modo, coisas como "cookie persistente" não têm qualquer significado, de modo que você vai ser a regenerar os dados pelo menos uma vez por sessão de qualquer maneira.
O mais comum sugestão para casos onde você cookieless, mas ainda precisa de dados personalizado como este é permitir cookieless sessões, e apenas armazenar seus dados personalizados como uma variável de sessão.O ID de sessão irá ficar colocada no URI, mas o costume de dados vai ficar na memória no servidor.O padrão de uso é idêntico, não importa se suas sessões são cookieless ou não.
Se você realmente quisesse, você poderia vir com um sistema de armazenamento de dados personalizados no URI manualmente.A coisa mais fácil a fazer seria colocar o costume de dados em seqüências de caracteres de consulta ou uso pathdata.Eu não consigo ver nenhuma vantagem real sobre as sessões de variáveis, a menos que você é apenas deperate não uso de memória do servidor (adicionando um pouco de memória para um servidor é baixo, feio URLs e escrever o código manualmente para lidar com eles não é barato).
Outras dicas
Obrigado pela grande explicação, Stephen. Nos casos em que o usuário não permite cookies, vou precisar evitar os dados do usuário e carregar os dados do banco de dados.
Antes do código listado acima, vou fazer:
if( !HttpContext.Current.Request.Browser.Cookies || !FormsAuthentication.CookiesSupported )
{
FormsAuthentication.RedirectFromLoginPage( userName, false);
return;
}