你的位置:首页 > ASP.net教程

[ASP.net教程]owin 中间件 katana 如何解密cookie


.NET MVC5 默认的用户登录组件是AspNet.Identity ,支持owin,并且微软自己实现的一套owin 中间件叫 katana

补充一下 katana项目源码地址:https://katanaproject.codeplex.com/

如何用owin做用户登录 授权等这里就不详细说了,大家可以自行搜索。

登录就有用户状态,用户状态一般就是保存在cookie 里,cookie里肯定是保存的加密串了。

那么这个katana是如何解密跟加密呢?

翻了大半天源码,终于找到核心的2个类 CookieAuthenticationMiddleware,CookieAuthenticationHandler

引用一下这篇比较全的文章,

http://www.cnblogs.com/jesse2013/p/aspnet-identity-claims-based-authentication-and-owin.html?utm_source=tuicool&utm_medium=referral

作者最后说下回分解CookieAuthenticationMiddleware这个东西,一直没等到下回,只能自己动手丰衣足食了。

CookieAuthenticationHandler 里面有2个方法

1,AuthenticateCoreAsync

2,ApplyResponseGrantAsync

前者是解密,后者是加密

我们直接看解密的

 protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()    {      AuthenticationTicket ticket = null;      try      {        string cookie = Options.CookieManager.GetRequestCookie(Context, Options.CookieName);        if (string.IsNullOrWhiteSpace(cookie))        {          return null;        }        ticket = Options.TicketDataFormat.Unprotect(cookie);    //这里省略 …………}  

 Unprotect(cookie); 这个方法就是解密的核心方法了

查找引用 找到SecureDataFormat<TData> 这个类

 

 public TData Unprotect(string protectedText)    {      try      {        if (protectedText == null)        {          return default(TData);        }        byte[] protectedData = _encoder.Decode(protectedText);        if (protectedData == null)        {          return default(TData);        }        byte[] userData = _protector.Unprotect(protectedData);        if (userData == null)        {          return default(TData);        }        TData model = _serializer.Deserialize(userData);        return model;      }      catch      {        // TODO trace exception, but do not leak other information        return default(TData);      }    }

这里我们可以看到,解密步骤分成了三个步骤

Decode(解码)
Unprotect(解除保护)
Deserialize(反序列化)

分别查看源码后发现
解码用的是 Base64 解保护用的windowsapi 里的CryptoAPI ,序列化用的是二进制序列化。

到这里我就停了,需要的知识已经搞清楚了。

那么我在项目里怎么解密呢?

我没有直接用CookieAuthenticationMiddleware这个类,这个依赖较多,也可能是我没全看懂,反正没直接用。
既然知道三个步骤是什么了,干脆我也是3个步骤了。
Decode(解码)用Base64UrlTextEncoder
Deserialize用TicketSerializer
这两个类都是public 的,并且直接new 就能用的。katana源码里也是用这两个类。
麻烦的地方在
Unprotect

需要在Startup里面通过IAppBuilder 来创建 IDataProtector
不要问startup是什么,会用owin的都知道。
  public partial class Startup  {    public static IDataProtector dataProtector=null;    private ILog loger = LogManager.GetLogger(typeof (Startup));    public const string LoginCookieName = "xxx";      public void ConfigureAuth(IAppBuilder app)    {            var op = new CookieAuthenticationOptions      {        AuthenticationType = LoginCookieName,        LoginPath = new PathString("/Login")          //,ExpireTimeSpan = TimeSpan.FromHours(1)        ,        ExpireTimeSpan = TimeSpan.FromDays(30)        ,        SlidingExpiration = true      };           app.UseCookieAuthentication(op);      app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);          dataProtector = app.CreateDataProtector(           typeof(CookieAuthenticationMiddleware).FullName,           op.AuthenticationType, "v1");    }  }

用了一个静态变量来装

dataProtector 

(直觉用静态变量不太好,有其他方案请不吝赐教啊)

那么真正实现解密cookie的地方就在某个Controller里
  public async Task<ActionResult> DeCodeUser(string cookie)    {           byte[] protectedData = new Base64UrlTextEncoder().Decode(cookie);      byte[] data = Startup.dataProtector.Unprotect(protectedData);      var tick = new TicketSerializer().Deserialize(data);      string userid = tick.Identity.GetUserId();      AppUser currentUser = await UserManager.FindByIdAsync(userid);      return Json(currentUser);    }

只要传入这个需要解密的cookie就能获取用户信息出来了。

当然这个主要是用来探讨怎么解密 cookie而已,真正你要获取用户信息,直接调用 controller 里User就可以了。

有人会担心,如果知道了解密方式,那岂不是只要cookie信息被截获 别人就能解出里面的信息?

当然不行,我写的这个例子是因为加密 跟解密的方法都在同一台机器上运行,所以所创建的

IDataProtector 其实包含着相同的密钥,相同的appname ,所以才能够加密解密对称。如果分开2台不同的机器就
应该不行了
(这个不太确定,如果知道了appname等信息不知道能不能模仿,但是还有winapi CryptoAPI 这个东西,底层实现我没细看,有心的读者可以去研究一下,记得把成果分享给我哟)。


 



法国游费用法国旅游团购法国蜜月旅游暑假去法国旅游价格法国旅游6天广州到连平新河漂流怎么走?广州到新河漂流自驾游路线? 河源火车站到野趣沟怎么坐车?河源火车站到野趣沟漂流有车吗? 野趣沟暗洞漂流好玩吗?河源野趣沟暗洞漂流多长时间? 黄腾峡全程勇猛漂流多少钱?清远黄腾峡全程勇猛漂流网上预订? 厦门鼓浪屿住宿有什么推荐的呢? 曾厝安周边住宿有哪些比较值的? 盘点国内的世外桃源 让人心旷神怡(图) 夏日避暑胜地 夏日避暑旅游国内十五大城市 文昌到椰子大观园有直达车吗?文昌到椰子大观园旅游线路? 文昌椰子大观园自驾游攻略?海口到椰子大观园多少公里? 红旗镇荷塘印象荷花开了吗?海口红旗镇荷塘印象荷花什么时候开? 海口红旗镇荷花印象好玩吗?红旗镇荷花印象门票价格? 回忆越南 滴滤式咖啡和柠檬朗姆的味道 菲律宾-长滩岛游记 马尼拉:享受美景 逐浪海豚湾 难忘的菲律宾之行 ISL43L840IRZ-T Datasheet ISL43L840IRZ-T Datasheet ISL6258AHRTZ-T Datasheet ISL6258AHRTZ-T Datasheet ISL43L841IRZ-T Datasheet ISL43L841IRZ-T Datasheet 长沙港澳游报价 长沙港澳游报价 长沙港澳游报价 佳木斯去香港游报价 佳木斯去香港游报价 佳木斯去香港游报价 佳木斯到香港澳门旅游报价 佳木斯到香港澳门旅游报价 佳木斯到香港澳门旅游报价