├── .vscode └── settings.json ├── LICENSE ├── README.md ├── alipay.jpg ├── wechatpay.jpg ├── 欢迎来到IdentityServer4.md ├── 第一部分 简介 ├── 第01章 背景.md ├── 第02章 术语.md ├── 第03章 支持和规范.md ├── 第04章 打包和构建.md ├── 第05章 支持和咨询选项.md ├── 第06章 演示服务器和测试.md └── 第07章 贡献.md ├── 第三部分 主题 ├── 第18章 启动.md ├── 第19章 定义资源.md ├── 第20章 定义客户端.md ├── 第21章 登录.md ├── 第22章 使用外部身份提供商登录.md ├── 第23章 Windows身份验证.md ├── 第24章 退出.md ├── 第25章 退出外部身份提供商.md ├── 第26章 联合注销.md ├── 第27章 联合网关.md ├── 第28章 确认(Consent).md ├── 第29章 保护API.md ├── 第30章 部署.md ├── 第31章 日志.md ├── 第32章 事件.md ├── 第33章 密码学(Cryptography),密钥(Keys)和HTTPS.md ├── 第34章 授予类型.md ├── 第35章 秘密(secrets).md ├── 第36章 扩展授权.md ├── 第37章 资源所有者密码验证(Resource Owner Password Validation).md ├── 第38章 刷新令牌.md ├── 第39章 引用令牌.md ├── 第40章 自定义令牌请求验证和发布.md ├── 第41章 CORS.md ├── 第42章 发现(discovery).md ├── 第43章 添加更多API端点.md ├── 第44章 添加新协议.md └── 第45章 工具.md ├── 第二部分 快速入门 ├── 第08章 概述.md ├── 第09章 使用客户端凭据保护API.md ├── 第10章 使用密码保护API.md ├── 第11章 使用OpenID Connect添加用户身份验证.md ├── 第12章 添加对外部认证的支持.md ├── 第13章 切换到混合流并添加API访问.md ├── 第14章 添加JavaScript客户端.md ├── 第15章 使用EntityFramework Core进行配置和操作数据.md ├── 第16章 使用ASP.NET Core Identity.md └── 第17章 社区快速入门和模板.md ├── 第五部分 参考 ├── 第54章 身份资源.md ├── 第55章 API资源.md ├── 第56章 Client.md ├── 第57章 GrantValidationResult.md ├── 第58章 Profile Service.md ├── 第59章 IdentityServer交互服务.md ├── 第60章 设备流交互服务.md ├── 第61章 IdentityServer Options.md ├── 第62章 EntityFramework支持.md └── 第63章 ASP.NET Identity 支持.md ├── 第六部分 其它 ├── 第64章 学习.md ├── 第65章 博客帖子.md └── 第66章 视频.md └── 第四部分 端点 ├── 第46章 发现端点(Discovery Endpoint).md ├── 第47章 授权端点(Authorize Endpoint).md ├── 第48章 UserInfo端点(UserInfo Endpoint).md ├── 第49章 令牌端点(Token Endpoint).md ├── 第50章 设备授权端点(Device Authorization Endpoint).md ├── 第51章 内省端点(Introspection Endpoint).md ├── 第52章 撤销端点(Revocation Endpoint).md └── 第53章 结束会话端点(End Session Endpoint).md /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 thinksjay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 欢迎来到IdentityServer4 2 | 3 | **欢迎IdentityServer4** 4 | 5 |
6 | 7 |
8 | 9 | IdentityServer4是ASP\.NET Core 2的OpenID Connect和OAuth 2.0框架。 10 | 11 | > **警告** 12 | 从2020年10月1日起,我们成立了一家新的[公司](https://duendesoftware.com/) 。 所有新的主要功能工作都将在我们新的[组织](https://github.com/duendesoftware)中进行。 新的 Duende IdentityServer 可在 FOSS (RPL) 和商业许可下使用。 开发和测试始终免费。[联系](https://duendesoftware.com/contact)了解更多信息。 13 | IdentityServer4将在2022年11月之前进行错误修复和安全更新。 14 | 15 | > **注** 16 | 本文档涵盖了主分支上的最新版本。这可能尚未发布。使用左下角的版本选择器选择特定版本的文档。 17 | 18 | 它在您的应用程序中启用以下功能: 19 | 20 | **身份验证即服务** 21 | 所有应用程序(Web、原生、移动、服务)的集中登录逻辑和工作流。 22 | IdentityServer 是 OpenID Connect 的官方 [认证](https://openid.net/certification/) 实现。 23 | 24 | **单点登录/注销** 25 | 通过多种应用程序类型进行单点登录(和注销)。 26 | 27 | **API访问控制** 28 | 为各种类型的客户端发布 API 的访问令牌,例如 服务器到服务器、Web 应用程序、SPA 和原生/移动应用程序。 29 | 30 | **联合网关** 31 | 支持外部身份提供商,如 Azure Active Directory、Google、Facebook 等。 32 | 这使您的应用程序免受如何连接到这些外部提供商的详细信息的影响。 33 | 34 | **专注于定制** 35 | 最重要的部分 - IdentityServer 的许多方面都可以定制以满足 您 的需求。由于 IdentityServer 是一个框架,而不是盒装产品或 SaaS,您可以编写代码来调整系统,使其适合您的场景。 36 | 37 | **成熟的开源** 38 | IdentityServer使用允许的[Apache 2](https://www.apache.org/licenses/LICENSE-2.0)许可证,允许在其上构建商业产品。它也是[.NET Foundation](https://dotnetfoundation.org/)的一部分,它提供治理和法律支持。 39 | 40 | **免费和商业支持** 41 | 如果您需要帮助构建或运行您的身份平台,[请告诉我们](mailto:contact@identityserver.io) 。我们可以通过多种方式帮助您。 42 | -------------------------------------------------------------------------------- /alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinksjay/IdentityServer4/bd13dea2cef709ac08eef90493848290fef8a998/alipay.jpg -------------------------------------------------------------------------------- /wechatpay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinksjay/IdentityServer4/bd13dea2cef709ac08eef90493848290fef8a998/wechatpay.jpg -------------------------------------------------------------------------------- /欢迎来到IdentityServer4.md: -------------------------------------------------------------------------------- 1 | # 欢迎来到IdentityServer4 2 | 3 | **欢迎IdentityServer4** 4 | 5 |
6 | 7 |
8 | 9 | IdentityServer4是ASP\.NET Core 2的OpenID Connect和OAuth 2.0框架。 10 | 11 | 它可以在您的应用程序中启用以下功能: 12 | 13 | **身份验证服务** 14 | 适用于所有应用程序(Web,本机,移动设备,服务)的集中登录逻辑和工作流程。IdentityServer是OpenID Connect 的官方认证实现。 15 | 16 | **单点登录/注销** 17 | 在多种应用程序类型上单点登录(和退出)。 18 | 19 | **API的访问控制** 20 | 为各种类型的客户端发出API访问令牌,例如服务器到服务器,Web应用程序,SPA和本机/移动应用程序。 21 | 22 | **联合网关** 23 | 支持Azure Active Directory,Google,Facebook等外部身份提供商。这可以保护您的应用程序免受如何连接到这些外部提供商的详细信息的影响。 24 | 25 | **专注于定制** 26 | 最重要的部分 - IdentityServer的许多方面都可以根据您的需求进行定制。由于IdentityServer是一个框架而不是盒装产品或SaaS,因此您可以编写代码以使系统适应您的方案。 27 | 28 | **成熟的开源** 29 | IdentityServer使用允许的[Apache 2](https://www.apache.org/licenses/LICENSE-2.0)许可证,允许在其上构建商业产品。它也是[.NET Foundation](https://dotnetfoundation.org/)的一部分,它提供治理和法律支持。 30 | 31 | **免费和商业支持** 32 | 如果您需要帮助构建或运行您的身份平台,请告知我们。我们可以通过多种方式为您提供帮助。 -------------------------------------------------------------------------------- /第一部分 简介/第01章 背景.md: -------------------------------------------------------------------------------- 1 | # 第01章 背景 2 | 3 | 大多数现代应用程序或多或少看起来像这样: 4 |
5 | 6 |
7 | 8 | 最常见的互动是: 9 | 10 | * 浏览器与Web应用程序通信 11 | * Web应用程序与Web API进行通信(Web应用程序自身 或 代表用户 与 Web API 通信) 12 | * 基于浏览器的应用程序与Web API通信 13 | * 本地应用程序与Web API通信 14 | * 基于服务器的应用程序与Web API通信 15 | * Web API与Web API进行通信(WebAPI自身 或 代表用户与另一个WebAPI 通信) 16 | 17 | 通常,每个层(前端,中间层和后端)都必须保护资源并实现身份验证和授权 - 通常针对同一个用户存储。 18 | 19 | 将这些基本安全功能外包给安全令牌服务可防止在这些应用程序和端点之间复制该功能。 20 | 21 | 重构应用程序以支持安全令牌服务会产生以下体系结构和协议: 22 | 23 |
24 | 25 |
26 | 27 | 这种设计将安全问题分为两部分: 28 | 29 | ## 1.1 认证 30 | 当应用程序需要知道当前用户的身份时,需要进行身份验证。通常,这些应用程序代表该用户管理数据,并且需要确保该用户只能访问允许的数据。最常见的示例是(经典)Web应用程序 - 但是基于本地和JS的应用程序也需要身份验证。 31 | 32 | 最常见的身份验证协议是SAML2p,WS-Federation和OpenID Connect - SAML2p是最受欢迎和最广泛部署的。 33 | 34 | OpenID Connect是三者中的最新产品,但被认为是未来,因为它具有最大的现代应用潜力。它从一开始就为移动应用场景而构建,旨在实现API友好。 35 | 36 | ## 1.2 API访问 37 | 应用程序有两种基本方式与API通信 - 使用应用程序标识或委派用户身份。有时两种方法都需要结合起来。 38 | 39 | OAuth2是一种协议,允许应用程序从安全令牌服务请求访问令牌,并使用它们与API通信。此委派降低了客户端应用程序和API的复杂性,因为身份验证和授权可以集中。 40 | 41 | ## 1.3 OpenID Connect和OAuth 2.0 - 更好地结合在一起 42 | OpenID Connect和OAuth 2.0非常相似 - 事实上,OpenID Connect是OAuth 2.0之上的扩展。两个基本的安全问题,即身份验证和API访问,被合并为一个协议 - 通常只需一次往返安全令牌服务。 43 | 44 | 我们相信OpenID Connect和OAuth 2.0的结合是在可预见的未来保护现代应用程序的最佳方法。IdentityServer4是这两种协议的实现,经过高度优化,可以解决当今移动,本地和Web应用程序的典型安全问题。 45 | 46 | ## 1.4 IdentityServer4如何提供帮助 47 | IdentityServer是一个中间件,可将符合规范的OpenID Connect和OAuth 2.0端点添加到任意ASP.NET Core应用程序中。 48 | 49 | 通常,您构建(或复用)包含登录和注销页面的应用程序(或者 授权确认页),并且IdentityServer 中间件会将需要的协议添加到页面头部,这样一来客户端应用程序就能够使用这些标准协议跟它协商了。 50 | 51 |
52 | 53 |
54 | 55 | 你可以根据你的需要使用尽可能复杂的宿主应用程序。但是,为了保持受攻击面尽可能小, 我们一般建议你只将认证相关的UI包含进来。 56 | -------------------------------------------------------------------------------- /第一部分 简介/第02章 术语.md: -------------------------------------------------------------------------------- 1 | # 第02章 术语 2 | 3 | 规范、文档和对象模型等都使用特定的术语来表述。 4 | 5 |
6 | 7 |
8 | 9 | ## 2.1 IdentityServer 10 | IdentityServer是OpenID Connect提供程序 - 它实现OpenID Connect和OAuth 2.0协议。 11 | 12 | 对于相同的角色,不同的文献将使用不同的术语 —— 你可能也发现了安全令牌服务(Security Token Service),身份提供程序(Identity Provider),授权服务器(Authorization Server),IP-STS 等。 13 | 14 | 但它们完全相同:一种向客户发放安全令牌的软件。 15 | 16 | IdentityServer 包含一些职责和功能: 17 | 18 | * 保护你的资源 19 | * 使用本地帐户存储或外部身份提供程序对用户进行身份验证 20 | * 提供会话管理和单点登录(SSO) 21 | * 管理和验证客户端 22 | * 向客户端发放身份和访问令牌 23 | * 验证令牌 24 | 25 | ## 2.2 用户 26 | 用户是使用注册客户端访问资源的人。 27 | 28 | ## 2.3 客户端 29 | 客户端是从IdentityServer请求令牌的软件 - 用于验证用户(请求身份令牌)或访问资源(请求访问令牌)。客户端必须首先向IdentityServer注册,然后才能请求令牌。 30 | 31 | 客户端可以是Web应用程序、移动客户端或桌面应用程序、单页面应用程序(SPA,Single Page Application)、服务器进程等等。 32 | 33 | ## 2.4 资源 34 | 您希望使用IdentityServer保护资源 - 用户的身份数据或API。 35 | 36 | 每个资源都有一个唯一的名称 - 客户端使用此名称来指定他们希望访问哪些资源。 37 | 38 | **身份数据** 关于用户的身份信息(也称为声明),例如姓名或电子邮件地址。 39 | 40 | **API** API资源表示客户端要调用的功能 - 通常建模为Web API,但不一定。 41 | 42 | ## 2.5 身份令牌 43 | 身份令牌表示身份验证过程的结果。它至少包含用户的标识符(称为sub aka subject声明)以及有关用户如何以及何时进行身份验证的信息。它可以包含其他身份数据。 44 | 45 | ## 2.6 访问令牌 46 | 访问令牌允许访问API资源。客户端请求访问令牌并将其转发给API。访问令牌包含有关客户端和用户(如果存在)的信息。API使用该信息来授权访问其数据。 47 | -------------------------------------------------------------------------------- /第一部分 简介/第03章 支持和规范.md: -------------------------------------------------------------------------------- 1 | # 第03章 支持和规范 2 | 3 | IdentityServer实现以下规范: 4 | 5 | ## 3.1 OpenID Connect 6 | * OpenID Connect Core 1.0 ([规范](http://openid.net/specs/openid-connect-core-1_0.html)) 7 | * OpenID Connect Discovery 1.0 ([规范](http://openid.net/specs/openid-connect-discovery-1_0.html)) 8 | * OpenID Connect Session Management 1.0 - draft 28 ([规范](http://openid.net/specs/openid-connect-session-1_0.html)) 9 | * OpenID Connect Front-Channel Logout 1.0 - draft 02 ([规范](https://openid.net/specs/openid-connect-frontchannel-1_0.html)) 10 | * OpenID Connect Back-Channel Logout 1.0 - draft 04 ([规范](https://openid.net/specs/openid-connect-backchannel-1_0.html)) 11 | 12 | ## 3.2 OAuth 2.0 13 | * OAuth 2.0 ([RFC 6749](http://tools.ietf.org/html/rfc6749)) 14 | * OAuth 2.0 Bearer Token Usage ([RFC 6750](http://tools.ietf.org/html/rfc6750)) 15 | * OAuth 2.0 Multiple Response Types ([规范](http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)) 16 | * OAuth 2.0 Form Post Response Mode ([规范](http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html)) 17 | * OAuth 2.0 Token Revocation ([RFC 7009](https://tools.ietf.org/html/rfc7009)) 18 | * OAuth 2.0 Token Introspection ([RFC 7662](https://tools.ietf.org/html/rfc7662)) 19 | * Proof Key for Code Exchange ([RFC 7636](https://tools.ietf.org/html/rfc7636)) 20 | * JSON Web Tokens for Client Authentication ([RFC 7523](https://tools.ietf.org/html/rfc7523)) 21 | * OAuth 2.0 Device Flow for Browserless and Input Constrained Devices ([草稿](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-13)) 22 | -------------------------------------------------------------------------------- /第一部分 简介/第04章 打包和构建.md: -------------------------------------------------------------------------------- 1 | # 第04章 打包和构建 2 | 3 | IdentityServer由许多nuget包组成。 4 | 5 | ## 4.1 IdentityServer4 6 | [nuget](https://www.nuget.org/packages/IdentityServer4/) | [github](https://github.com/identityserver/IdentityServer4)上 7 | 8 | 包含核心IdentityServer对象模型,服务和中间件。仅包含对内存配置和用户存储的支持 - 但您可以通过配置插入对其他存储的支持。这是其他仓库和程序包相关的内容。 9 | 10 | ## 4.2 Quickstart UI 11 | [github](https://github.com/IdentityServer/IdentityServer4.Quickstart.UI)上 12 | 13 | 包含一个简单的入门UI,包括登录,注销和授权确认页面。 14 | 15 | ## 4.3 Access token validation handler 16 | [nuget](https://www.nuget.org/packages/IdentityServer4.AccessTokenValidation) | [github](https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation)上 17 | 18 | 用于验证API中令牌的ASP.NET Core身份验证处理程序。处理程序允许在同一API中支持JWT和引用令牌。 19 | 20 | ## 4.4 ASP\.NET Core Identity 21 | [nuget](https://www.nuget.org/packages/IdentityServer4.AspNetIdentity) | [github](https://github.com/IdentityServer/IdentityServer4.AspNetIdentity)上 22 | 23 | IdentityServer的ASP\.NET Core Identity集成包。此包提供了一个简单的配置API,可以为IdentityServer用户使用ASP\.NET Identity管理库。 24 | 25 | ## 4.5 EntityFramework Core 26 | [nuget](https://www.nuget.org/packages/IdentityServer4.EntityFramework) | [github](https://github.com/IdentityServer/IdentityServer4.EntityFramework)上 27 | 28 | IdentityServer 的 EntityFramework Core 仓储实现。此包为IdentityServer中的配置和操作存储提供EntityFramework实现。 29 | 30 | ## 4.6 Dev builds 31 | 此外,我们将开发/临时构建发布到MyGet。可以添加以下程序包源到你的 Visual Studio 中: 32 | 33 | 34 | -------------------------------------------------------------------------------- /第一部分 简介/第05章 支持和咨询选项.md: -------------------------------------------------------------------------------- 1 | # 第05章 支持和咨询选项 2 | 3 | 我们为IdentityServer提供了多种免费和商业支持和咨询选项。 4 | 5 | ## 5.1 免费支持 6 | 免费支持是基于社区的,并使用公共论坛 7 | 8 | ### 5.1.1 StackOverflow 9 | StackOverflow 社区里日益增多的 IdentityServer 用户在监视着上面的问题。如果时间允许,我们也会试着尽可能多地回答这些问题。 10 | 11 | 您可以使用此Feed订阅所有IdentityServer4相关问题: 12 | 13 | 14 | 15 | 在提出新问题时请使用`IdentityServer4`标签 16 | 17 | ### 5.1.2 Gitter 18 | 19 | 您可以在我们的Gitter聊天室中与其他IdentityServer4用户聊天: 20 | 21 | 22 | 23 | ### 5.1.3 报告Bug 24 | 如果您认为自己发现了Bug或意外行为,请在Github 问题跟踪器上打开一个问题。我们会尽快回复您。请理解我们也有日常工作,可能太忙而无法立即回复。 25 | 26 | 你还可以在发布问题之前查看一下[贡献指南](https://github.com/IdentityServer/IdentityServer4/blob/dev/CONTRIBUTING.md)。 27 | 28 | ## 5.2 商业支持 29 | 我们正在围绕身份和访问控制架构进行咨询,指导和定制软件开发,特别是IdentityServer。请与我们[取得联系](mailto:identity@leastprivilege.com)以讨论可能的选项。 30 | 31 | ### 5.2.1 培训 32 | 我们经常围绕现代应用的身份和访问控制进行研讨会。在[这里](https://identityserver.io/training)查看议程和即将公布的日期 。我们也可以在贵公司私下进行培训。 联系我们以进行现场培训。 33 | 34 | ### 5.2.3 Admin UI,Identity Express和SAML2p支持 35 | 我们的合作伙伴提供了几种商业附加产品,请访问。 36 | -------------------------------------------------------------------------------- /第一部分 简介/第06章 演示服务器和测试.md: -------------------------------------------------------------------------------- 1 | # 第06章 演示服务器和测试 2 | 3 | 您可以使用您喜欢的客户端库尝试IdentityServer4。我们在[demo.identityserver.io](https://demo.identityserver.io/)上有一个测试实例。在主页面上,您可以找到有关如何配置客户端以及如何调用API的说明。 4 | 5 | 此外,我们还有一个repo,可以运行各种IdentityServer和Web API组合(IdentityServer 3和4,ASP.NET Core和Katana)。我们使用此测试工具确保所有排列都有效。您可以通过克隆此[repo](https://github.com/IdentityServer/CrossVersionIntegrationTests)来进行测试。 6 | -------------------------------------------------------------------------------- /第一部分 简介/第07章 贡献.md: -------------------------------------------------------------------------------- 1 | # 第07章 贡献 2 | 3 | 我们对社区贡献非常开放,但您应该遵循一些指导原则,以便我们可以毫不费力地处理这个问题。 4 | 5 | ## 7.1 如何贡献? 6 | 最简单的方法是打开一个问题并开始讨论。然后我们可以决定是否以及如何实现功能或更改。如果您应提交包含更改代码的pull请求,请从描述开始,仅进行最小的更改并提供涵盖这些更改的测试。 7 | 8 | 首先阅读:[成为一名优秀的开源公民](https://hackernoon.com/being-a-good-open-source-citizen-9060d0ab9732#.x3hocgw85) 9 | 10 | ## 7.2 一般反馈和讨论? 11 | 请在 [核心仓库问题跟踪](https://github.com/IdentityServer/IdentityServer4/issues) 上开启一个讨论。 12 | 13 | ## 7.3 平台 14 | IdentityServer是针对ASP.NET Core 2构建的,可在.NET Framework 4.6.1(及更高版本)和.NET Core 2(及更高版本)上运行。 15 | 16 | ## 7.4 错误和功能请求? 17 | 请在相应的GitHub仓库中记录新问题: 18 | 19 | * [Core(核心)](https://github.com/IdentityServer/IdentityServer4) 20 | * [Samples(示例)](https://github.com/IdentityServer/IdentityServer4.Samples) 21 | * [AccessTokenValidation(访问令牌验证)](https://github.com/IdentityServer/IdentityServer4.AccessTokenValidation) 22 | 23 | ## 7.5 其他讨论 24 | 25 | 26 | ## 7.6 贡献代码和内容 27 | 在您提供任何代码或内容之前,您需要签署贡献者许可协议。这是一个自动化过程,将在您打开拉取请求后启动。 28 | 29 | > **注意** 30 | > 我们只接受开发分支的PR。 31 | 32 | ## 7.7 贡献项目 33 | 如果您启动贡献项目(例如,支持Database X或Configuration Store Y),我们非常感谢。告诉我们,我们可以在我们的文档中发推文和链接。 34 | 35 | 我们通常不会要你们贡献的库的所有权,为了支持核心项目,我们已经很忙了。 36 | 37 | **命名约定** 38 | 截至2017年10月,IdentityServer4。* nuget名称空间保留给我们的软件包。请使用以下命名约定: 39 | 40 | YourProjectName.IdentityServer4 41 | 42 | 要么 43 | 44 | IdentityServer4.Contrib.YourProjectName 45 | -------------------------------------------------------------------------------- /第三部分 主题/第18章 启动.md: -------------------------------------------------------------------------------- 1 | # 第18章 启动 2 | IdentityServer是中间件和服务的组合。所有配置都在您的启动类中完成。 3 | 4 | ## 18.1 配置服务 5 | 您可以通过调用以下方法将IdentityServer服务添加到DI系统: 6 | ``` C# 7 | public void ConfigureServices(IServiceCollection services) 8 | { 9 | var builder = services.AddIdentityServer(); 10 | } 11 | ``` 12 | 13 | 您可以选择将选项传入此调用。有关选项的详细信息,请参见[此](https://github.com/thinksjay/IdentityServer4/blob/master/%E5%8F%82%E8%80%83/%E7%AC%AC61%E7%AB%A0%20IdentityServer%20Options.md) 14 | 15 | 这将返回一个构建器对象,该构建器对象又有许多方便的方法来连接其他服务。 16 | 17 | ## 18.2 密钥材料 18 | * **`AddSigningCredential`** 19 | 添加签名密钥服务,该服务为各种令牌创建/验证服务提供指定的密钥材料。您可以从证书存储中传入证书的`X509Certificate2`, `SigningCredential`或引用。 20 | 21 | * **`AddDeveloperSigningCredential`** 22 | 在启动时创建临时密钥材料。当您没有要使用的证书时,这仅适用于dev。生成的密钥将保留到文件系统,以便在服务器重新启动之间保持稳定(可以通过传递禁用false)。这解决了客户端/api元数据缓存在开发期间不同步时的问题。 23 | 24 | * **`AddValidationKey`** 25 | 添加用于验证令牌的密钥。它们将由内部令牌验证器使用,并将显示在发现文档中。您可以从证书存储中传入证书的 X509Certificate2`,`SigningCredential`或引用。这对于关键翻转场景非常有用。 26 | 27 | ## 18.3 内存配置存储 28 | 各种“内存中”配置API允许从内存中的配置对象列表配置IdentityServer。这些“内存中”集合可以在宿主应用程序中进行硬编码,也可以从配置文件或数据库动态加载。但是,通过设计,这些集合仅在托管应用程序启动时创建。 29 | 30 | 这些配置API的使用旨在用于原型设计,开发和/或测试时,在运行时不需要为配置数据动态查询数据库。如果配置很少更改,则此配置模板也可能适用于生产方案,或者如果必须更改值,则要求重新启动应用程序并不方便。 31 | 32 | * **`AddInMemoryClients`** 33 | 基于配置对象的内存中集合的注册IClientStore和ICorsPolicyService实现Client。 34 | 35 | * **`AddInMemoryIdentityResources`** 36 | IResourceStore根据IdentityResource配置对象的内存中集合注册实现。 37 | 38 | * **`AddInMemoryApiResources`** 39 | IResourceStore根据ApiResource配置对象的内存中集合注册实现。 40 | 41 | ## 18.4 测试商店 42 | 该TestUser是用户类,他们的凭据和声明在IdentityServer中。使用TestUser类似于“内存”存储的,因为它用于原型设计,开发或测试。TestUser在生产中不推荐使用。 43 | 44 | * **`AddTestUsers`** 45 | `TestUserStore`基于`TestUser`对象集合的注册。 `TestUserStore`由默认的快速入门UI使用。还注册实现`IProfileService`和`IResourceOwnerPasswordValidator`。 46 | ## 18.5 添加服务 47 | * **`AddExtensionGrantValidator`** 48 | 添加`IExtensionGrantValidator`实现以用于扩展授权。 49 | 50 | * **`AddSecretParser`** 51 | 添加ISecretParser用于解析客户端或API资源凭据的实现。 52 | 53 | * **`AddSecretValidator`** 54 | 添加`ISecretValidator`用于针对凭证存储验证客户端或API资源凭证的实现。 55 | 56 | * **`AddResourceOwnerValidator`** 57 | 添加`IResourceOwnerPasswordValidator`用于验证资源所有者密码凭据授予类型的用户凭据的实现。 58 | 59 | * **`AddProfileService`** 60 | 添加`IProfileService`用于连接到自定义用户配置文件存储的实现。的`DefaultProfileService`类提供了依赖于验证cookie作为权利要求中的用于在令牌发行的唯一来源的默认实现。 61 | 62 | * **`AddAuthorizeInteractionResponseGenerator`** 63 | 添加`IAuthorizeInteractionResponseGenerator`实现以在授权端点处定制逻辑,以便在必须向用户显示错误,登录,同意或任何其他自定义页面的UI时。本`AuthorizeInteractionResponseGenerator`类提供了一个默认的实现,因此考虑从这个现有的类派生如果需要增强现有的行为。 64 | 65 | * **`AddCustomAuthorizeRequestValidator`** 66 | 添加`ICustomAuthorizeRequestValidator`实现以在授权端点处自定义请求参数验证。 67 | 68 | * **`AddCustomTokenRequestValidator`** 69 | 添加`ICustomTokenRequestValidator`实现以在令牌端点处自定义请求参数验证。 70 | 71 | * **`AddRedirectUriValidator`** 72 | 添加`IRedirectUriValidator`实现以自定义重定向URI验证。 73 | 74 | * **`AddAppAuthRedirectUriValidator`** 75 | 添加一个“AppAuth”(适用于Native Apps的OAuth 2.0)兼容的重定向URI验证器(进行严格验证,但也允许带有随机端口的http://127.0.0.1)。 76 | 77 | * **`AddJwtBearerClientAuthentication`** 78 | 使用JWT承载断言添加对客户端身份验证的支持。 79 | 80 | ## 18.6 缓存 81 | IdentityServer经常使用客户端和资源配置数据。如果从数据库或其他外部存储加载此数据,则频繁重新加载相同数据可能会很昂贵。 82 | 83 | * **`AddInMemoryCaching`** 84 | 要使用下面描述的任何缓存,`ICache`必须在DI中注册实现。此API注册了`ICache`基于ASP.NET Core的默认内存实现`MemoryCache`。 85 | 86 | * **`AddClientStoreCache`** 87 | 注册一个`IClientStore`装饰器实现,它将维护`Client`配置对象的内存缓存。缓存持续时间可在``Caching配置选项上配置`IdentityServerOptions`。 88 | 89 | * **`AddResourceStoreCache`** 90 | 注册一个`IResourceStore`装饰器实现,它将维护内存缓存`IdentityResource`和`ApiResource`配置对象。缓存持续时间可在`Caching`配置选项上配置`IdentityServerOptions`。 91 | 92 | * **`AddCorsPolicyCache`** 93 | 注册`ICorsPolicyService`装饰器实现,该实现将维护**CORS**策略服务评估结果的内存缓存。缓存持续时间可在`Caching`配置选项上配置`IdentityServerOptions`。 94 | 95 | 可以进一步自定义缓存: 96 | 97 | 默认缓存依赖于`ICache`实现。如果要自定义特定配置对象的缓存行为,可以在依赖项注入系统中替换此实现。 98 | 99 | `ICache`本身的默认实现依赖于.NET提供的`IMemoryCache`接口(和`MemoryCache`实现)。如果要自定义内存中缓存行为,可以替换`IMemoryCache`依赖项注入系统中的实现。 100 | 101 | ## 18.7 配置管道 102 | 您需要通过调用以下方法将IdentityServer添加到管道: 103 | 104 | ``` C# 105 | public void Configure(IApplicationBuilder app) 106 | { 107 | app.UseIdentityServer(); 108 | } 109 | ``` 110 | 111 | > **注意** 112 | `UseIdentityServer`包括`UseAuthentication`,所以没有必要同时使用。 113 | 114 | 中间件没有其他配置。 115 | 116 | 请注意,顺序在管道中很重要。例如,您需要在实现登录页面的UI框架之前添加IdentitySever。 117 | -------------------------------------------------------------------------------- /第三部分 主题/第19章 定义资源.md: -------------------------------------------------------------------------------- 1 | # 第19章 定义资源 2 | 您通常在系统中定义的第一件事是您要保护的资源。这可能是您的用户的身份信息,如个人资料数据或电子邮件地址,或访问API。 3 | 4 | > **注意** 5 | 您可以使用C#对象模型定义资源 - 或从数据存储加载它们。`IResourceStore`的一个实现处理这些低级细节。对于本文档,我们使用内存实现。 6 | 7 | # 19.1 定义身份资源 8 | 身份资源是用户的用户ID,名称或电子邮件地址等数据。标识资源具有唯一名称,您可以为其分配任意声明类型。然后,这些声明将包含在用户的身份令牌中。客户端将使用该`scope`参数来请求访问标识资源。 9 | 10 | OpenID Connect规范指定了几个[标准](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims)身份资源。最低要求是,您为用户发送唯一ID提供支持 - 也称为主题ID。这是通过公开名为的标准身份资源来完成的`openid`: 11 | 12 | ``` C# 13 | public static IEnumerable GetIdentityResources() 14 | { 15 | return new List 16 | { 17 | new IdentityResources.OpenId() 18 | }; 19 | } 20 | ``` 21 | 22 | 该IdentityResources类支持的规范(OpenID,电子邮件,个人资料,电话和地址)中定义的所有范围。如果要全部支持它们,可以将它们添加到支持的身份资源列表中: 23 | 24 | ``` C# 25 | public static IEnumerable GetIdentityResources() 26 | { 27 | return new List 28 | { 29 | new IdentityResources.OpenId(), 30 | new IdentityResources.Email(), 31 | new IdentityResources.Profile(), 32 | new IdentityResources.Phone(), 33 | new IdentityResources.Address() 34 | }; 35 | } 36 | ``` 37 | 38 | ## 19.2 定义自定义标识资源 39 | 您还可以定义自定义标识资源。创建一个新的*IdentityResource*类,为其指定名称和可选的显示名称和描述,并定义在请求此资源时应将哪些用户声明包含在标识令牌中: 40 | 41 | ``` C# 42 | public static IEnumerable GetIdentityResources() 43 | { 44 | var customProfile = new IdentityResource( 45 | name: "custom.profile", 46 | displayName: "Custom profile", 47 | claimTypes: new[] { "name", "email", "status" }); 48 | 49 | return new List 50 | { 51 | new IdentityResources.OpenId(), 52 | new IdentityResources.Profile(), 53 | customProfile 54 | }; 55 | } 56 | ``` 57 | 58 | 有关身份资源设置的更多信息,请[参考](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC54%E7%AB%A0%20%E8%BA%AB%E4%BB%BD%E8%B5%84%E6%BA%90.md)。 59 | 60 | ## 19.2 定义API资源 61 | 要允许客户端请求API的访问令牌,您需要定义API资源,例如: 62 | 63 | 要获取API的访问权限,您还需要将它们注册为范围。这次范围类型是*Resource*类型: 64 | 65 | ``` C# 66 | public static IEnumerable GetApis() 67 | { 68 | return new[] 69 | { 70 | // simple API with a single scope (in this case the scope name is the same as the api name) 71 | new ApiResource("api1", "Some API 1"), 72 | 73 | // expanded version if more control is needed 74 | new ApiResource 75 | { 76 | Name = "api2", 77 | 78 | // secret for using introspection endpoint 79 | ApiSecrets = 80 | { 81 | new Secret("secret".Sha256()) 82 | }, 83 | 84 | // include the following using claims in access token (in addition to subject id) 85 | UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Email }, 86 | 87 | // this API defines two scopes 88 | Scopes = 89 | { 90 | new Scope() 91 | { 92 | Name = "api2.full_access", 93 | DisplayName = "Full access to API 2", 94 | }, 95 | new Scope 96 | { 97 | Name = "api2.read_only", 98 | DisplayName = "Read only access to API 2" 99 | } 100 | } 101 | } 102 | }; 103 | } 104 | ``` 105 | 106 | 有关API资源设置的更多信息,请[参考](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC55%E7%AB%A0%20%20API%E8%B5%84%E6%BA%90.md)。 107 | 108 | > **注意** 109 | 由资源定义的用户声明由[IProfileService](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC58%E7%AB%A0%20Profile%20Service.md)扩展点加载。 -------------------------------------------------------------------------------- /第三部分 主题/第20章 定义客户端.md: -------------------------------------------------------------------------------- 1 | # 第20章 定义客户端 2 | 客户端表示可以从您的身份服务器请求令牌的应用程序。 3 | 4 | 详细信息各不相同,但您通常会为客户端定义以下常用设置: 5 | 6 | * 唯一的客户ID 7 | * 如果需要的秘密 8 | * 允许与令牌服务的交互(称为授权类型) 9 | * 身份和/或访问令牌发送到的网络位置(称为重定向URI) 10 | * 允许客户端访问的范围列表(也称为资源) 11 | 12 | > **注意** 13 | 在运行时,通过实现来检索客户端`IClientStore`。这允许从任意数据源(如配置文件或数据库)加载它们。对于本文档,我们将使用客户端存储的内存版本。您可以通过`ConfigureServices`的`AddInMemoryClientsextensions`方法连接内存存储。 14 | 15 | ## 20.1 定义服务器到服务器通信的客户端 16 | 在这种情况下,没有交互式用户 - 服务(aka client)想要与API(aka scope)进行通信: 17 | 18 | ``` C# 19 | public class Clients 20 | { 21 | public static IEnumerable Get() 22 | { 23 | return new List 24 | { 25 | new Client 26 | { 27 | ClientId = "service.client", 28 | ClientSecrets = { new Secret("secret".Sha256()) }, 29 | 30 | AllowedGrantTypes = GrantTypes.ClientCredentials, 31 | AllowedScopes = { "api1", "api2.read_only" } 32 | } 33 | }; 34 | } 35 | } 36 | ``` 37 | 38 | ## 20.2 定义基于浏览器的JavaScript客户端(例如SPA)以进行用户身份验证和委托访问及API 39 | 40 | 此客户端使用所谓的隐式流来从JavaScript请求身份和访问令牌: 41 | 42 | ``` C# 43 | var jsClient = new Client 44 | { 45 | ClientId = "js", 46 | ClientName = "JavaScript Client", 47 | ClientUri = "http://identityserver.io", 48 | 49 | AllowedGrantTypes = GrantTypes.Implicit, 50 | AllowAccessTokensViaBrowser = true, 51 | 52 | RedirectUris = { "http://localhost:7017/index.html" }, 53 | PostLogoutRedirectUris = { "http://localhost:7017/index.html" }, 54 | AllowedCorsOrigins = { "http://localhost:7017" }, 55 | 56 | AllowedScopes = 57 | { 58 | IdentityServerConstants.StandardScopes.OpenId, 59 | IdentityServerConstants.StandardScopes.Profile, 60 | IdentityServerConstants.StandardScopes.Email, 61 | 62 | "api1", "api2.read_only" 63 | } 64 | }; 65 | ``` 66 | 67 | ## 20.3 定义服务器端Web应用程序(例如MVC)以使用身份验证和委托API访问 68 | 交互式服务器端(或本地桌面/移动)应用程序使用混合流。此流程为您提供最佳安全性,因为访问令牌仅通过反向通道调用传输(并允许您访问刷新令牌): 69 | 70 | ``` C# 71 | var mvcClient = new Client 72 | { 73 | ClientId = "mvc", 74 | ClientName = "MVC Client", 75 | ClientUri = "http://identityserver.io", 76 | 77 | AllowedGrantTypes = GrantTypes.Hybrid, 78 | AllowOfflineAccess = true, 79 | ClientSecrets = { new Secret("secret".Sha256()) }, 80 | 81 | RedirectUris = { "http://localhost:21402/signin-oidc" }, 82 | PostLogoutRedirectUris = { "http://localhost:21402/" }, 83 | FrontChannelLogoutUri = "http://localhost:21402/signout-oidc", 84 | 85 | AllowedScopes = 86 | { 87 | IdentityServerConstants.StandardScopes.OpenId, 88 | IdentityServerConstants.StandardScopes.Profile, 89 | IdentityServerConstants.StandardScopes.Email, 90 | 91 | "api1", "api2.read_only" 92 | }, 93 | }; 94 | ``` 95 | 96 | ## 20.4 在appsettings.json中定义客户端 97 | 该`AddInMemoryClients`扩展方法也支持从ASP.NET Core配置文件中添加客户端。这允许您直接从*appsettings.json*文件定义静态客户端: 98 | 99 | ``` json 100 | "IdentityServer": { 101 | "IssuerUri": "urn:sso.company.com", 102 | "Clients": [ 103 | { 104 | "Enabled": true, 105 | "ClientId": "local-dev", 106 | "ClientName": "Local Development", 107 | "ClientSecrets": [ { "Value": "" } ], 108 | "AllowedGrantTypes": [ "implicit" ], 109 | "AllowedScopes": [ "openid", "profile" ], 110 | "RedirectUris": [ "https://localhost:5001/signin-oidc" ], 111 | "RequireConsent": false 112 | } 113 | ] 114 | } 115 | ``` 116 | 117 | 然后将配置部分传递给`AddInMemoryClients`方法: 118 | 119 | ``` C# 120 | AddInMemoryClients(configuration.GetSection("IdentityServer:Clients")) 121 | ``` -------------------------------------------------------------------------------- /第三部分 主题/第21章 登录.md: -------------------------------------------------------------------------------- 1 | # 第21章 登录 2 | 为了使IdentityServer能够代表用户发出令牌,该用户必须登录IdentityServer。 3 | 4 | ## 21.1 Cookie身份验证 5 | 使用由ASP\.NET Core中的cookie身份验证处理程序管理的cookie来跟踪身份验证。 6 | 7 | IdentityServer注册了两个cookie处理程序(一个用于身份验证会话,另一个用于临时外部cookie)。默认情况下使用它们,如果要手动引用它们,可以从`IdentityServerConstants`类(`DefaultCookieAuthenticationScheme`和`ExternalCookieAuthenticationScheme`)中获取它们的名称。 8 | 9 | 我们只公开这些cookie的基本设置(到期和滑动),如果您需要更多控制,您可以注册自己的cookie处理程序。当使用ASP\.NET Core中的`AddAuthentication`时,IdentityServer使用与`AuthenticationOptions`上配置的`DefaultAuthenticateScheme`匹配的cookie处理程序。 10 | 11 | ## 21.2 覆盖cookie处理程序配置 12 | 如果您希望使用自己的cookie身份验证处理程序,则必须自己配置它。这必须在`ConfigureServices` DI(`AddIdentityServer`)中注册IdentityServer之后完成。例如: 13 | 14 | ``` C# 15 | services.AddIdentityServer() 16 | .AddInMemoryClients(Clients.Get()) 17 | .AddInMemoryIdentityResources(Resources.GetIdentityResources()) 18 | .AddInMemoryApiResources(Resources.GetApiResources()) 19 | .AddDeveloperSigningCredential() 20 | .AddTestUsers(TestUsers.Users); 21 | 22 | services.AddAuthentication("MyCookie") 23 | .AddCookie("MyCookie", options => 24 | { 25 | options.ExpireTimeSpan = ...; 26 | }); 27 | ``` 28 | 29 | > **注意** 30 | IdentityServer在内部使用自定义方案(通过常量`IdentityServerConstants.DefaultCookieAuthenticationScheme`)调用`AddAuthentication`和`AddCookie`,因此要覆盖它们,您必须在`AddIdentityServer`之后进行相同的调用。 31 | 32 | ## 21.3 登录用户界面和身份管理系统 33 | IdentityServer不为用户身份验证提供任何用户界面或用户数据库。 这些是您希望自己提供或开发的东西。 34 | 35 | 如果您需要基本UI的起点(登录,注销,同意和管理授权),您可以使用我们的[快速入门UI](https://github.com/IdentityServer/IdentityServer4.Quickstart.UI)。 36 | 37 | 快速入门UI针对内存数据库对用户进行身份验证。 您可以通过访问真实用户存储来替换这些位。 我们有[使用ASP.NET Identity](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86%20%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/%E7%AC%AC16%E7%AB%A0%20%E4%BD%BF%E7%94%A8ASP.NET%20Core%20Identity.md)的示例。 38 | 39 | ## 21.4 登录工作流程 40 | 当IdentityServer在授权端点收到请求且未对用户进行身份验证时,将用户重定向到已配置的登录页面。 您必须通过[选项](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC61%E7%AB%A0%20IdentityServer%20Options.md)上的`UserInteraction`设置(默认`/account/login`)通知IdentityServer登录页面的路径。 将传递`returnUrl`参数,通知您的登录页面,一旦登录完成,应该重定向用户。 41 | 42 |
43 | 44 |
45 | 46 | 47 | > **注意** 48 | 通过`returnUrl`参数注意[open-redirect attacks](https://en.wikipedia.org/wiki/URL_redirection#Security_issues)攻击。 您应该验证`returnUrl`是否引用了众所周知的位置。 请参阅API的[交互服务](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC59%E7%AB%A0%20IdentityServer%E4%BA%A4%E4%BA%92%E6%9C%8D%E5%8A%A1.md)以验证`returnUrl`参数。 49 | 50 | ## 21.5 登录上下文 51 | 在您的登录页面上,您可能需要有关请求上下文的信息,以便自定义登录体验(例如客户端,提示参数,IdP提示或其他内容)。这可以通过[交互服务](https://github.com/thinksjay/IdentityServer4/blob/master/%E7%AC%AC%E4%BA%94%E9%83%A8%E5%88%86%20%E5%8F%82%E8%80%83/%E7%AC%AC59%E7%AB%A0%20IdentityServer%E4%BA%A4%E4%BA%92%E6%9C%8D%E5%8A%A1.md)上的`GetAuthorizationContextAsync` API获得。 52 | 53 | ## 21。6 发行cookie和声明 54 | ASP\.NET Core上的`HttpContext`上有与身份验证相关的扩展方法,用于发出身份验证cookie并对用户进行签名。使用的身份验证方案必须与您正在使用的cookie处理程序匹配(请参见上文)。 55 | 56 | 当您签署用户时,您必须至少发出一个`sub`和一个`name`声明。 IdentityServer还在`HttpContext`上提供了一些`SignInAsync`扩展方法,以使这更方便。 57 | 58 | 您还可以选择发出`idp`声明(针对身份提供者名称),`amr`声明(针对所使用的身份验证方法)和/或`auth_time`声明(针对用户身份验证的纪元时间)。如果您不提供这些,IdentityServer将提供默认值。 -------------------------------------------------------------------------------- /第三部分 主题/第22章 使用外部身份提供商登录.md: -------------------------------------------------------------------------------- 1 | # 第22章 使用外部身份提供商登录 2 | ASP\.NET Core有一种灵活的方式来处理外部身份验证。这涉及几个步骤。 3 | 4 | > **注意** 5 | 如果您使用的是ASP\.NET Identity,则会隐藏许多基础技术细节。建议您还阅读Microsoft [文档](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/)并执行ASP\.NET Identity [快速入门](https://github.com/thinksjay/IdentityServer4/blob/master/%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/%E7%AC%AC16%E7%AB%A0%20%E4%BD%BF%E7%94%A8ASP.NET%20Core%20Identity.md)。 6 | 7 | ## 22.1 为外部提供者添加身份验证处理程序 8 | 与外部提供者通信所需的协议实现封装在身份验证处理程序中。一些提供商使用专有协议(例如Facebook等社交提供商),有些提供商使用标准协议,例如OpenID Connect,WS-Federation或SAML2p。 9 | 10 | 有关添加外部身份验证和配置它的分步说明,请参阅此[快速入门](https://github.com/thinksjay/IdentityServer4/blob/master/%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/%E7%AC%AC12%E7%AB%A0%20%E6%B7%BB%E5%8A%A0%E5%AF%B9%E5%A4%96%E9%83%A8%E8%AE%A4%E8%AF%81%E7%9A%84%E6%94%AF%E6%8C%81.md)。 11 | 12 | ## 22.2 cookies的作用 13 | 调用外部身份验证处理程序的一个选项`SignInScheme`,例如: 14 | 15 | ``` C# 16 | services.AddAuthentication() 17 | .AddGoogle("Google", options => 18 | { 19 | options.SignInScheme = "scheme of cookie handler to use"; 20 | 21 | options.ClientId = "..."; 22 | options.ClientSecret = "..."; 23 | }) 24 | ``` 25 | 26 | 登录方案指定将临时存储外部认证结果的cookie处理程序的名称,例如由外部提供者发送的声明。这是必要的,因为在完成外部身份验证过程之前通常会涉及一些重定向。 27 | 28 | 鉴于这是一种常见做法,IdentityServer专门为此外部提供程序工作流注册cookie处理程序。该方案通过`IdentityServerConstants.ExternalCookieAuthenticationScheme`常数表示。如果您要使用我们的外部cookie处理程序,那么对于`SignInScheme`上面的内容,您将赋值为`IdentityServerConstants.ExternalCookieAuthenticationScheme`常量: 29 | 30 | ``` C# 31 | services.AddAuthentication() 32 | .AddGoogle("Google", options => 33 | { 34 | options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; 35 | 36 | options.ClientId = "..."; 37 | options.ClientSecret = "..."; 38 | }) 39 | ``` 40 | 41 | 您也可以注册自己的自定义cookie处理程序,如下所示: 42 | 43 | ``` C# 44 | services.AddAuthentication() 45 | .AddCookie("YourCustomScheme") 46 | .AddGoogle("Google", options => 47 | { 48 | options.SignInScheme = "YourCustomScheme"; 49 | 50 | options.ClientId = "..."; 51 | options.ClientSecret = "..."; 52 | }) 53 | ``` 54 | 55 | > **注意** 56 | 对于特殊情况,您还可以将外部cookie机制短路并将外部用户直接转发到主cookie处理程序。这通常涉及处理外部处理程序上的事件,以确保您从外部标识源执行正确的声明转换。 57 | 58 | ## 22.3 触发认证处理程序 59 | 您可以通过(或使用MVC`ChallengeResult` )`HttpContext`上的`ChallengeAsync`扩展方法调用外部认证处理程序。 60 | 61 | 您通常希望将一些选项传递给挑战操作,例如回调页面的路径和簿记提供者的名称,例如: 62 | 63 | ``` C# 64 | var callbackUrl = Url.Action("ExternalLoginCallback"); 65 | 66 | var props = new AuthenticationProperties 67 | { 68 | RedirectUri = callbackUrl, 69 | Items = 70 | { 71 | { "scheme", provider }, 72 | { "returnUrl", returnUrl } 73 | } 74 | }; 75 | 76 | return Challenge(provider, props); 77 | ``` 78 | 79 | ## 22.4 处理回调并签署用户 80 | 在回调页面上,您的典型任务是: 81 | 82 | * 检查外部提供商返回的身份。 83 | * 决定如何处理该用户。如果这是新用户或返回用户,则可能会有所不同。 84 | * 新用户在被允许之前可能需要额外的步骤和UI。 85 | * 可能会创建一个链接到外部提供程序的新内部用户帐户。 86 | * 存储您要保留的外部声明。 87 | * 删除临时cookie 88 | * 登录用户 89 | 90 | ### 22.4.1 检查外部身份: 91 | ``` C# 92 | // read external identity from the temporary cookie 93 | var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); 94 | if (result?.Succeeded != true) 95 | { 96 | throw new Exception("External authentication error"); 97 | } 98 | 99 | // retrieve claims of the external user 100 | var externalUser = result.Principal; 101 | if (externalUser == null) 102 | { 103 | throw new Exception("External authentication error"); 104 | } 105 | 106 | // retrieve claims of the external user 107 | var claims = externalUser.Claims.ToList(); 108 | 109 | // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier 110 | // depending on the external provider, some other claim type might be used 111 | var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); 112 | if (userIdClaim == null) 113 | { 114 | userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); 115 | } 116 | if (userIdClaim == null) 117 | { 118 | throw new Exception("Unknown userid"); 119 | } 120 | 121 | var externalUserId = userIdClaim.Value; 122 | var externalProvider = userIdClaim.Issuer; 123 | 124 | // use externalProvider and externalUserId to find your user, or provision a new user 125 | ``` 126 | 127 | ### 22.4.2 清理和登录: 128 | 129 | ``` C# 130 | // issue authentication cookie for user 131 | await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, props, additionalClaims.ToArray()); 132 | 133 | // delete temporary cookie used during external authentication 134 | await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); 135 | 136 | // validate return URL and redirect back to authorization endpoint or a local page 137 | if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl)) 138 | { 139 | return Redirect(returnUrl); 140 | } 141 | 142 | return Redirect("~/"); 143 | ``` 144 | 145 | ## 22.5 状态,URL长度和ISecureDataFormat 146 | 重定向到外部提供程序进行登录时,必须经常从客户端应用程序进行往返状态。这意味着在离开客户端之前捕获状态并保留状态,直到用户返回到客户端应用程序。许多协议(包括OpenID Connect)允许将某种状态作为参数传递作为请求的一部分,并且身份提供者将在响应上返回该状态。ASP\.NET Core提供的OpenID Connect身份验证处理程序利用协议的这一功能,即它实现上述`returnUrl`功能的方式。 147 | 148 | 在请求参数中存储状态的问题是请求URL可能变得太大(超过2000个字符的公共限制)。OpenID Connect身份验证处理程序确实提供了一个可扩展点,用于在服务器中而不是在请求URL中存储状态。您可以通过`ISecureDataFormat`在[OpenIdConnectOptions](https://github.com/aspnet/AspNetCore/blob/master/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs#L249)上实现和配置它来自行实现。 149 | 150 | 幸运的是,IdentityServer为您提供了一个实现,由`IDistributedCache` DI容器中注册的实现(例如标准`MemoryDistributedCache`)支持。要使用IdentityServer提供的安全数据格式实现,只需在配置DI时调用`IServiceCollection`扩展`AddOidcStateDataFormatterCache`方法。如果未传递任何参数,则配置的所有OpenID Connect处理程序将使用IdentityServer提供的安全数据格式实现: 151 | ``` C# 152 | public void ConfigureServices(IServiceCollection services) 153 | { 154 | // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache. 155 | services.AddOidcStateDataFormatterCache(); 156 | 157 | services.AddAuthentication() 158 | .AddOpenIdConnect("demoidsrv", "IdentityServer", options => 159 | { 160 | // ... 161 | }) 162 | .AddOpenIdConnect("aad", "Azure AD", options => 163 | { 164 | // ... 165 | }) 166 | .AddOpenIdConnect("adfs", "ADFS", options => 167 | { 168 | // ... 169 | }); 170 | } 171 | ``` 172 | 173 | 如果只配置特定方案,则将这些方案作为参数传递: 174 | ``` C# 175 | public void ConfigureServices(IServiceCollection services) 176 | { 177 | // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache. 178 | services.AddOidcStateDataFormatterCache("aad", "demoidsrv"); 179 | 180 | services.AddAuthentication() 181 | .AddOpenIdConnect("demoidsrv", "IdentityServer", options => 182 | { 183 | // ... 184 | }) 185 | .AddOpenIdConnect("aad", "Azure AD", options => 186 | { 187 | // ... 188 | }) 189 | .AddOpenIdConnect("adfs", "ADFS", options => 190 | { 191 | // ... 192 | }); 193 | } 194 | ``` 195 | -------------------------------------------------------------------------------- /第三部分 主题/第23章 Windows身份验证.md: -------------------------------------------------------------------------------- 1 | # 第23章 Windows身份验证 2 | 在支持的平台上,您可以使用IdentityServer使用Windows身份验证对用户进行身份验证(例如,针对Active Directory)。当前使用以下命令托管IdentityServer时,Windows身份验证可用: 3 | 4 | * [Kestrel](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel)在Windows上使用IIS和IIS集成包 5 | * Windows上的[HTTP.sys](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys)服务器 6 | 7 | 在这两种情况下,使用方案`“Windows”`在`HttpContext`上使用`ChallengeAsync` API来触发Windows身份验证。我们的[快速入门UI](https://github.com/IdentityServer/IdentityServer4.Quickstart.UI)中的帐户控制器实现了必要的逻辑。 8 | 9 | ## 23.1 使用 Kestrel 10 | 使用Kestrel时,必须运行“behind”IIS并使用IIS集成: 11 | ``` C# 12 | var host = new WebHostBuilder() 13 | .UseKestrel() 14 | .UseUrls("http://localhost:5000") 15 | .UseContentRoot(Directory.GetCurrentDirectory()) 16 | .UseIISIntegration() 17 | .UseStartup() 18 | .Build(); 19 | ``` 20 | 21 | 使用该`WebHost.CreateDefaultBuilder`方法设置时,会自动配置`WebHostBuilder`。 22 | 23 | IIS(或IIS Express)中的虚拟目录也必须启用Windows并启用匿名身份验证。 24 | 25 | IIS集成层将Windows身份验证处理程序配置为DI,可以通过身份验证服务调用。通常在IdentityServer中,建议禁用此自动行为。这是在`ConfigureServices`: 26 | 27 | ``` C# 28 | services.Configure(iis => 29 | { 30 | iis.AuthenticationDisplayName = "Windows"; 31 | iis.AutomaticAuthentication = false; 32 | }); 33 | ``` 34 | 35 | > **注意** 36 | 默认情况下,显示名称为空,Windows身份验证按钮不会显示在快速入门UI中。如果依赖于自动发现外部提供程序,则需要设置显示名称。 -------------------------------------------------------------------------------- /第三部分 主题/第24章 退出.md: -------------------------------------------------------------------------------- 1 | # 第24章 退出 2 | 注销IdentityServer就像删除身份验证cookie一样简单,但是为了完成联合注销,我们必须考虑将用户从客户端应用程序(甚至可能是上游身份提供者)中签名。 3 | 4 | ## 24.1 删除认证 5 | 要删除身份验证cookie,只需使用`HttpContext`扩展方法`SignOutAsync`即可。您需要传递使用的方案(`IdentityServerConstants.DefaultCookieAuthenticationScheme`除非您已更改,否则提供此方案): 6 | ``` C# 7 | await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme); 8 | ``` 9 | 10 | 或者您可以使用IdentityServer提供的便捷扩展方法: 11 | ``` C# 12 | await HttpContext.SignOutAsync(); 13 | ``` 14 | 15 | > **注意** 16 | 通常,您应该提示用户注销(需要POST),否则攻击者可能会链接到您的注销页面,导致用户自动注销。 17 | 18 | ## 24.2 通知客户端用户已注销 19 | 作为退出流程的一部分,您需要确保客户端应用程序被告知用户已退出。IdentityServer支持服务器端客户端的[前端通道](https://openid.net/specs/openid-connect-frontchannel-1_0.html)规范(例如MVC),服务器端客户端的[反向通道](https://openid.net/specs/openid-connect-backchannel-1_0.html) 规范(例如MVC),以及基于浏览器的JavaScript客户端的[会话管理](https://openid.net/specs/openid-connect-session-1_0.html)规范(例如SPA,React,Angular)等)。 20 | 21 | ### 24.2.1 前端服务器端客户端 22 | 23 | 要通过前端通道规范从服务器端注销客户端应用程序用户,IdentityServer中的“已注销”页面必须呈现`