C# MVC4-在表单身份验证票证中设置自定义用户数据会导致表单身份验证cookie未设置吗?

C# MVC4-在表单身份验证票证中设置自定义用户数据会导致表单身份验证cookie未设置吗?,c#,asp.net-mvc,asp.net-mvc-4,forms-authentication,C#,Asp.net Mvc,Asp.net Mvc 4,Forms Authentication,我的传统MVC4应用程序使用表单身份验证。当我尝试创建以下自定义表单sauthenticationticket时,cookie将在响应中返回,但浏览器从未设置。请注意,我试图在cookie中存储OpenID Connect id_令牌,这依赖于FormsAuthenticationTicket类提供的加密 //Yes you can decode it - it's just test data string idToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjA1

我的传统MVC4应用程序使用表单身份验证。当我尝试创建以下自定义表单sauthenticationticket时,cookie将在响应中返回,但浏览器从未设置。请注意,我试图在cookie中存储OpenID Connect id_令牌,这依赖于
FormsAuthenticationTicket
类提供的加密

//Yes you can decode it - it's just test data
string idToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjA1M2JjYTgzNzZmZjhlNTM5MWVkYzMxYWJkMjU5YzBjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDc1ODExMjcsImV4cCI6MTUwNzU4MTQyNywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiaW1wbGljaXQiLCJub25jZSI6IjE1MDc1ODExMjA5MDMwMDQ0MDUzNDkzNjk3ODUzMTYiLCJpYXQiOjE1MDc1ODExMjcsImF0X2hhc2giOiJVWm5SeU1pXzVyUEN6NWduYmt5c09BIiwic2lkIjoiOTExYjI1OGQ5OGNiYzRlYzVkYTFiNmFkYzhiMmRjNTUiLCJzdWIiOiIxIiwiYXV0aF90aW1lIjoxNTA3NTgxMTI3LCJpZHAiOiJsb2NhbCIsIm5hbWUiOiJ4Iiwid2Vic2l0ZSI6Imh0dHBzOi8vYWxpY2UuY29tIiwicm9sZSI6ImFkbWluIiwibW9kZWxBY2Nlc3MiOlsiMTIzNCIsIjU2NzgiXSwiY29ubmVjdGlvblN0cmluZyI6InNvbWVNb2RlbENvbm5lY3Rpb25TdHJpbmciLCJhbXIiOlsicHdkIl19.SwTIU1dP1FifCcXVNHkbIGshQiGIjfaa7UAWOrtqKb-FqMMrkvJx_Wa3W19r6NeNwc8mo2go6AFwwu_WM0TF1VJBO1pfmvX35oKgjdTTSqrSmMo5R9_rcywm5YKwVYzmvDqRjPfhZksXkIOuTIk3JOemLrKqw6VIHPyFYV6ZYSK6ZxTpxx50Yz90MmEOBDsTc0GZpQbeZmzyDkBe-iD9uVnlPN2UHz_UuMF__yfmzjGROKLpvem36TKSMa1mEJE7DVxJkexmbxQe3CVwZeIU3iPKloabSReaLCJLqINeI0ikGa4x6PbgfjiP1TPVhIP6i8zUp47lSavGgyy0XVFGtQ";

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                            1,
                            model.UserName,
                            DateTime.Now,
                            DateTime.Now.AddDays(30),
                            true,
                            idToken,
                            FormsAuthentication.FormsCookiePath);
                        // Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
this.Response.Cookies.Add(new HttpCookie("TEST", encTicket));
起初我认为这可能是因为长度。但是我读到cookie的最大长度是4096字节。
idToken
只有983字节

有趣的是,如果我将数据变小(将
idToken
更改为684字节),那么一切都会正常工作。以下是一个工作示例:

//Shortened the idToken (for the sake of the example)
string idToken = "eyJhbGciOiJSUzI1NiIsImtpZCI6IjA1M2JjYTgzNzZmZjhlNTM5MWVkYzMxYWJkMjU5YzBjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MDc1ODExMjcsImV4cCI6MTUwNzU4MTQyNywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiaW1wbGljaXQiLCJub25jZSI6IjE1MDc1ODExMjA5MDMwMDQ0MDUzNDkzNjk3ODUzMTYiLCJpYXQiOjE1MDc1ODExMjcsImF0X2hhc2giOiJVWm5SeU1pXzVyUEN6NWduYmt5c09BIiwic2lkIjoiOTExYjI1OGQ5OGNiYzRlYzVkYTFiNmFkYzhiMmRjNTUiLCJzdWIiOiIxIiwiYXV0aF90aW1lIjoxNTA3NTgxMTI3LCJpZHAiOiJsb2NhbCIsIm5hbWUiOiJ4Iiwid2Vic2l0ZSI6Imh0dHBzOi8vYWxpY2UuY29tIiwicm9sZSI6ImFkbWluIiwibW9kZWxBY2Nlc3MiOlsiMTIzNCIsIjU2NzgiXSwiY29ubmVjdGlvblN0cmluZyI6InNvbWVNb2RlbENvbm5lY3Rpb25TdHJpbmciLCJhbXIiOlsicHdkIl19.SwTIU1dP1FifCcXVNHkbIGshQiGIjfaa7UAWOrtqKb-";

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                            1,
                            model.UserName,
                            DateTime.Now,
                            DateTime.Now.AddDays(30),
                            true,
                            idToken,
                            FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
this.Response.Cookies.Add(new HttpCookie("TEST", encTicket));
我正在按如下方式解密数据:

HttpCookie cookie = HttpContext.Current.Request.Cookies["TEST"];
if (cookie != null)
{
    Debug.WriteLine("Found Cookie Application_PostAuthenticateRequest");

    // Get the forms authentication ticket.
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(cookie.Value);
    if (authTicket == null)
    {
          Debug.WriteLine("auth ticket was null");
    }
    else
    {
          Debug.WriteLine("printing auth ticket");
          Debug.WriteLine(authTicket.UserData);
    }
}
else
{
     Debug.WriteLine("No Cookie Application_PostAuthenticateRequest");
}

为什么第一个示例在cookie完全低于最大限制的情况下仍不起作用?

问题在于加密后数据太大。您必须限制放入
表单身份验证票证中的数据量。如果您在限制范围内,那么一切都将按预期工作。

问题在于加密后数据太大。您必须限制放入
表单身份验证票证中的数据量。如果您在限制范围内,那么一切都将按预期工作。

我在深入查看ASP.NET auth Cookie时遇到了这个问题。根本原因是ASP.NET将其转换为cookie所使用的编码导致最终的over-The-wire cookie中983b的数据占用3936b

原因有两个

1) ASP.NET cookie将数据字符串作为UTF-16LE字符串序列化到cookie负载中

这将导致983b被写入7位编码长度(
0x5707
),然后是1966b(983个UTF-16LE字符),编码前总大小为1968b,存储空间增加了2:1

2) 加密后的整个cookie被写入十六进制字符串,这意味着在最终的cookie中,这些1968b中的每一个都表示为两个字符0..9A..F(例如:
A1B2C3..
),导致cookie中的总大小为3936b,存储空间增加了4:1

当然,cookie中还有剩余的内容,如过期日期、用户名等,这意味着983b的数据会很快超出4kb cookie的限制

这似乎可以解释dotnet对userdata的评论

您应该限制存储在UserData属性中的数据量。您必须确保UserData属性的大小不会导致无效的cookie或过长的URL

因为看起来每1个字节的userdata会产生4个字节的cookie


我希望这篇文章在48小时前就已经存在。我在深入研究ASP.NET auth Cookie时发现了这篇文章。根本原因是ASP.NET将其转换为cookie所使用的编码导致最终的over-The-wire cookie中983b的数据占用3936b

原因有两个

1) ASP.NET cookie将数据字符串作为UTF-16LE字符串序列化到cookie负载中

这将导致983b被写入7位编码长度(
0x5707
),然后是1966b(983个UTF-16LE字符),编码前总大小为1968b,存储空间增加了2:1

2) 加密后的整个cookie被写入十六进制字符串,这意味着在最终的cookie中,这些1968b中的每一个都表示为两个字符0..9A..F(例如:
A1B2C3..
),导致cookie中的总大小为3936b,存储空间增加了4:1

当然,cookie中还有剩余的内容,如过期日期、用户名等,这意味着983b的数据会很快超出4kb cookie的限制

这似乎可以解释dotnet对userdata的评论

您应该限制存储在UserData属性中的数据量。您必须确保UserData属性的大小不会导致无效的cookie或过长的URL

因为看起来每1个字节的userdata会产生4个字节的cookie

因为我希望这篇文章在48小时前就已经存在,所以我一直在分享