英文原文:http://tech.trailmax.info/2014/08/aspnet-identity-and-owin-who-is-who/

最近我发现Stackoverflow上有一个非常好的问题.提问者问:为什么在调用AuthenticationManager.SignIn后,claim仍然可以被添加到Identity并持久化到cookie里.

示例代码如下所示:

ClaimsIdentity identity = UserManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie ); var claim1 = new Claim(ClaimTypes.Country, "Arctica");
identity.AddClaim(claim1);AuthenticationManager.SignIn(new AuthenticationProperties  { IsPersistent = true }, identity ); var claim2 = new Claim(ClaimTypes.Country, "Antartica");
identity.AddClaim(claim2);

是的,为什么claim2在cookie已经设置完成后还可用.

在深入研究后,我发现AspNet Identity框架不设置cookie,而OWIN会设置,OWIN是Katana开源项目的一部分.有源码可用是一件好事--你可以发现为什么事情有或没有按你预期的方式工作.

在这个案例里,我花了一些时间探索Katana项目和 AuthenticationManager 工作方式.结果证明SignIn方法不设置cookie.它把Identity对象保存在内存里,直到设置响应cookies的时刻到来,然后claims被转化为一个cookie,所有的事情就这样魔法般地工作着 -)

结果证明Identity框架只处理user持久化,密码哈希,验证密码是否正确,发送密码重置邮件,等等.但是Identity实际上不验证users或创建cookies.而Cookies是被OWIN处理的.

看一下登录的代码:

public async Task SignInAsync(Microsoft.Owin.Security.IAuthenticationManager       authenticationManager, ApplicationUser applicationUser, bool isPersistent)
{authenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);ClaimsIdentity identity = await UserManager.CreateIdentityAsync(applicationUser,       DefaultAuthenticationTypes.ApplicationCookie);authenticationManager.SignIn(new Microsoft.Owin.Security.AuthenticationProperties()        {        IsPersistent = isPersistent        }, identity);
}

Identity只创建ClaimsIdentity(学习网站 ReferenceSource ),而ClaimsIdentity是.Net framework的一部分,而不是来自于互联网的nuget包.然后这个ClaimsIdentity被传给拥有一个设置cookies回调的OWIN的AuthenticationManager,而AuthenticationManager拥有一个在写响应头时设置cookies的回调.

到目前为止都很好,已有三部分:Identity框架创建一个ClaimsIdentity,OWIN根据这个ClaimsIdentity创建一个cookie,和.Net framework掌控ClaimsIdentity的类.

当在你的类中要访问ClaimsPrincipal.Current时,你只用到.Net framework,不需要用到其它类库,这是非常方便的!

默认的Claims

Identity框架为你做了一件很漂亮的事,默认情况下当你登录时,它为一个principal添加了一些claims,如下所示:

  • User.Id:类型为“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier” 或ClaimTypes.NameIdentifier.

  • Username:类型为“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name” 或ClaimTypes.Name.

  • "ASP.NET Identity":保存为“http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider“.这在你使用OpenId做验证时非常有用.不过如果只是使用数据库存储users时没什么用.点击查看更多信息.

  • 包含user的安全邮戳的Guid,在Claim中持久化类型为“AspNet.Identity.SecurityStamp“.安全邮戳是user状态的一个主要快照,如果验证的密码/方法,email,等等发生变化,安全邮戳就会发生变化,这允许你通过改变证书实现"在任何地方登出".从Kung的回答中获取更多有关安全邮戳的信息.

  • 最有用的claims是role.所有分配给user的role被保存成ClaimTypes.Role或“http://schemas.microsoft.com/ws/2008/06/identity/claims/role“.所以下次你需要检查当前user的roles,检查这个claims,不会到数据库中查找,这样非常快.实际上,如果你调用ClaimsPrincipal的.IsInRole("RoleName"),框架会进入claims并检查用户是否分配了这个指定值的Role.

你可以在.Net Reference 网站查看这些claim类型,这个列表不是完整的,你可以创建你自己的claim类型--就是一个string.

如果你想添加你自己的owin claim类型,我建议你使用自己的符号,例如:“MyAppplication:GroupId” ,并保持所有的claim类型作为常量在一个类中:

public class MyApplicationClaimTypes
{         public string const GroupId = "MyAppplication:GroupId";    public string const PersonId = "MyAppplication:PersonId";     // other claim types

} 

这种方式,你总是可以找到claims,并不会与框架中的claim类型冲突,除非你的claims与框架中的claims类型完全一致,例如:ClaimTypes.Email.

添加默认的claims

我总是在user登录里,添加user的email到claims列表中,就如最前面示例里的claim1和claim2:

public async Task SignInAsync(IAuthenticationManager authenticationManager, ApplicationUser applicationUser, bool isPersistent)
{authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie,DefaultAuthenticationTypes.ApplicationCookie);    var identity = await this.CreateIdentityAsync(applicationUser,   DefaultAuthenticationTypes.ApplicationCookie);      // using default claim type from the frameworkidentity.AddClaim(new Claim(ClaimTypes.Email, applicationUser.Email));authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

你可以在这里为所有user添加默认的claims,但有一个IClaimsIdentityFactory类(赋给UserManager),只有一个方法:

public interface IClaimsIdentityFactory<TUser, TKey> where TUser :             class, IUser<TKey> where TKey : IEquatable<TKey>
{         /// <summary>/// Create a ClaimsIdentity from an user using a UserManager      /// </summary>Task<ClaimsIdentity> CreateAsync(UserManager<TUser, TKey> manager, TUser user, string authenticationType);
}

AspNet Identity的默认实现是:创建ClaimsIdentity,添加如上所述的默认claims,为user在数据库中存储IdentityUserClaims类型的claims.你可以重写这个实现,并插入你自己的逻辑/claims:

public class MyClaimsIdentityFactory : ClaimsIdentityFactory<ApplicationUser, string>
{     public override async Task<ClaimsIdentity> CreateAsync(UserManager<ApplicationUser, string>    userManager, ApplicationUser user, string authenticationType){           var claimsIdentity = await base.CreateAsync(userManager, user, authenticationType);claimsIdentity.AddClaim(new Claim("MyApplication:GroupId", "42"));           return claimsIdentity;}
}

然后在赋给UserManger:

public UserManager(MyDbContext dbContext): base(new UserStore<ApplicationUser>(dbContext))
{    // other configurations    

// Alternatively you can have DI container to provide this class for better  application flexebilitythis.ClaimsIdentityFactory = new MyClaimsIdentityFactory();}
原文地址:http://www.cnblogs.com/kid1412/p/6403518.html

.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

AspNet Identity 和 Owin 谁是谁相关推荐

  1. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  2. 在现有项目中使用AspNet Identity 2.0 实战

    感谢@LAgess 的解答:http://q.cnblogs.com/q/68698/ 办法一: 1.用 NuGet 安装 Identity. 2.添加链接字符串: <add name=&quo ...

  3. Asp.Net Core Authentication Middleware And Generate Token

    或者应该包含什么信息呢? 1.这个人是谁? 2.这个人可以用此token访问什么样的内容?(scope) 3.token的过期时间 (expire) 4.谁发行的token. 5.其他任何你希望加入的 ...

  4. MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

    在Membership系列的最后一篇引入了ASP.NET Identity,看到大家对它还是挺感兴趣的,于是来一篇详解登录原理的文章.本文会涉及到Claims-based(基于声明)的认证,我们会详细 ...

  5. MVC5 - ASP.NET Identity登录原理-Claims-based认证和OWIN

    目录 ASP.NET Identity登录原理 什么是Claims-based(基于声明)的认证 ASP.NET 下的 Claims-based认证实现 到底什么是OWIN 问题引入: 为什么要解耦服 ...

  6. [ASP.NET]ASP.NET中的Inherits、CodeFile、CodeBehind的区别详解及OWIN及IDENTITY

    篇一 : ASP.NET中的Inherits.CodeFile.CodeBehind的区别详解 Inherits.CodeFile.CodeBehind 在 ASP.NET 中使用代码隐藏方法来设计W ...

  7. [转]Membership 到 .NET4.5 之 ASP.NET Identity

    本文转自:http://www.cnblogs.com/jesse2013/p/membership-part3.html 我们前面已经讨论过了如何在一个网站中集成最基本的Membership功能,然 ...

  8. 【译】Asp.Net Identity Cookies 格式化

    原文出处 Trailmax Tech Max Vasilyev: ASP.Net MVC development in Aberdeen, Scotland 中英对照版 我的读者联系到我,并向我提出了 ...

  9. ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

最新文章

  1. WMI技术介绍和应用——Instance/Method Provider
  2. 计算机什么时候学汇编,[计算机基础] 汇编学习(1)
  3. android 打包hbuilder 高德地图加载不出来_十一黄金周地图很忙:百度获央视报道,高德忙道歉,究竟谁好用?...
  4. timeSetEvent
  5. ORACLE查询删除重复记录
  6. Keepalived双机热备
  7. VTK修炼之道2_VTK体系结构1
  8. linux界面添加地址,Linux系统下图形界面更改IP地址
  9. 语言 重量计算_R语言 第五章 高级绘图工具(4)
  10. linux系统管理实验报告总结_Linux系统:常用Linux系统管理命令总结
  11. 大型情感剧集Selenium:3_元素定位 #华为云·寻找黑马程序员#
  12. 《30天学习30种新技术》-Day 15:Meteor —— 从零开始创建一个 Web 应用
  13. [deepstream][原创]更改deepstream_test1_app在弹出视频上显示fps
  14. matlab幂函数回归分析,求助matlab种幂函数回归 这样的:
  15. (转)Openbravo ERP介绍(二)
  16. Inc. magazine年度公司Evernote: 小小记事本如何风靡全球
  17. python图片转文字easyocr_Python OpenCV读取png图像转成jpg图像存储
  18. asp.net word操作
  19. 工作以后如何做读书笔记
  20. houdini instance

热门文章

  1. 可能会紧急用到的Linux命令
  2. .NET Core 返回结果统一封装
  3. 06Prism WPF 入门实战 - Log控件库
  4. Envoy实现.NET架构的网关(五)集成Redis实现限流
  5. .NET Core HttpClient请求异常思考
  6. 写给自己,2020的年终总结
  7. IdentityServer4系列 | 简化模式
  8. 技术债! 怎样简洁高效的实现多个 Enum 自由转换
  9. Java国家/地区使用限制条款引发争议
  10. 初识ABP vNext(2):ABP启动模板