无法在无cookie模式下设置FormsAuthenicationTicket.UserData

时间:2008-11-04 17:37:28

标签: c# asp.net forms-authentication

我正在尝试实现this article的“将信息写入UserData”部分,但当cookie是URI的一部分时,它无法正常工作。

我的代码:

// 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 );

当使用cookieless时,页面重定向但没有获得带有cookie信息的正确URI,因此它会循环回到我的登录页面,其中Request.IsAuthenticated返回false。随之而来的是无休止的循环。

如何重定向到正确的URI?

2 个答案:

答案 0 :(得分:4)

我发现这是一个有趣的问题,因此我开始对.net框架源进行一些挖掘,测试和一些调试。

基本上,你要做的事情是行不通的。如果浏览器不支持cookie,您放入Response.Cookies集合中的任何内容都将被忽略。您可以检查Request.Browser.Cookies以查看是否支持cookie。

在asp.net中,会话状态和身份验证都支持无cookie模式,但这不会扩展到其他cookie。实际上,似乎会话和身份验证本身甚至可以设置为不同的操作模式。

身份验证系统可以将自己的数据存储在URI中,但它通过直接操作URI本身来实现。遗憾的是,Microsoft似乎没有将这些功能暴露给身份验证模块之外的代码。

基本上,如果您使用FormsAuthentication.GetAuthCookie()和FormsAuthentication.SetAuthCookie()等方法,那么身份验证系统将自动将该信息放入URI中...但它不允许您为这些方法提供自定义的身份验证票证......因此您将无法使用默认的身份验证票证。在这些情况下,您可以自行存储任何自定义数据。

总之...

如果身份验证系统已经无cookie,那么将自定义数据直接存储在身份验证票证中确实没有多大优势...在“无cookie”模式下,“持久性cookie”之类的内容没有任何意义,因此您将重新生成数据至少每次会话一次。

对于无Cookie但仍需要这样的自定义数据的情况,最常见的建议是启用无Cookie会话,并将自定义数据存储为会话变量。会话ID将被放入URI中,但自定义数据将保留在服务器的内存中。无论您的会话是否无cookie,使用模式都是相同的。

如果你真的想,你可以想出一个在URI中手动存储自定义数据的系统。最简单的方法是将自定义数据放入查询字符串或使用pathdata。除非你只是决定不使用服务器内存(向服务器添加一点内存是便宜的,丑陋的URL并手动编写代码来处理它们并不便宜),我看不到会话变量的任何真正优势。 / p>

答案 1 :(得分:1)

谢谢你的解释,斯蒂芬。在用户不允许使用cookie的情况下,我只需要避免使用UserData并从数据库加载数据。

在上面列出的代码之前,我会这样做:

if( !HttpContext.Current.Request.Browser.Cookies || !FormsAuthentication.CookiesSupported )
{
    FormsAuthentication.RedirectFromLoginPage( userName, false);
    return;
}