无法在 cookieless 模式下设置 FormsAuthenicationTicket.UserData
我正在尝试实现 this 的“将信息写入 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?
I'm trying to implement the "Writing Information to UserData" section of this article, but it doesn't work properly when the cookie is part of the URI.
My code:
// 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 );
When cookieless is used, the page redirects but doesn't get the correct URI with the cookie information in it, so it loops back to my Login page where Request.IsAuthenticated returns false. An endless loop ensues.
How do I redirect to the proper URI?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发现这是一个有趣的问题,因此我开始对 .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 并手动编写代码来处理它们并不便宜)。
I found this to be an interesting problem, so I set about doing some digging, testing, and a little bit of debugging into the .net framework source.
Basically, what you are trying to do will not work. Anything you put into the Response.Cookies collection will just be ignored if the browser doesn't support cookies. You can check Request.Browser.Cookies to see if cookies are supported.
In asp.net, both session state and authentication support a cookieless mode, but this does not extend to other cookies. In fact, it seems that session and authentication can be set to different modes of operation themselves even.
The authentication system can store it's own data in the URI, but it does so by directly manipulating the URI itself. Sadly, Microsoft doesn't appear to have exposed these capabilities to code outside the authentication module.
Basically, if you use the methods like FormsAuthentication.GetAuthCookie() and FormsAuthentication.SetAuthCookie() then the authentication system will take care of putting that information into the URI for you automagically... but it doesn't allow you to supply a customized authentication ticket to these methods... so you are stuck with the default auth ticket.In these cases, you are on your own for storing any custom data.
Anyway...
There really isn't much advantage to storing custom data directly in an authentication ticket if the authentication system has gone cookieless... in cookieless mode, things like "persistant cookie" have no meaning so you'll be regenerating the data at least once per session anyway.
The most common suggestion for cases where you are cookieless but still need custom data like this is to enable cookieless sessions, and just store your custom data as a session variable. The session ID will get put into the URI, but the custom data will stay in memory on the server. The usage pattern is identical no matter if your sessions are cookieless or not.
If you really wanted to, you could come up with a system of storing the custom data in the URI manually. The easiest thing to do would be to put the custom data into query strings or use pathdata. I can't see any real advantage to this over sessions variables unless you are just deperate not to use server memory (adding a little memory to a server is cheap, ugly URLs and manually writing code to deal with them is not cheap).
谢谢你的精彩解释,斯蒂芬。 如果用户不允许 cookie,我将不得不避免 UserData 并从数据库加载数据。
在上面列出的代码之前我会这样做:
Thank you for the great explanation, Stephen. In cases where the user does not allow cookies, I'm just going to have to avoid the UserData and load the data from the database.
Before the code listed above I'll do: