请选择 进入手机版 | 继续访问电脑版

程序人生

 找回密码
 注册

QQ登录

只需一步,快速开始

程序人生 门户 .NET开发 查看内容

MVC5 - Claims-based认证和OWIN(一)

2016-5-4 17:18| 发布者: sean| 查看: 1741| 评论: 0

摘要: 目录ASP.NET Identity 登录原理什么是Claims-based (基于声明) 的认证ASP.NET 下Claims-based 认证的实现到底什么是OWIN问题引入:为什么要解耦服务器与应用程序OWin如何做到解耦?微软对OWin的开源实现KatanaOWin A ...

目录

  • ASP.NET Identity 登录原理
    • 什么是Claims-based (基于声明) 的认证
    • ASP.NET 下Claims-based 认证的实现
  • 到底什么是OWIN
    • 问题引入:为什么要解耦服务器与应用程序
    • OWin如何做到解耦?
  • 微软对OWin的开源实现Katana 
  • OWin Authentication(认证)
    • Forms 认证
    • MVC 5 默认的start up配置类
    • 将Owin Middleware绑定到IIS 集成模式的管道
    • CookieAuthenticationMiddelware 负责读取用户信息cookie
    • CookieAuthenticationMiddelware 对cookie的加密方式

ASP.NET Identity登录原理

  废话少说,我们直接切入正题。在上一篇从Membership到ASP.NET Identity,我们已经给了一个简单的实例,并且大致的描述了一下ASP.NET Identity的结构体系,但是ASP.NET Identity主要提供的功能是帮助我们管理用户,角色等信息,它主要负责的是存储这一块,也就是我们的信息存到哪里去的问题。但是用户是如何实现登录的? 是Forms认证么?用到Cookie了么? Cookie里面有保存明文信息么(咳咳,最近某程旅游网好像很火?),接下来我们就来一一的回答这些问题。

  在上一篇的例子中,我们可以简单的发现,要实现登录实际上只有简单的三行代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private IAuthenticationManager AuthenticationManager
{
get return HttpContext.GetOwinContext().Authentication; }
}
 
private async Task SignInAsync()
{
// 1. 利用ASP.NET Identity获取用户对象
var user = await UserManager.FindAsync("UserName""Password");
// 2. 利用ASP.NET Identity获取identity 对象
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
// 3. 将上面拿到的identity对象登录
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

  我们发现UserManager.CreateIdentityAsync返回给我们的对象是一个ClaimsIdentity,这又是一个什么玩意?它和我们原来所熟知的Identity对象有什么关联么?毕竟长的那么像,在深入之前,我们先要了解一下下面的概念。

什么是Claims-based(基于声明)的认证

  首先这个玩意不是微软特有的,Claims-based认证和授权在国外被广泛使用,包括微软的ADFS,Google,Facebook等。 国内我就不知道了,没有使用过国内的第三方登录,有集成过QQ登录或者支付宝登录的同学可以解释一下。

  Claims-based认证主要解决的问题?

  对比我们传统的Windows认证和Forms认证,claims-based认证这种方式将认证和授权与登录代码分开,将认证和授权拆分成另外的web服务。活生生的例子就是我们的qq集成登录,未必qq集成登录采用的是claims-based认证这种模式,但是这种场景,千真万确就非常适合claims-based认证。

  Claims-based认证的主要特点:

  • 将认证与授权拆分成独立的服务
  • 服务调用者(一般是网站),不需要关注你如何去认证,你用Windows认证也好,用令牌手机短信也好,与我无关。
  • 如果用户成功登录的话,认证服务(假如是QQ) 会返回给我们一个令牌。
  • 令牌当中包含了服务调用者所需要的信息,用户名,以及角色信息等等。

  总的来说就是,我再也不用管你怎么登录,怎么样去拿你有哪些角色了,我只需要把你跳到那个登录站点上,然后它返回给我令牌信息,我从令牌上获取需要的信息来确定你是谁,你拥有什么角色就可以了。 

  进一步理解Claims-based 认证

  为了让大家进一步理解Claims-based认证,我们从一个普通的登录场景开始说起,拿QQ集成登录来举例。

  1. 用户跑到我们的网站来访问一个需要登录的页面
  2. 我们的网站检测到用户没有登录,返回一个跳转到QQ登录页的响应(302 指向QQ登录页面的地址并加上一个返回的链接页面,通常是returnUrl=)
  3. 用户被跳转到指定QQ的登录页面
  4. 用户在QQ登录页面上输入用户名和密码,QQ会到自己的数据库中查询,一旦登录成功,会返回一个跳转到我们站点的响应(302指向我们的网站页面)
  5. 用户被跳转到我们网站的一个检测登录的页面,我们可以拿到用户的身份信息,建立ClaimsPrinpical和ClaimsIdentity对象,生成cookie等。
  6. 我们再把用户带到指定的页面,也就是returnUrl,那是用户登录前最后一次访问的页面

  

  简单的来说,就是把登录的代码(验证用户,获取用户信息)拆分成独立的服务或组件。

ASP.NET 下的 Claims-based认证实现

  说完什么是Claims-based认证之后,我们接下来就可以看看ClaimsIdentity以及ClaimsPrincipal这两个类,他们是.NET下Claims-based认证的主要基石。当然正如我们所想,他们继承了接口IIdentity和IPrincipal。

  IIdentity封装用户信息

  这个接口很简单,它只包含了三个最基本的用户身份信息。

  

  IPrincipal 代表着一个安全上下文

  这个安全上下文对象包含了上面的identity以及一些角色和组的信息,每一个线程都会关联一个Principal的对象,但是这个对象是属性进程或者AppDomain级别的。ASP.NET自带的 RoleProvider就是基于这个对象来实现的。

  CalimsIdentity和ClaimsPrincipal

  在System.Security.Claims命名空间下去,我们可以发现这两个对象。下面我们来做一个小例子,这个小例子会告诉我们这两个对象是如何进行认证和授权的。我们要做的demo很简单,建一个空的mvc站点,然后加上一个HomeController,和两个Action。并且给这个HomeController打上Authroize的标签,但是注意我们没有任何登录的代码,只有这个什么也没有的Controller和两个什么也没有的Action。

  

  当然,结果也是可想而知的,我们得到了401页面,因为我们没有登录。

  

  下面我们就来实现登录,这里的登录非常简单,我们手动去创建这个ClaimsIdentity和ClaimsPrincipal对象,然后将Principal对象指给当前的HttpContext.Current.User。

  

  我们在Global.asax中添加了Application_AuthenticateRequest方法,也就是每次MVC要对用户进行认证的时候都会进到我们这个方法里面,然后我们就这样神奇的把用户给登录了。

  当然,我们没有Home/Manager的访问权限,因为我们上面只给了用户Users的Role。  

  现在大家知道ClaimsIdentity和ClaimsPrincipal是如何使用了么?这里要注意一下的是,我们没有设置IsAutheiticated为true,在.NET4.5以前,对于GenericIdentity只要设置它的Name的时候IsAutheiticated就自动设置为true了,而对于ClaimsIdentity是在它有了第一个Claim的时候。在.NET4.5以后,我们就可以灵活控制了,默认ClaimsIdentity的IsAutheiticated是false,只有当我们构造函数中指定Authentication Type,它才为true。

  最后结论,我们讲了ClaimsIdentity什么的,讲了这么多和今天的主题有嘛关系?我们上面说ASPNET Identity登录有三句话,第一句话可以略过,第二句话就是我们上面讲的。

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

  UserManager实际上只是为我们创建了一个ClaimsIdentity的对象,还是通过我们自己从数据库里面取出来的对象来创建的,它也就干了那么点事,一层小小的封装而已。不要被后面的DefaultAuthenticationTypes.ApplicationCookie吓到了,这里还没有和cookie扯上半点关系,这就是一个字符串常量,和我们上面自己定义的MyClaimsLogin是没有区别的。

  到这里,我想算是把登录代码的第二句话讲完了,讲清楚了,那么我们来看看第三句话,也就是最后一句,其实它才是登录的核心,第二句只是创建了一个ClaimsIdentity的对象。


private IAuthenticationManager AuthenticationManager

{

get { return HttpContext.GetOwinContext().Authentication; }

}

AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

 通过F12查看,发现IAuthenticationManager 在  Microsoft.Owin.Security命名空间下,而这个接口是定义在Microsoft.OWin.dll中的。这又是个什么玩意儿?带着这个疑问,我开始了我的OWin学习之旅。


鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

Web开发技术
Asp.net Mvc5的项目结构
Asp.net Mvc5的项目结构
用Visual studio创建了一个MVC5的项目,其项目结构如下分别对这个MVC的项目模板各个目
我真的不想成为Web前端程序员
我真的不想成为Web前端程序员
职位名称并不代表技能,从事web开发很多年,我现在真的不想成为一个纯粹的web前端程序
MVC5 - Claims-based认证和OWIN(二)
MVC5 - Claims-based认证和OWIN(二)
到底什么是OWIN  首先我们来简单介绍一下OWin,它是由微软ASP.NET小组成员组织成立
MVC5 - Claims-based认证和OWIN(一)
MVC5 - Claims-based认证和OWIN(一)
目录ASP.NET Identity 登录原理什么是Claims-based (基于声明) 的认证ASP.NET 下Claim
想成为一名Web前端开发人员,该学习哪些技术
想成为一名Web前端开发人员,该学习哪些技
Web前端开发者越来越受到追捧,以致于很多后端开发人员都转而去做前端工程师,甚至参
webapi生成帮助文档,减少文档工作量
webapi生成帮助文档,减少文档工作量
微软的webapi真的很强大,试用webapi时真是太好了,而且Microsoft.AspNet.WebApi.Help

关于程序人生网|小黑屋|手机版|Archiver|

程序人生 | QQ

粤公网安备 44040202000007号

( 粤ICP备13038131号-5 )

返回顶部