前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一个基础的验证服务器,并实现了基于客户端证书的Oauth2.0受权流程,以及经过access token访问被保护资源,本文将继续完善IdentityServer实现与Identity组件的集成,可以使用Identity的用户来完成受权。html
在软件领域中只要提到身份验证就能想到登陆,而登陆每每与用户名和密码相关联,IdentityServer4或者说OAuth2.0和OpenIDConnect也是同样的,它须要用户数据来支持完成相关的验证及受权操做,下面咱们就先来实现IdentityServer4的用户数据接入及与用户数据相关的受权流程。数据库
首先为IdentityServer添加Asp.Net core Identity模块:api
Asp.net core Identity是Asp.net core的身份验证组件,它不只包含了身份验证所需的数据及数据持久化支持,另外还提供了用户管理、登陆管理等一系列的服务和UI,在建立新的Asp.net core mvc或api项目时,若是勾选身份验证选项就会默认包含该组件,可是因为文本中的例子是从零开始的,因此Identity组件也须要手动添加。服务器
在添加Identity以前还有一个概念须要再说一下就是metapackege(元包,具体参考:https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/),它实质上是一组共享库,提供了.net core和asp.net core应用的基础运行时和基础功能,在建立项目时默认会依赖相应.net core版本的元包,而元包共享的程序集实际上在dotnet的安装目录的shared目录下,元包的好处就是在框架发布时,发布文件就不须要包含元包内容,减小发布文件大小:mvc
而Asp.net core 5.0应用程序包含两个元包:框架
其中Microsoft.AspNetCore.App中包含了Identity的基础组件:asp.net
基础组件中已经包含了Identity的基础组件,如IdentityUser等相关的实体以及相关的服务类型/接口,因此换句话说使用Identity功能仅须要完成数据持久化及UI便可。ide
EF core是.net core下面的首选数据持久化框架,因此一样的identity也提供了基于EF core的数据持久化组件,添加基于EF的Identity数据持久化组件:布局
同时为了方便后续的扩展,新建一个ApplicationUser继承于IdentityUser和ApplicationDbContext继承于IdentityDbContext<ApplicationUser>:visual-studio
添加Identity的数据上下文及identity服务:
添加数据库迁移代码并更新到数据库:
Add-Migration initIdentityDb -c ApplicationDbContext -o Migrations/IdentityServer/IdentityDb
Update-Database -Context ApplicationDbContext
Identity的UI是一个Razor的类库,换句话说就是页面文件被包含在类库里面了,若是要对UI进行修改能够经过VS的构建程序构建(VS Code可参考文档:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-5.0&tabs=netcore-cli#scaffold-identity-into-an-empty-project):
在对话框中选择“标识(Identity)”中的“标识(Identity)”选项:
在标识对话框中勾选“替代全部文件”,布局文件没有留空便可,最后选择Identity的DbContext便可:
添加Razor服务、静态文件处理中间件(访问js等文件)及Razor终结点映射:
访问登陆地址:https://localhost:55002/Identity/Account/Login
到目前为止identity的数据库和UI都已经添加到项目中而且能够运行了,可是还存在一些问题,如默认的Identity UI相关功能依赖IEmailSender组件等等,同时还须要与IdentityServer4集成,其登陆、注册、登出等基础功能须要根据IdentityServer4自己的一些需求进行修改。
下面就进入IdentityServer4与Asp.net core Identity的集成工做,首先先添加IdentityServer4.AspNetIdentity组件:
而后经过IIdentityBuilder向容器中添加相关服务:
最后对修改一下Identity的注册代码,将与IEmailSender有关的代码注释掉(注:默认生成代码中包含邮件发送逻辑,可是没有EmailSender的实现,除了注释相关代码外也能够实现一个IEmailSender并注册到容器中来解决问题):
启动应用,访问注册页面注册用户:https://localhost:55002/Identity/Account/Register
注册成功后,在数据库中为相应的client信息手动添加一条基于用户名密码的Grant Type(password),便可使用注册的用户来经过password的方式获取access token了:
如下是经过刚注册用户名密码得到的access token:
对上面的access token解码后能够看到它的payload部分包含如下信息(sub使用了用户的Id):
小提示:在IdentityServer4中获取Token时会根据请求对携带的Client信息以及相关参数进行验证,本例中若是Client不支持Password的Grant Type,那么会致使不支持相应的受权类型而致使没法正确得到Access Token,遇到没法正确得到Access Token或者一些验证错误的时候能够在调试模式下查看IdentityServer的输出,里面会包含相关受权成功/失败的信息。
本篇文章经过集成asp.net core identity组件实现了用户管理,包括注册、登陆等,而且实现了经过注册的用户,基于Oauth2.0的用户名密码模式(password grant type)来获取到Access Token,但就目前为止本系统文章所实现的、演示的IdentityServer功能仍旧是基于Oauth2.0协议,从下一篇文章开始就会开始介绍OpenIDConnect(oidc)相关的内容,此外现阶段实现的Identity登陆也仅仅只是Identity自己的内容,针对OpenIDConnect或者说IdentityServer4它还有一些额外的操做,如事件、受权赞成等等,这些内容也会在后续文章中不断完善。
参考:
https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/