3

我正在尝试实现本文的“向 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?

4

2 回答 2

4

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

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

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

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

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

反正...

如果身份验证系统已无 cookie,则将自定义数据直接存储在身份验证票证中确实没有太大优势……在无 cookie 模式下,诸如“持久性 cookie”之类的东西没有意义,因此您将至少重新生成数据一次无论如何,每个会话。

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

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

于 2008-11-05T08:47:12.280 回答
1

谢谢你的精彩解释,斯蒂芬。如果用户不允许使用 cookie,我将不得不避开 UserData 并从数据库中加载数据。

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

if( !HttpContext.Current.Request.Browser.Cookies || !FormsAuthentication.CookiesSupported )
{
    FormsAuthentication.RedirectFromLoginPage( userName, false);
    return;
}
于 2008-11-05T14:41:30.443 回答