我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:六合特肖 > 访问令牌 >

Core的身份认证框架IdentityServer4--入门【转】

归档日期:06-27       文本归类:访问令牌      文章编辑:爱尚语录

  目前流行的一句话是“概念上兼容”,但这对于Identity Server 4来说是正确的。概念是相同的,它仍然是按照规范构建的OpenID Connect提供程序,但是它的大部分内部和可扩展性点已经改变。当我们将客户端应用程序与IdentityServer集成时,我们没有集成到实现中。相反,我们使用OpenID Connect或OAuth规范进行集成。这意味着当前与IdentityServer 3一起使用的任何应用程序都将与IdentityServer 4一起使用。

  Identity Server被设计为作为自托管组件运行,使用4.x很难实现,而MVC仍然与IIS和System.Web紧密耦合,从而导致katana提供内部视图引擎零件。借助在ASP.NET Core上运行的Identity Server 4,我们现在可以在ASP.NET Core可以运行的任何环境中使用任何UI技术和主机IdentityServer。这也意味着我们现在可以与现有的登录表单/系统集成,从而实现升级。

  IdentityServer 3不会去任何地方,就像.NET Framework不会去任何地方一样。就像微软已将大多数活动开发转移到.NET Core(参见KatanaASP.NET Identity)一样,我想IdentityServer最终会做同样的事情,但我们在这里讨论的是OSS,而项目保持这种状态它始终是开放的PRs修复错误和相关的新功能。我不会很快放弃它,商业支持将继续下去。

  对于我们的初始实现,我们将使用为演示和轻量级实现保留的内存服务。在本文的后面,我们将切换到实体框架,以更真实地表示IdentityServer的生产实例。

  在开始编码之前,将项目URL切换为HTTPS。在没有TLS的情况下,您不应该运行身份验证服务。假设您使用的是IIS Express,则可以通过打开项目属性,进入“调试”选项卡并单击“启用SSL”来执行此操作。虽然我们在这里,但您应该将生成的HTTPS URL作为App URL,这样当我们运行项目时,我们就会从正确的页面开始。

  如果在为localhost使用IIS Express开发证书时遇到证书信任问题,请尝试按照本文中步骤操作。如果您发现此方法存在问题,请随意切换到自托管模式(而不是IIS Express,使用项目的命名空间运行)。

  在您的ConfigureServices方法中添加以下内容以注册所需的最低依赖项:

  我们在这里做的是在我们的DI容器中注册IdentityServerAddIdentityServer,使用演示签名证书AddDeveloperSigningCredential,并为我们的客户,资源和用户使用内存存储。通过使用,AddIdentityServer我们还将所有生成的令牌/授权存储在内存中。我们将很快添加实际的客户,资源和用户。

  OpenID Connect Discovery文档(被亲切地称为disco doc)可在此着名端点的每个OpenID Connect提供程序上使用(根据规范)。本文档包含各种端点的位置(例如令牌端点和结束会话端点),提供程序支持的授权类型,可提供的范围等信息。通过这个标准化文档,我们开辟了自动集成的可能性。

  签名证书是用于签署令牌的专用证书,允许客户端应用程序验证令牌的内容在传输过程中未被更改。这涉及用于签署令牌的私钥和用于验证签名的公钥。客户端应用程序可以通过jwks_uriOpenID Connect发现文档访问此公钥。

  当您创建并使用自己的签名证书时,请随意使用自签名证书。此证书不需要由受信任的证书颁发机构颁发。

  首先,我们需要存储允许使用IdentityServer的客户端应用程序,以及这些客户端可以使用的资源以及允许对其进行身份验证的用户。

  我们目前正在使用InMemory商店,这些商店接受他们各自实体的集合,我们现在可以使用一些静态方法填充它们。

  IdentityServer需要知道允许哪些客户端应用程序使用它。我想将此视为白名单,即您的访问控制列表。然后将每个客户端应用程序配置为仅允许执行某些操作,例如,他们只能请求将令牌返回到某些URL,或者他们只能请求某些信息。他们有访问范围。

  这里我们添加一个使用Client Credentials OAuth授权类型的客户端。此授权类型需要客户端ID和客户端密钥来授权访问,使用Identity Server提供的扩展方法简单地对密码进行哈希处理(毕竟我们从不在纯文本中存储任何密码,这总比没有好)。允许的范围是允许此客户端请求的范围列表。这里我们的范围是customAPI.read,我们现在将以API资源的形式初始化它。

  范围代表您可以做的事情。它们代表我之前提到的范围访问。在IdentityServer 4中,作用域被建模为资源,它有两种形式:Identity和API。标识资源允许您为将返回特定声明集的作用域建模,而API资源作用域允许您建模对受保护资源(通常是API)的访问。

  前三个身份资源代表我们希望IdentityServer支持的一些标准OpenID Connect定义的范围。例如,email范围允许返回email和email_verified声明。我们还创建了一个自定义标识资源,其形式为经过身份验证的用户role返回role声明。

  快速提示,openid使用OpenID Connect流时始终需要范围。您可以在OpenID Connect规范中找到有关这些的更多信息。

  通过在这样的范围内设置声明,我们确保将这些声明类型添加到具有此范围的任何标记中(当然,如果用户具有该类型的值)。在这种情况下,我们确保将用户角色声明添加到具有此范围的任何令牌。稍后将在令牌自省期间使用范围秘密。

  offline_access现在,默认情况下支持用于请求刷新令牌的作用域,并授权使用由该Client属性控制的此作用域AllowOfflineAccess。

  用户主题(或子)声明是其唯一标识符。这应该是您的身份提供商独有的东西,而不是电子邮件地址。我指出这是由于最近Azure AD的漏洞。

  如果您再次运行此命令并再次访问发现文档,您现在将看到填充的部分scopes_supported和claims_supported部分。

  为了测试我们的实现,我们可以使用之前的OAuth客户端从Identity Server获取访问令牌。这将使用Client Credentials流程,因此我们的请求将如下所示:

  我们现在可以使用IdentityServer的令牌内省端点来验证令牌,就好像我们是从外部方接收它的OAuth资源一样。如果成功,我们将收到该标记中的声明回复给我们。请注意,IdentityServer 4中的访问令牌验证端点在IdentityServer 4中不再可用。

  在这里,我们之前创建的范围秘密通过使用基本身份验证来使用,其中用户名是范围Id,密码是范围秘密。

  IdentityServer文档还提供了有关如何使用资源所有者授权类型的指南。不要被这种授权类型包含用户名和密码的事实所迷惑,它仍然只是授权而不是身份验证。实际上,文章和原始OAuth 2.0规范中有多个免责声明,声明此授权类型应仅用于旧版应用程序。请参阅我的文章为什么资源所有者密码凭据授予类型不是身份验证也不适合现代应用程序,以调查资源所有者授予类型的所有错误。

  要下载此文件,请将repo中的所有文件夹复制到项目中,或使用以下powershell命令(同样,在项目文件夹中):

  现在我们需要将ASP.NET MVC Core添加到我们的项目中。为此,首先将以下包添加到项目中(如果已安装,则可以跳过此安装Microsoft.AspNetCore.All):

  现在,当我们运行项目时,我们会看到一个闪屏。万岁!现在我们有了UI,现在我们可以开始验证用户了。

  要使用OpenID Connect演示身份验证,我们需要创建一个客户端Web应用程序并在IdentityServer中添加相应的客户端。

  重定向和后注销重定向uris的位置是我们即将推出的应用程序的URL。重定向uri需要路径/signin-oidc,这条路径将由即将推出的中间件自动创建和处理。

  这里我们使用OpenID Connect隐式授权类型。此授权类型允许我们通过浏览器请求身份和访问令牌。我会称之为最简单的授权类型,但也是最不安全的。

  现在我们需要创建客户端应用程序。为此,我们需要另一个Core网站,这次使用Web应用程序(MVC)VS模板,但没有认证。

  在这里,我们告诉我们的应用程序使用cookie身份验证,登录用户,并将其用作默认的身份验证方法。虽然我们可能正在使用IdentityServer对用户进行身份验证,但每个客户端应用程序仍需要发布自己的cookie(到其自己的域)。

  在这里,我们告诉我们的应用程序使用我们的OpenID Connect Provider(IdentityServer),我们希望登录的客户端ID以及成功验证时登录的身份验证类型(我们之前定义的cookie中间件)。

  默认情况下,ID连接中间件选项将使用/signin-oidc其重定向URI,请求范围openid和profile,并用implicit流动(只要求身份令牌)。

  接下来我们需要在我们的管道(Configure)之前添加身份验证UseMvc:

  现在剩下的就是让页面需要身份验证才能访问。让我们将“添加”属性添加到“联系人”操作,因为联系我们的人是我们想要的最后一件事。

  现在,当我们运行此应用程序并选择“联系”页面时,我们将收到未经授权的401。这反过来将被我们的OpenID Connect中间件拦截,该中间件将302重定向到我们的Identity Server身份验证端点以及必要的参数。

  成功登录后,IdentityServer将要求我们同意客户端应用程序代表您访问某些信息或资源(这些信息或资源对应于客户端请求的身份和资源范围)。可以在客户端基于客户端禁用此同意请求。默认情况下,Core的OpenID Connect中间件将请求openid和配置文件范围。

  这就是使用隐式授权类型连接简单OpenID Connect Client所需的全部内容。

  目前我们在内存存储中使用,正如我们之前提到的那样,它是用于演示目的,或者最多是非常轻量级的实现。理想情况下,我们希望将各种商店移动到一个持久性数据库中,该数据库在每次部署时都不会被删除,或者需要更改代码才能添加新条目。

  Identity Server Entity Framework Core软件包已使用In-Memory,SQLite(内存中)和SQL Server数据库提供程序进行了集成测试。如果您发现其他提供商存在任何问题或希望针对其他数据库提供商编写测试,请随时在GitHub问题跟踪器上打开问题或提交拉取请求)。

  对于本文,我们将使用SQL服务器(SQL Express或本地数据库会这样做),因此我们需要以下nuget包:

  持久授权存储包含有关给定同意的所有信息(因此我们不会一直要求对每个请求的同意),引用令牌(存储的jwt,其中只有与jwt相对应的密钥被提供给请求者,使其易于撤销),以及更多。如果没有持久性存储,则在每次重新部署IdentityServer时,令牌都将失效,并且我们无法一次承载多个安装(无负载平衡)。

  然后,我们可以通过添加到AddIdentityServer以下内容来添加对持久授权存储的支持:

  我们的迁移程序集是我们托管IdentityServer的项目。这对于不在您的托管项目中的DbContexts(在这种情况下它位于nuget包中)是必要的,并允许我们运行EF迁移。否则,我们将遇到一个例外情况,例如:

  要使用我们之前使用的配置以编程方式创建客户端和资源,请查看本文库中的InitializeDbTestData方法。

  目前我们需要创建自己的自定义实现,IdentityDbContext以覆盖构造函数以获取非泛型版本DbContextOptions。这是因为IdentityDbContext只有一个接受通用的构造函数DbContextOptions,当我们注册多个DbContexts时,会导致无效的操作异常。我已经就此问题提出了一个问题,希望我们能尽快跳过这一步。

  这就是将ASP.NET核心身份与IdentityServer 4连接起来所需的全部内容,但不幸的是,我们之前下载的Quickstart用户界面不再正常工作,因为它仍在使用TestUserStore。

  首先,我们需要更改构造函数以接受ASP.NET核心标识UserManager,而不是现有的TestUserStore。我们的构造函数现在应该如下所示:

本文链接:http://shawntierney.com/fangwenlingpai/572.html