ASP.NET Cookie是怎么生成的(推荐)

来源:脚本之家  责任编辑:小易  

cookie都是限域名读取,不能跨域名读取,如果要读取指定网站cookie需要得到指定网站的协助才行!

可能有人知道Cookie的生成由machineKey有关,machineKey用于决定Cookie生成的算法和密钥,并如果使用多台服务器做负载均衡时,必须指定一致的machineKey用于解密,那么这个过程到底是怎样的呢?

理论上是找不到的。。 你打开连接后 没有创新新的cookie 那么你给URL的cookie就是NULL值 复制到游览器的话 应该是你cookie还在没有超时失效时用的吧

如果需要在.NET Core中使用ASP.NET Cookie,本文将提到的内容也将是一些必经之路。

foreach (string cookieName in Request.Cookies.AllKeys) { }获取本域名下的所有有效cookie

抽丝剥茧,一步一步分析

两个都可以用来存私密的东西,同样也都有有效期的说法。 区别在于。 session是放在服务器上的,过期与否取决于服务期的设定,cookie是存在客户端的,过去与否可以在cookie生成的时候设置进去。 1、cookie数据存放在客户的浏览器上, session数据

首先用户通过AccountController->Login进行登录:

protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack)//第一次加载 { string time = DateTime.Now.ToString(); lblTime.Text = time; HttpCookie cookie = new HttpCookie("time", time); Response.Cookies.Add(cooki

//// POST: /Account/Loginpublic async Task<ActionResult> Login(LoginViewModel model, string returnUrl){ if (!ModelState.IsValid) { return View(model); } var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); // ......省略其它代码 }}

茄子味道鲜美,是一种老少皆宜的食物,茄子的功效与作用十分的强大。茄子不能和什么一起吃墨鱼:茄子和墨鱼一起吃,容易引起霍乱;螃蟹:对肠胃会形成不小的刺激,容易导致肠道健康受损;河蟹:河蟹也不能和茄子一起吃,会引起食物中毒,中毒后可以用藕节治疗。和什么一起吃茄子和苦瓜一起吃好茄子和苦瓜可以一起吃,茄子具有清热活血,预防心血管疾病的功效,苦瓜具有清热解暑,明目解毒的作用,苦瓜和茄子的合理搭配是心血管病人的理想菜肴。茄子和西红柿一起吃好茄子和西红柿一起吃,茄子和西红柿中都含有丰富的维生素C,对于皮肤溃疡,皮肤干燥,高血压,动脉粥样硬化等病症具有防止作用。茄子和猪肉一起吃好茄子中富含维生素P,有预防微血

它调用了SignInManager的PasswordSignInAsync方法,该方法代码如下(有删减):

作为一个入手荣耀9一个多月的喜欢搞机的妹子,想跟题主推荐荣耀9几个不为人知的小功能,至于强不强悍,题主自己判断哈!第一,应用分身。这个功能在荣耀8就有了,不过还是很少人知道。点击设置——应用分身。先来简单看一下它的介绍是不是很厉害,然后开启之后,神奇的变化产生了2、除了应用分身之外,荣耀还有一个隐藏应用的功能,对于重视自己的隐私空间或者对安全性要求高的朋友们可以试试这个功能,二当家把所有的银行软件,支付类软件和比较私密的如日记本之类的软件都放在隐私空间里面,感觉十分的靠谱。首先打开设置,你会看到一个高级设置选项,点进去在用户模式下面有三个选项,用户,简易模式和学生模式,不得不说我们荣耀真的贴心

public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout){ // ...省略其它代码 if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture()) { if (!await IsTwoFactorEnabled(user)) { await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture(); } return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture(); } // ...省略其它代码 return SignInStatus.Failure;}

女排历来多美女,不管是在世界排坛还是在中国排坛,这也不难理解,对于身高要求极高的女排妹子们一水的大长胳膊大长腿,女排姑娘的起点就已经很高了。就个人而言,我认为中国女排的第一美女当属江苏队的张常宁,95后生人,身高1米95。张常宁长得属于娃娃脸,圆嘟嘟的脸上总是洋溢着萌宠活泼的笑(好吧,请原谅我是一个萝莉控)。今年3月,张常宁一改萝莉清纯的形象,以性感撩人的姿势登上了《男人装》的封面,令人血脉喷张刷屏网络。有句话怎么说来着?欲把西湖比西子,淡妆浓抹总相宜,张常宁算得上是,做得了萝莉当得好欲女。不过面对这样的女排第一美女,一般的男性朋友就不用有什么想法了,因为张常宁早已经放话出来:男友的身高不能低

想浏览原始代码,可参见官方的Github链接:

说起邓丽君,恐怕无人不知无人不晓,她是中国的风靡多年的甜歌皇后,她的诸多知名歌曲广为传唱至今,红遍中国甚至是东南亚。然而天妒红颜,在1995年42岁的邓丽君突然与世长辞,这个消息传出后,令无数人痛哭流涕。关于邓丽君的突然死亡引来不少人怀疑,一时间各种谣言四起。有人说邓丽君死于疾病,有人说邓丽君是被人谋杀的,甚至还出现了关于邓丽君是间谍被迫害的传闻。但是有一点可以肯定的是,邓丽君并非自杀。那造成邓丽君死亡的原因是什么呢?我们来深入分析下。其实我觉得邓丽君会去世和她坎坷的爱情之路密不可分:她本身就有严重的哮喘,但后期的事业不断走下滑路,导致她心情郁郁寡欢,久而久之病情愈加严重,最后她一个人是在泰国

https://github.com/aspnet/AspNetIdentity/blob/master/src/Microsoft.AspNet.Identity.Owin/SignInManager.cs#L235-L276

可见它先需要验证密码,密码验证正确后,它调用了SignInOrTwoFactor方法,该方法代码如下:

private async Task<SignInStatus> SignInOrTwoFactor(TUser user, bool isPersistent){ var id = Convert.ToString(user.Id); if (await IsTwoFactorEnabled(user) && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id).WithCurrentCulture()) { var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id)); AuthenticationManager.SignIn(identity); return SignInStatus.RequiresVerification; } await SignInAsync(user, isPersistent, false).WithCurrentCulture(); return SignInStatus.Success;}

该代码只是判断了是否需要做双重验证,在需要双重验证的情况下,它调用了AuthenticationManager的SignIn方法;否则调用SignInAsync方法。SignInAsync的源代码如下:

public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser){ var userIdentity = await CreateUserIdentityAsync(user).WithCurrentCulture(); // Clear any partial cookies from external or two factor partial sign ins AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie); if (rememberBrowser) { var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id)); AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity, rememberBrowserIdentity); } else { AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity); }}

可见,最终所有的代码都是调用了AuthenticationManager.SignIn方法,所以该方法是创建Cookie的关键。

AuthenticationManager的实现定义在Microsoft.Owin中,因此无法在ASP.NET Identity中找到其源代码,因此我们打开Microsoft.Owin的源代码继续跟踪(有删减):

public void SignIn(AuthenticationProperties properties, params ClaimsIdentity[] identities){ AuthenticationResponseRevoke priorRevoke = AuthenticationResponseRevoke; if (priorRevoke != null) { // ...省略不相关代码 AuthenticationResponseRevoke = new AuthenticationResponseRevoke(filteredSignOuts); } AuthenticationResponseGrant priorGrant = AuthenticationResponseGrant; if (priorGrant == null) { AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identities), properties); } else { // ...省略不相关代码 AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(mergedIdentities), priorGrant.Properties); }}

AuthenticationManager的Github链接如下:https://github.com/aspnet/AspNetKatana/blob/c33569969e79afd9fb4ec2d6bdff877e376821b2/src/Microsoft.Owin/Security/AuthenticationManager.cs

可见它用到了AuthenticationResponseGrant,继续跟踪可以看到它实际是一个属性:

public AuthenticationResponseGrant AuthenticationResponseGrant{ // 省略get set { if (value == null) { SignInEntry = null; } else { SignInEntry = Tuple.Create((IPrincipal)value.Principal, value.Properties.Dictionary); } }}

发现它其实是设置了SignInEntry,继续追踪:

public Tuple<IPrincipal, IDictionary<string, string>> SignInEntry{ get { return _context.Get<Tuple<IPrincipal, IDictionary<string, string>>>(OwinConstants.Security.SignIn); } set { _context.Set(OwinConstants.Security.SignIn, value); }}

其中,_context的类型为IOwinContext,OwinConstants.Security.SignIn的常量值为"security.SignIn"。

跟踪完毕……

啥?跟踪这么久,居然跟丢啦!?

当然没有!但接下来就需要一定的技巧了。

原来,ASP.NET是一种中间件(Middleware)模型,在这个例子中,它会先处理MVC中间件,该中间件处理流程到设置AuthenticationResponseGrant/SignInEntry为止。但接下来会继续执行CookieAuthentication中间件,该中间件的核心代码在aspnet/AspNetKatana仓库中可以看到,关键类是CookieAuthenticationHandler,核心代码如下:

protected override async Task ApplyResponseGrantAsync(){ AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType); // ... 省略部分代码 if (shouldSignin) { var signInContext = new CookieResponseSignInContext( Context, Options, Options.AuthenticationType, signin.Identity, signin.Properties, cookieOptions); // ... 省略部分代码 model = new AuthenticationTicket(signInContext.Identity, signInContext.Properties); // ... 省略部分代码 string cookieValue = Options.TicketDataFormat.Protect(model); Options.CookieManager.AppendResponseCookie( Context, Options.CookieName, cookieValue, signInContext.CookieOptions); } // ... 又省略部分代码}

这个原始函数有超过200行代码,这里我省略了较多,但保留了关键、核心部分,想查阅原始代码可以移步Github链接:https://github.com/aspnet/AspNetKatana/blob/0fc4611e8b04b73f4e6bd68263e3f90e1adfa447/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs#L130-L313

这里挑几点最重要的讲。

与MVC建立关系

建立关系的核心代码就是第一行,它从上文中提到的位置取回了AuthenticationResponseGrant,该Grant保存了Claims、AuthenticationTicket等Cookie重要组成部分:

AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);

继续查阅LookupSignIn源代码,可看到,它就是从上文中的AuthenticationManager中取回了AuthenticationResponseGrant(有删减):

public AuthenticationResponseGrant LookupSignIn(string authenticationType){ // ... AuthenticationResponseGrant grant = _context.Authentication.AuthenticationResponseGrant; // ... foreach (var claimsIdentity in grant.Principal.Identities) { if (string.Equals(authenticationType, claimsIdentity.AuthenticationType, StringComparison.Ordinal)) { return new AuthenticationResponseGrant(claimsIdentity, grant.Properties ?? new AuthenticationProperties()); } } return null;}

如此一来,柳暗花明又一村,所有的线索就立即又明朗了。

Cookie的生成

从AuthenticationTicket变成Cookie字节串,最关键的一步在这里:

string cookieValue = Options.TicketDataFormat.Protect(model);

在接下来的代码中,只提到使用CookieManager将该Cookie字节串添加到Http响应中,翻阅CookieManager可以看到如下代码:

public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options){ if (context == null) { throw new ArgumentNullException("context"); } if (options == null) { throw new ArgumentNullException("options"); } IHeaderDictionary responseHeaders = context.Response.Headers; // 省去“1万”行计算chunk和处理细节的流程 responseHeaders.AppendValues(Constants.Headers.SetCookie, chunks);}

有兴趣的朋友可以访问Github看原始版本的代码:https://github.com/aspnet/AspNetKatana/blob/0fc4611e8b04b73f4e6bd68263e3f90e1adfa447/src/Microsoft.Owin/Infrastructure/ChunkingCookieManager.cs#L125-L215

可见这个实现比较……简单,就是往Response.Headers中加了个头,重点只要看TicketDataFormat.Protect方法即可。

逐渐明朗

该方法源代码如下:

public string Protect(TData data){ byte[] userData = _serializer.Serialize(data); byte[] protectedData = _protector.Protect(userData); string protectedText = _encoder.Encode(protectedData); return protectedText;}

可见它依赖于_serializer、_protector、_encoder三个类,其中,_serializer的关键代码如下:

public virtual byte[] Serialize(AuthenticationTicket model){ using (var memory = new MemoryStream()) { using (var compression = new GZipStream(memory, CompressionLevel.Optimal)) { using (var writer = new BinaryWriter(compression)) { Write(writer, model); } } return memory.ToArray(); }}

其本质是进行了一次二进制序列化,并紧接着进行了gzip压缩,确保Cookie大小不要失去控制(因为.NET的二进制序列化结果较大,并且微软喜欢搞xml,更大😂)。

然后来看一下_encoder源代码:

public string Encode(byte[] data){ if (data == null) { throw new ArgumentNullException("data"); } return Convert.ToBase64String(data).TrimEnd('=').Replace('+', '-').Replace('/', '_');}

可见就是进行了一次简单的base64-url编码,注意该编码把=号删掉了,所以在base64-url解码时,需要补=号。

这两个都比较简单,稍复杂的是_protector,它的类型是IDataProtector。

IDataProtector

它在CookieAuthenticationMiddleware中进行了初始化,创建代码和参数如下:

IDataProtector dataProtector = app.CreateDataProtector( typeof(CookieAuthenticationMiddleware).FullName, Options.AuthenticationType, "v1");

注意它传了三个参数,第一个参数是CookieAuthenticationMiddleware的FullName,也就是"Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",第二个参数如果没定义,默认值是CookieAuthenticationDefaults.AuthenticationType,该值为定义为"Cookies"。

但是,在默认创建的ASP.NET MVC模板项目中,该值被重新定义为ASP.NET Identity的默认值,即"ApplicationCookie",需要注意。

然后来看看CreateDataProtector的源码:

public static IDataProtector CreateDataProtector(this IAppBuilder app, params string[] purposes){ if (app == null) { throw new ArgumentNullException("app"); } IDataProtectionProvider dataProtectionProvider = GetDataProtectionProvider(app); if (dataProtectionProvider == null) { dataProtectionProvider = FallbackDataProtectionProvider(app); } return dataProtectionProvider.Create(purposes);}public static IDataProtectionProvider GetDataProtectionProvider(this IAppBuilder app){ if (app == null) { throw new ArgumentNullException("app"); } object value; if (app.Properties.TryGetValue("security.DataProtectionProvider", out value)) { var del = value as DataProtectionProviderDelegate; if (del != null) { return new CallDataProtectionProvider(del); } } return null;}

可见它先从IAppBuilder的"security.DataProtectionProvider"属性中取一个IDataProtectionProvider,否则使用DpapiDataProtectionProvider。

我们翻阅代码,在OwinAppContext中可以看到,该值被指定为MachineKeyDataProtectionProvider:

builder.Properties[Constants.SecurityDataProtectionProvider] = new MachineKeyDataProtectionProvider().ToOwinFunction();

文中的Constants.SecurityDataProtectionProvider,刚好就被定义为"security.DataProtectionProvider"。

我们翻阅MachineKeyDataProtector的源代码,刚好看到它依赖于MachineKey:

internal class MachineKeyDataProtector{ private readonly string[] _purposes; public MachineKeyDataProtector(params string[] purposes) { _purposes = purposes; } public virtual byte[] Protect(byte[] userData) { return MachineKey.Protect(userData, _purposes); } public virtual byte[] Unprotect(byte[] protectedData) { return MachineKey.Unprotect(protectedData, _purposes); }}

最终到了我们的老朋友MachineKey。

逆推过程,破解Cookie

首先总结一下这个过程,对一个请求在Mvc中的流程来说,这些代码集中在ASP.NET Identity中,它会经过: AccountController SignInManager AuthenticationManager

设置AuthenticatinResponseGrant

然后进入CookieAuthentication的流程,这些代码集中在Owin中,它会经过:

CookieAuthenticationMiddleware(读取AuthenticationResponseGrant)

ISecureDataFormat(实现类:SecureDataFormat<T>)

IDataSerializer(实现类:TicketSerializer)

IDataProtector(实现类:MachineKeyDataProtector)

ITextEncoder(实现类:Base64UrlTextEncoder)

这些过程,结果上文中找到的所有参数的值,我总结出的“祖传破解代码”如下:

string cookie = "nZBqV1M-Az7yJezhb6dUzS_urj1urB0GDufSvDJSa0pv27CnDsLHRzMDdpU039j6ApL-VNfrJULfE85yU9RFzGV_aAGXHVkGckYqkCRJUKWV8SqPEjNJ5ciVzW--uxsCBNlG9jOhJI1FJIByRzYJvidjTYABWFQnSSd7XpQRjY4lb082nDZ5lwJVK3gaC_zt6H5Z1k0lUFZRb6afF52laMc___7BdZ0mZSA2kRxTk1QY8h2gQh07HqlR_p0uwTFNKi0vW9NxkplbB8zfKbfzDj7usep3zAeDEnwofyJERtboXgV9gIS21fLjc58O-4rR362IcCi2pYjaKHwZoO4LKWe1bS4r1tyzW0Ms-39Njtiyp7lRTN4HUHMUi9PxacRNgVzkfK3msTA6LkCJA3VwRm_UUeC448Lx5pkcCPCB3lGat_5ttGRjKD_lllI-YE4esXHB5eJilJDIZlEcHLv9jYhTl17H0Jl_H3FqXyPQJR-ylQfh";var bytes = TextEncodings.Base64Url.Decode(cookie);var decrypted = MachineKey.Unprotect(bytes, "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware", "ApplicationCookie", "v1");var serializer = new TicketSerializer();var ticket = serializer.Deserialize(decrypted);ticket.Dump(); // Dump为LINQPad专有函数,用于方便调试显示,此处可以用循环输出代替

运行前请设置好app.config/web.config中的machineKey节点,并安装NuGet包:Microsoft.Owin.Security,运行结果如下(完美破解):

总结

学习方式有很多种,其中看代码是我个人非常喜欢的一种方式,并非所有代码都会一马平川。像这个例子可能还需要有一定ASP.NET知识背景。

注意这个“祖传代码”是基于.NET Framework,由于其用到了MachineKey,因此无法在.NET Core中运行。我稍后将继续深入聊聊MachineKey这个类,看它底层代码是如何工作的,然后最终得以在.NET Core中直接破解ASP.NET Identity中的Cookie,敬请期待!

以上所述是小编给大家介绍的ASP.NET Cookie是怎么生成的,希望对大家有所帮助!

扩展阅读,根据您访问的内容系统为您准备了以下内容,希望对您有帮助。

asp.net 一般处理程序 怎么获取 cookie

HttpCookie cookie = HttpContext.Current.Request.Cookies["info"];

// cookie = null;

if (cookie == null )

{

cookie = new HttpCookie("Info");

cookie["CityID"] = HttpContext.Current.Server.UrlEncode(cityID);

cookie["CityName"] = HttpContext.Current.Server.UrlEncode(CityName);

cookie.Expires = DateTime.Now.AddDays(10);//

HttpContext.Current.Response.Cookies.Add(cookie);

}else{

//直接读值,注意编码 解码、不然汉字会出现乱码。

}

asp.net cookie问题

你要明白,一个Request都会伴随着一个Response

你在点击按钮以后,会产生一个Request,此时会带上你的Cookie 产生一个请求.

然后在事件中,写入了Cookie,然后你再输出的,还是在你写Cookie之前带来的Cookie

所以,你第四次点击,带过来第三次的Cookie,这个是没有问题的.按你这样的写法,是正常的.

你这个不需要解决,实际开发中,不应该有你现在这种情况.追答你说的这种情况,我大概看懂了.

如果你这个cookie名称写入的是一样的,应该会覆盖原来的,重新写入现在的Cookie,你说的这种情况,不应该会出现.

在浏览器中检查一下你写入的Cookie值是不是对的.或者检查一下你的代码,看看业务上是不是有分支,导致Cookie没有写入覆盖的情况.

如果还有不明白的,把你的代码邮件给我,我帮你看看. cpiblm 新浪.com追问谢谢,追问里放不下了,烦请刷下问题我写在补充里了。谢谢。

ASP.NET保存cookie位置在哪里??

这里是不同windows版本cookie存储的路径

windows2000、windowsXp:

Cookie:C:/Documents and Settings/[user name]/Cookies/

Vista、Win7:

在Vista、Win7中,权限管理较为严格,IE7/IE8 默认运行使用了保护模式机制,在保护机制下,IE 运行于低权限。如果 IE 运行在低权限下,则将目录设置为对应的Low目录,如下:

Cookie: C:/Users/[user name]/AppData/Roaming/Microsoft/Windows/Cookies/

C:/Users/[user name]/AppData/Roaming/Microsoft/Windows/Cookies/Low/

进入到目录以后按最新时间排序第一个文件就是你当前操作的cookie文件,这里的文件名是随机生成的。

  • 本文相关:
  • 详解在asp.net core 中使用cookie中间件
  • asp.net中安全退出时清空session或cookie的实例代码
  • asp.net中cookie的使用方法
  • asp.net利用cookie保存用户密码实现自动登录的方法
  • asp.net之response.cookies.remove 无法删除cookie的原因
  • asp.net笔记之页面跳转、调试、form表单、viewstate、cookie的使用说明
  • .net语言smobiler开发之如何在手机上实现表单设计
  • 未将对象引用设置到对象的实例 (system.nullreferenceexception)
  • asp.net基于web service实现远程上传图片的方法
  • ajaxcontroltoolkit中cascadingdropdown的用法说明
  • asp.net "对路径的访问被拒绝" 解决方法的分析
  • system.timers.timer定时执行程序示例代码
  • c#.net 微信公众账号接口开发
  • asp.net core mvc项目实现多语言实例(globalization/localizati
  • 关于asp.net button按钮的onclick和onclientclick事件
  • visual studio 2017企业版本安装(附序列号)
  • asp.net 一般处理程序 怎么获取 cookie
  • asp.net cookie问题
  • ASP.NET保存cookie位置在哪里??
  • ASP.NET(C#)使用Cookies时,获取cookies值的问题。
  • ASP.NET中,生成一个随机数并把它保存到Cookie里
  • asp.net中怎样判读指定的cookie是否存在
  • Asp.Net 读取cookie的问题
  • asp.net 怎么循环读取cookie
  • ASP.NET里session和cookie的区别是什么?
  • 如何在ASP.NET使用cookie对象保存上次登陆的时间?
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved