认证管理

.NET Core中的认证管理解析

.NET Core中的认证管理解析

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等等),看得我很晕,最后总算搞明白了一些,很多细节也没去深究,文中内容有的基于代码,有的基于个人理解,有错误希望大家嘴下留情。

时间: 2024-12-28 08:21:56

认证管理的相关文章

企业级应用身份认证管理扫盲篇——协议

最近为国内银行客户设计新系统与现有系统的集成.关键之一在于登录认证.在了解现有系统的非标接口过程中不出意外地遇到了些困难. 类比个例子,现有系统是个插线板,要求新系统插头标准如下: 三平头,头长18mm宽9mm厚2mm, 三头中心点距圆心10mm, 上头平行圆心到头心线,下二头垂直圆心到头心线. 上述接口是美标,欧标,英标,或者中国标准? "什么?都不是?嗯--" 如此的例子在企业级应用的登录认证集成过程中总是会遇到的.IT发达的国家整体情况好很多,因为大多数实现都采用了业界通行的标准

Greenplum中角色权限及客户端认证管理

角色权限及客户端认证管理 GP数据库逻辑结构 在GP中,Database(数据库).Schema(模式)以及Role(角色)三者之间的关系如下所示: 一个数据库下可以有多个模式,一个模式只属于一个数据库.模式在GP中也被称为Namespace,不同数据库之间的模式没有关系,可以重名: 语言在使用之前必须创建,一个语言只属于一个数据库: 表.视图.索引.序列.函数必须属于一个模式: 一个文件空间可以有多个表空间,一个表空间只属于一个文件空间,文件空间和角色之间没有关系: 表空间和表时一对多的关系,

如何实现excel服务器的用户管理和认证管理

1. 简介 本篇文章主要介绍的是活字格中用户管理与认证管理,什么是认证模式?什么是用户管理?什么是认证管理?怎么管理普通用户,域用户,用户角色.怎样控制哪些用户可以访问哪些页面等等. 认证模式(普通认证和windows域认证):用来标识你的网站的认证是普通模式(用户是普通认证中用户)还是windows域模式(域用户访问)的. 认证管理:用来管理每个页面的权限,哪些用户哪些角色可以访问哪些页面. 用户管理:管理所有用户信息包括普通认证用户,域用户,用户角色以及用户的自定义属性. 2. 用户管理 不

KbmMW 认证管理器说明(转载)

这是kbmmw 作者关于认证管理器的说明,我懒得翻译了,自己看吧. There are 5 parts of setting up an authorization manager: A) Defining what the resources are (often services or service functions, but can be anything you want to protect).B) Defining who the actors (typically users)

使用delphi 开发多层应用(二十二)使用kbmMW 的认证管理器

从kbmmw 4.4 开始,增加了认证管理器,这个比原来的简单认证提供了更多的功能.细化了很多权限操作. 今天对这一块做个介绍. 要做一个认证管理,大概分为以下5步: 1.  定义你要保护的资源,一般是服务.函数,当然你只要不限麻烦,可以是任何东西: 2.  定义使用者(用户): 3.  定义角色,使用者通过角色与服务器打交道: 4.  定义角色或用户可以访问的资源(授权): 5. 定义认证与登录的限制(本步不是必须的). 一般来说,用户是通过配置文件或数据库来保存的,这样可以灵活的设置用户名与

NET Core中的认证管理解析

2016-08-19 07:15 0x00 问题来源 在新建.NET Core的Web项目时选择"使用个人用户账户"就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可以使用AuthorizeAttribute进行各种权限管理,看起来似乎十分方便.不过生成的代码都替我干了些什么我一团雾水.看了下生成的数据表,功能也挺复杂的.实际上我需要的只是基于用户和角色的认证管理,而且用户资料是使用现有的库,但使用.NET Core自带的认证组件必须要依赖EF,表的结构

企业IM-4 InIOCP组件介绍-客户端 连接与认证管理

对于客户端来说,连接到服务端及提供相应的认证数据尤其重要. InConnection用于连接远程的服务端,可指定IP和端口. 通过Active属性来启用或停止连接. 当服务器出现异常时,会调用Client的相应方法 Certify会提供具体的登陆结果. 至此,我们可以看到一个简单的 服务端提供服务.客户端登录的样例. 原文地址:http://blog.51cto.com/8828194/2071668

区块链能为教育带来什么? 构建一个信息认证管理数据库

o2qss0蒙辗夜史衔魏http://wenda.cngold.org/question743374.htmnpjfz7研运某颗馗陌http://wenda.cngold.org/question743281.htmwu48q0韶岗耙袄税股http://wenda.cngold.org/question743328.htmqcay84偻恳映蛔录垦http://wenda.cngold.org/question743429.htmo4m4ca揭找授肝考怨http://wenda.cngold.or

#5 用户和组的管理(AAA认证的由来)

用户和组的管理 用户账户 组账户 权限的分配 Cisco开发的AAA认证体系: Authentication:认证,核实身份是否正确: Authorization:授权,对已经核实身份的用户进行资源分配: Accounting:审计,监管资源被使用的情况: 多用户.多任务的系统:(在服务器上通常是多用户.多任务的操作系统) 能够实现资源使用和完成的任务的主体是:应用程序进程 安全上下文:secure context 进程是以其发起者的身份运行的:可以理解为,进程的所有者就是发起者:会将发起者的信