前言

从本篇开始将围绕asp.net core身份验证写个小系列,希望你看完本系列后,脑子里对asp.net core的身份验证原理有个大致印象。
至于身份验证是啥?与授权有啥联系?就不介绍了,太啰嗦。你如果不晓得,自己去搜搜吧。
我的学习思路是详细看源码 > 总结得出一个宏观上的印象 + 如何使用。
如果发现有啥讲错的望指正,免得误导观众

我们偶尔会思考如何设计一个牛X的软件,其实通过对asp.net core框架本身的学习更划算,一来我们熟悉了asp.net core框架,再者我们学习了微软碰到需求是如何设计的。

计划:

  • 基本介绍 - 概述 + 核心类介绍
  • 基于cookie/session的身份验证原理 - 适合浏览器
  • 基于Token身份验证 - 适合移动端app
  • 集成第三方登录原理 - 比如集成微信、支付宝登录
  • IdentityServer - 目前不鸟解
  • asp.net core Identity - 目前不鸟解

必备知识:asp.net core、配置、选项、依赖注入、中间件等...

参考:源码Artechmvc5基于owin的身份验证视频

注意:本篇只讲涉及到的几个概念

身份验证方式和简易流程

常见的身份验证方式:

  • 基于cookie/session的身份验证原理 - 适合浏览器
  • 基于Token身份验证 - 适合移动端app
  • 集成第三方登录原理 - 比如集成微信、支付宝登录

为了便于理解后续的概念,下面先以最常见的 用户密码+cookie的身份验证方式说说核心流程

登录:

  1. 用户输入账号密码提交
  2. 服务端验证账号密码
  3. 若验证成功,则创建一个包含用户标识的票证(下面会说)
  4. 将票证加密成字符串写入cookie

携带cookie请求:

  1. 用户发起请求
  2. 身份验证中间件尝试获取并解密cookie,进而得到含用户标识的票证(下面会说)
  3. 将用户标识设置到HttpContext.User属性

注意:若身份验证中间件即使没有解析得到用户标识,请求也会继续执行,此时以匿名用户的身份在访问系统

用户标识ClaimsPrincipal

它用来表示当前登录的用户,它包含用户Id + 一些与权限检查相关的附件属性(角色、所属部门)。
当请求抵达时“身份验证中间件”将从请求中解析得到当前用户,如果获取成功则赋值给HttpContext.User属性

所以对于我们来说通常有两个场景使用它
在任意能访问HttpContext的地方获取当前用户,比如在Controller中。
如果需要自定义实现身份验证,则我们要想方设法从请求中解析得到用户,并赋值给HttpContext.User

现在你至少对用户标识这个概念有点理解了,如果要刨根问底儿就自行搜索关键字:asp.net Claims

也许你曾经做过或见过这样的设计,定义Employee表示当前系统的用户,当用户登录时会从数据库查询得到对应的Employee,若账号密码验证通过则将其放入Session或缓存中。下次访问时直接从Session/缓存中获取当前用户。个人觉得这种设计存在如下问题:

  • 浪费内存:我们的业务代码访问当前用户最多的字段可能只是用户id,性别、地址、联系电话、学历....这些字段不是每个业务处理都需要的
  • 抛弃了asp.net身份验证框架:从asp.net 2.0时代微软就设计了IPrincipal,后续的版本直到mvc5中基于owin的身份验证都在使用此接口,后续的权限验证微软也提供了,也是基于此接口的,但我们放弃了,反而是自己有写了一套微软本身就实现的功能,可能多数是觉得自己写的更简单。但我觉得判断哪种方式更合适是在你对两种方式都了解的情况下再做出判断。

用户票证AuthenticationTicket

既然有了上面的用户标识,何不直接在登录时加密这个标识,解析时直接解密得到呢?因为我们还需要额外的控制,比如过期时间,这个属性只是在身份验证阶段来判断是否过期,在我们(如Controller.Action中)使用用户标识的时候并不需要此字段,类似的额外字段根据不同的身份验证方式可能有很多,因此定义了“用户票证”这个概念,它包含 用户标识 + 身份验证过程中需要的额外属性(如得到用户标识的时间、过期时间等)

身份验证处理器AuthenticationHandler

参考上面的用户名密码+cookie身份验证流程我们发现有几个核心的处理步骤:

  • 在登录时验证通过后将用户标识加密后存储到cookie,SignIn
  • 当用户注销时,需要清楚代表用户标识的cookie,SignOut
  • 在登录时从请求中获取用户标识,Authenticate
  • 在用户未登录访问受保护的资源时,我们希望跳转到到登录页,Challenge
    • Challenge叫做质询/挑战,意思是当发现没有从当前请求中发现用户标识是希望怎么办,可能是跳转到登录页,也可能是直接响应401,或者跳转到第三方(如QQ、微信)的登录页 
  • 因为某种原因(如权限验证不过),阻止方案,Forbid

身份验证处理器就是用来定义这些步骤的
asp.net core中定义了对应的接口、和抽象类,不同的身份验证方式有不的实现类,比如基于token的身份验证方式在SignIn时直接加密票证然后返回这个字符串(而不是写入cookie)
这些步骤都是围绕身份验证来定义的,在不同地方来调用(比如在登录页对于的Action、在请求抵达时、在授权中间件中)

身份验证选项AuthenticationSchemeOptions

在上述身份验证处理的多个步骤中会用到一些选项数据,比如基于cookie的身份验证 cookeName、有效时长、再比如从请求时从cookie中解析得到用户标识后回调选项中的某个回调函数,允许我们的代码向调试中添加额外数据,或者干脆替换整个标识。

所以身份验证选项用来允许我们控制AuthenticationHandler的执行。不同的身份验证方式有不同的选项对象,它们直接或间接实现AuthenticationSchemeOptions

身份验证方案AuthenticationScheme

总结性的说:身份验证方案 = 名称 + 身份验证处理器类型,暂时可以理解一种身份验证方式 对应 一个身份验证方案,比如:
基于用户名密码+cookie的身份验证方式 对应的 身份验证方案为:new AuthenticationScheme("UIDPWDCookie",typeof(CookieAuthenticationHandler))
基于用户名密码+token  的身份验证方式 对应的 身份验证方案为:new AuthenticationScheme("JwtBearer",typeof(JwtBearerHandler))

身份验证方案在程序启动阶段配置,启动后形成一个身份验证方案列表。
程序运行阶段从这个列表中取出制定方案,得到对应的处理器类型,然后创建它,最后调用这个处理器做相应处理
比如登录操作的Action中xxx.SignIn("方案名") > 通过方案名找到方案从而得到对应的处理器类型 > 创建处理器 > 调用其SignIn方法

一种特殊的情况可能多种方案使用同一个身份验证处理器类型,这个后续的集成第三方登录来说

身份验证方案的容器AuthenticationSchemeProvider

我们说一个系统可能同时支持多种身份验证方案,因此我们需要一个容器,可以把它理解为Dictionary<方案名,身份验证方案>

身份验证处理器容器AuthenticationHandlerProvider

可以暂时把它理解为Dictionary<方案名, 身份验证处理器容器>,因为这个对象是每次请求都会创建,并且它提供AuthenticationHandler时时从方案列表中去找到制定方案从而得到对应的处理器类型然后创建的。如果不理解没关系,下一篇讲流程就懂了

身份验证服务AuthenticationService

身份验证中的步骤是在多个地方被调用的,身份验证中间件、授权中间件、登录的Action(如:AccountController.SignIn())、注销的Action(如:AccountController.SignOut()),身份验证的核心方法定义在这个类中,但它本质上还是去找到对应的身份验证处理器并调用其同名方法。其实这些方法还进一步以扩展方法的形式定义到HttpContext上了。以SignIn方法为例
HttpContext.SignIn() > AuthenticationService.SignIn() > AuthenticationHandler.SignIn()

后续

这一篇只尽量简单的说了下身份验证涉及到的几个核心概念,如果不明白的可以留言或等到下篇结合理解。下一篇将以用户名密码+cookie的身份验证方式来详细梳理下流程。

asp.net core 3.x 身份验证-1涉及到的概念的更多相关文章

  1. asp.net core 3.x 身份验证-3cookie身份验证原理

    概述 上两篇(asp.net core 3.x 身份验证-1涉及到的概念.asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份 ...

  2. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  3. asp.net core 3.x 身份验证-2启动阶段的配置

    注册服务.配置选项.添加身份验证方案 在Startup.ConfigureServices执行services.AddAuthentication() 注册如下服务(便于理解省略了部分辅助服务): s ...

  4. ASP.NET Core和ASP.NET Framework共享Identity身份验证

    .NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源.组件化.跨平台.性能优秀.社区活跃等等标签再加上"微软爸爸"主推和大力支持,尽管现阶段对比.net ...

  5. ASP.NET Core 和 ASP.NET Framework 共享 Identity 身份验证

    .NET Core 已经热了好一阵子,1.1版本发布后其可用性也越来越高,开源.组件化.跨平台.性能优秀.社区活跃等等标签再加上"微软爸爸"主推和大力支持,尽管现阶段对比.net ...

  6. ASP.NET没有魔法——ASP.NET Identity 的“多重”身份验证

    ASP.NET Identity除了提供基于Cookie的身份验证外,还提供了一些高级功能,如多次输入错误账户信息后会锁定用户禁止登录.集成第三方验证.账户的二次验证等,并且ASP.NET MVC的默 ...

  7. 学学dotnet core中的身份验证和授权-1-概念

    前言 身份验证: Authentication 授权: Authorization net core 中的身份验证和授权这两个部分,是相辅相成的.当初我在学在部分的时候,是看的 net core 官网 ...

  8. ASP.NET MVC:窗体身份验证及角色权限管理示例

    ASP.NET MVC 建立 ASP.NET 基础之上,很多 ASP.NET 的特性(如窗体身份验证.成员资格)在 MVC 中可以直接使用.本文旨在提供可参考的代码,不会涉及这方面太多理论的知识. 本 ...

  9. ASP.NET 中通过Form身份验证 来模拟Windows 域服务身份验证的方法

    This step-by-step article demonstrates how an ASP.NET   application can use Forms authentication to ...

随机推荐

  1. Synchronized解析——如果你愿意一层一层剥开我的心

    前言 synchronized,是解决并发情况下数据同步访问问题的一把利刃.那么synchronized的底层原理是什么呢?下面我们来一层一层剥开它的心,就像剥洋葱一样,看个究竟. Synchroni ...

  2. 基于GPS北斗卫星授时系统和NTP网络授时服务器的设计与开发

    基于GPS北斗卫星授时系统和NTP网络授时服务器的设计与开发 安徽京准科技提供@请勿转载@@ 更多资料请参考——ahjzsz.com 天文观测设备对于控制系统的时间准确度有严格要求.为此,采用搭建高精 ...

  3. 《C++Primer》第五版习题答案--第三章【学习笔记】

    [C++Primer]第五版[学习笔记]习题解答第三章 ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2020/1/10 第三章:字符串,向量和数组 ...

  4. 生产环境中使用docker注意点

    是否对容器使用的资源进行合理限制,比如内存 CPU 网络带宽等. 是否设置合理的网络访问限制,如 非root用户 iptables. 是否有在docker无法使用时的备选方案,如提供非docker环境 ...

  5. stars-one原创工具——m3u8视频下载合并器(kotlin)

    一款可以下载m3u8.解密ts文件及合并ts文件的视频下载工具 蓝奏云下载地址 github地址 软件对你有帮助的话,不妨赞赏一波!感谢! 程序说明 采用多线程下载,可有效的提高下载速度 内置解密程序 ...

  6. Android 平台JS调试技术

    1.  测试技术简介 Android平台微信公众号一般以H5的形式开发,测试发现流量一般都通过js进行加密传输,导致无法对越权.SQL注入等风险点进行测试.针对此难点,本手册会介绍包括Android环 ...

  7. enum sizeof typedef分析

    1.枚举类型的使用方法 enum是C语言中的一种自定义类型 enum值是可以根据需要自定义的整型值 第一个定义的enum值默认为0 默认情况下的enum值是在前一个定义值的基础上加1 enum类型的变 ...

  8. OpenGLES思维导图

    两本书到头来就只剩下了这三张图了吧.想要原图:https://github.com/wangwangla/biji/blob/master/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8 ...

  9. 临近年关,修复ASPNETCore因浏览器内核版本引发的单点登陆故障

    临近年关,咨询师提出360,搜狗急速浏览器无法单点登陆到公司核心产品WD, 报重定向过多. 现象 经过测试, 出现单点登陆故障的是搜狗,360等主打双核(默认Chrome内核)的浏览器, 较新式的Ed ...

  10. java8新特性Lambda和Stream

    Java8出来已经4年,但还是有很多人用上了jdk8,但并没用到里面的新东西,那不就等于没用?jdk8有许多的新特性,详细可看下面脑图 我只讲两个最重要的特性Lambda和Stram,配合起来用可以极 ...