[转].NET Core中的认证管理解析
本文转自:http://www.cnblogs.com/durow/p/5783089.html
0x00 问题来源
在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册、登录等很多页面,也可以使用AuthorizeAttribute进行各种权限管理,看起来似乎十分方便。不过生成的代码都替我干了些什么我一团雾水。看了下生成的数据表,功能也挺复杂的。实际上我需要的只是基于用户和角色的认证管理,而且用户资料是使用现有的库,但使用.NET Core自带的认证组件必须要依赖EF,表的结构也很多对不上,所以学习了下自带的认证组件的实现,然后自己写了个认证服务替换了Identity组件,同时Cookie管理使用自带的Cookie中间件、可以使用AuthorizeAttribute进行认证。复杂的需求还没遇到,所以就学习到了这里。这篇博客主要讨论最简单情况下的的基于用户和角色的认证。关于.NET Core自带认证组件的一些基本用法,可以参考https://docs.asp.net/en/latest/security/authentication/accconfirm.html。
0x01 .NET Core中的认证管理
提到认证管理,首相想到的就是用户的注册、登录、注销以及给用户添加/删除角色等功能。其中用户信息,角色信息等都是保存在数据库中的。所以主要包含数据库操作和登录业务逻辑两部分。在登录业务逻辑层面,.NET Core主要通过三个比较核心的类UserManager、RoleManager、SigninManager进行管理(在Microsoft.AspNetCore.Identity程序集)。其中:
- UserManager主要负责用户的认证、注册、修改、删除以及与用户相关的角色、令牌、声明等的管理。
- RoleManager负责角色、角色相关声明的管理。
- SigninManager负责登录、注销等相关操作。在涉及到用户操作(如登陆时用户验证)会调用UserManager进行操作。
这三个核心类在操作数据库时,使用数据库层面的UserStore、RoleStore进行操作(在Microsoft.AspNetCore.Identity.EntityFrameworkCore程序集)。业务关系如下图所示:
我们在开发认证相关功能时使用这三个核心类即可满足大多数需求。我们在使用这几个核心类的对象时都是通过依赖注入获取的,那么这些相关的依赖是什么时候注入的呢?在Startup的ConfigureServices方法中有AddIdentity扩展方法,就是在这个方法中添加了需要的所有依赖。
0x02 登录和注销
了解了Identity组件的整体分工后,再来看一下登录和注销的操作的部分细节。登录和注销过程主要由SigninManager负责,的先来看一下登录的过程:
登录成功后Response的Header中包含了Set-Cookie,Cookie的Key需要和Cookie中间件中设置的要解密的Cookie的Key一致,在截图中这个Cookie的Key是IdentityCookie。设置Cookie的同时返回302重定向到登录页面。
重定向到登陆页面时,请求中已经带有设置的Key为IdentityCookie的Cookie了。
注销过程比较简单,调用HttpContext.Authentication.SignOutAsync方法即可注销,此时会给HttpContext.Response添加Set-Cookie,但内容为空。
0x03 通过Cookie识别用户
.NET Core中通过CookieAuthenticationMiddleware这个中间件识别HttpContext中认证相关的Cookie,从而添加用户的验证和授权信息。最关键的是ClaimsPrincipal对象,它记录用户的认证和授权信息(除此之外当然也可以包含其它你需求的任意信息),从上面登录过程可以看到,登录成功后用户认证和授权信息保存至ClaimsPrincipal对象(实际上对于这条Cookie键值对中的认证信息保存为ClaimsIdentity,一个ClaimsPrincipal可以包含多个ClaimsIdentity),然后在HttpContext.Response的Headers中添加Set-Cookie,Key为Cookie中间件中指定的CookieName,Value就是这个对象加密后的字符串。以后的HttpContext都会带有这个Cookie,Cookie中间件会把符合这个CookieName的Cookie取出来,解密并还原为ClaimsPrincipal对象,并把HttpContext.User设置为这个对象。后面MVC中间件在路由到相应Controller和Action的时候就可以根据Authorize特性中指定的认证和角色在HttpContext.User中进行检查,不满足检查则跳转至相应页面。因此需要注意的就是一定要把Cookie中间件放在MVC中间件之前。
这里需要特别说一下ClaimsPrincipal。一个ClaimsPrincipal对象中包含了一个或多个ClaimsIdentity对象,一个ClaimsIdentity对象一般来说对应着一个Cookie中某条键值对(个人理解)。Cookie中间件和ClaimsIdentity是通过AuthenticationScheme联系起来的。后面我们在写自己的认证服务时,也是把Cookie中间件的AuthenticationScheme和创建的ClaimsIdentity一致。所以更准确地说是ClaimsIdentity包含了用户认证和权限的声明,而ClaimsPrincipal可以包含多个ClaimsIdentity。当管道中存在多个Cookie中间件时,通过AuthenticationScheme进行区分。
在ClaimsIdentity中除了AuthenticationScheme外还有两个比较重要的属性,UserType和RoleType,其中UserType指定了用户验证类型,RoleType指定可角色验证类型。意思就是如果我指定了RoleType为”RoleName”,那么在进行角色认证时就会寻找Claims中所有的Type为”RoleName”的值,并检查其中是否包含了Authorize中指定的RoleName。不过.NET Core中自带了ClaimTypes,可以直接使用。例如角色类型就是ClaimTypes.Role。如果添加角色时用的自带的ClaimTypes.Role,那么在创建ClaimsIdentity时就不需要显示指定RoleType了,默认角色认证就是使用ClaimTypes.Role。
关于Cookie中间件的添加,是通过Startup中Configure方法中的app.UseIdentity扩展方法实现的。这个扩展方法实际上添加了多种Cookie识别方式。在后面我在写自己的用户认证管理时只用一种。
0x04 自己写用户认证管理
了解了用户认证的过程,我们可以自己写认证管理来代替Identity组件了,同样分为数据库操作和认证业务逻辑。数据库相关就不多说了,都写到了IdentityRepository类,只有很简单的数据操作。为了方便使用了Dapper,数据库用的Sqlite。程序在启动时会检查数据库表,没有会自动创建空表。
认证服务也比较简单就都写到了IdentityService类,提供了注册和登录操作,注销太简了直接写在了Action里。为了方便没有提供角色管理页面,如果要测试角色认证功能,需要手动去数据库添加Role,然后在UserRoles中给用户添加Role。
登录:
注册:
注销:
具体示例可以到:
https://github.com/durow/NetCoreStudy
只是为了测试,逻辑上很多问题,比如用户密码明文存储。重点看过程:)
0x05 写在最后
第一次接触Web应用,很多概念都不是很了解。就拿Cookie认证用户来说,我之前的只知道通过Cookie识别用户,一直以为是收到Cookie后再从数据库或缓存中查出相应的权限信息。不过看了自带的Cookie中间件代码后才知道认证信息是直接存在Cookie中的,这样只要解密后反序列化就可以了。Identity这个程序集涉及了很多其它程序集(Security、HttpAbstraction等等),看得我很晕,最后总算搞明白了一些,很多细节也没去深究,文中内容有的基于代码,有的基于个人理解,有错误希望大家嘴下留情。
[转].NET Core中的认证管理解析的更多相关文章
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- .Net Core中自定义认证实现
一.起因 最近项目中需要对项目同时支持JWT认证,以及自定义的认证校验方式认证.通过对官方文档了解,得到认证实现主要通过继承IAuthenticationHandler 或 Authenticatio ...
- asp.net core 2.1认证
asp.net core 2.1认证 这篇文章基于asp.net core的CookieAuthenticationHandler来讲述. 认证和授权很相似,他们的英文也很相似,一个是Authenti ...
- .net core 中的经典设计模式的应用
.net core 中的经典设计模式的应用 Intro 前段时间我们介绍了23种设计模式,今天来分享一下 asp.net core 种我觉得比较典型的设计模式的应用 实例 责任链模式 asp.net ...
- 如何在ASP.NET Core 中使用IHttpClientFactory
利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期. 当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用Web ...
- ASP.NET Core中的OWASP Top 10 十大风险-失效的访问控制与Session管理
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...
- ASP.NET CORE中使用Cookie身份认证
大家在使用ASP.NET的时候一定都用过FormsAuthentication做登录用户的身份认证,FormsAuthentication的核心就是Cookie,ASP.NET会将用户名存储在Cook ...
- C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
C# 嵌入dll 在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...
- ASP.NET Core 中jwt授权认证的流程原理
目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...
随机推荐
- Php基础知识测试题
一:选择题 1. LAMP具体结构不包含下面哪种(A ) A:Windows系统 如果是这个就是WMP B:Apache服务器 C:MySQL数据库 D:PHP语 ...
- Android线程管理之ExecutorService线程池
前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Execu ...
- 设计模式(九): 从醋溜土豆丝和清炒苦瓜中来学习"模板方法模式"(Template Method Pattern)
今天是五.四青年节,祝大家节日快乐.看着今天这标题就有食欲,夏天到了,醋溜土豆丝和清炒苦瓜适合夏天吃,好吃不上火.这两道菜大部分人都应该吃过,特别是醋溜土豆丝,作为“鲁菜”的代表作之一更是为大众所熟知 ...
- ORACLE 11gR2 DG(Physical Standby)日常维护02
环境:RHEL 6.5 + Oracle 11.2.0.4 三.监控DG的状态 3.1监控DG备库的状态 3.2监控主库传输日志链路的状态 四.备库切换为snapshot standby 4.1备库切 ...
- CSS知识总结(二)
CSS的选择符分成: 1. 通配选择符 2. 元素选择符 3. 群组选择符 4. 关系选择符 5. id及class选择符 6. 伪类选择符 7. 属性选择符 8. 伪对象选择符 1.通配选择符(*) ...
- .net请求URL过长,解决方案
<system.web> 节点下加上 <httpRuntime requestValidationMode="2.0" maxQueryStringLength= ...
- react入门(3)
在第一篇文章里我们介绍了jsx.组件.css写法 点击查看react入门(1) 第二篇文章里我们介绍了事件.this.props.children.props....other.map循环 点击查 ...
- Win10 UWP开发系列:实现Master/Detail布局
在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...
- 第二篇 Entity Framework Plus 之 Query Future
从性能的角度出发,能够减少 增,删,改,查,跟数据库打交道次数,肯定是对性能会有所提升的(这里单纯是数据库部分). 今天主要怎样减少Entity Framework查询跟数据库打交道的次数,来提高查询 ...
- PHP中模拟JSONArray
前面整理过一篇文章,描述php中的array与json的array和object的转换关系.http://www.cnblogs.com/x3d/p/php-json-array-object-typ ...