美文网首页程序员.NET技术干货
原创 | Authentication & Author

原创 | Authentication & Author

作者: KennethChen93 | 来源:发表于2018-01-12 11:05 被阅读307次

    以下思路参考于 IdentityServer4 源码,流程。阅读文章请 先 熟悉 OAuth 2.0, Open ID ,Open ID Connect 。本文章已申请授权骑士处理,转载请注明出处。
    存储于 本机 Markdown文档。 | 待更新。

    IdentityServer4是一个针对 ASP.NET Core 2.0 的OpenID Connect 和 OAuth 2.0框架。

    在你的应用中,它支持以下特性:

    Authentication as a Service

    所有应用程序的集中登录逻辑和工作流(web,native,mobile,services),IdentityServer 是一个官方认证的OpenID Connect的实现。

    Single Sign-on / Sign-out

    在多个应用程序类型的登入和登出

    Access Control for APIs

    为不同的客户端提供api的访问令牌,e.g. server to server, web 应用,SPAs和 native .mobile apps

    Federation Gateway(联合网关)

    支持如Azure AD,Google,Facebook等外部的身份验证提供者,这将保护你的应用程序从如何连接到这些外部提供程序的细节。

    Focus on Customization(专注于定制)

    最重要的一部分--IdentityServer 的很多方面都可以定制,以满足你的需求,由于IdentityServer 是一个框架,而不是一个boxed product或者一个SaaS,所以你可以编写代码来对系统进行调整,以适应您的场景。

    Mature Open Source(成熟的开源)

    IdentityServer 使用了Apache 2的开源许可,允许在它上面构建商业产品,它也是.NET Foundation的一部分,提供了法律支持和治理。

    Free and Commercial Support(免费和商业支持)

    如果你需要帮助构建或运行您的身份平台,请让我们知道,我们有几种方法可以帮组你。

    let us know

    The Big Picture

    大多数现代应用程序或多或少都是这样的:

    ../_images/appArch.png

    最常见的互动是:

    • 浏览器与Web 应用程序的通信

    • Web应用程序与Web api进行通信(有时是自己的,也有代表用户的)

    • 基于浏览器的应用程序与web apis通信

    • Native applications 与 web APIs通信

    • 基于服务器的应用程序与Web api通信

    • web api 与web api 进行通信(有时是自己的,有时代表用户)

    通常,每个层(前端,中间层和后端)都必须保护资源,并实现身份验证/或授权 --通常是针对同一个用户存储的。

    将这些基本安全功能外包给安全令牌服务,可以防止在这些应用程序和端点之间复制该功能,

    对应用程序进行重构以支持安全令牌服务,这将导致以下体系和协议:

    image

    这样的设计将安全问题分为两部分:

    Authentication

    当应用程序需要了解当前用户的身份时,需要进行身份验证。通常,这些应用程序为了去管理数据和需要去确保这个用户能被与允许连接这些数据。最常见的例子就是web 应用程序,但是是基于native和JS的应用程序也需要去进行身份验证。

    OpenID Connect是最新的三个,但它被认为是未来,因为它对现代应用最有潜力。它是为移动应用场景而建的,从开始和设计也是友好的和API。

    API Access

    应用程序有两种基本的方式与API进行通信。使用application identity,或者委托user’s identity。有时这两种方法需要结合使用。

    OAurh2 是一种协议,允许应用程序从安全令牌服务请求访问令牌,并使用它们与api进行通信,这个委托减少了客户端应用程序和身份验证和身份验证之后的api复杂性。

    OpenID Connect and OAuth 2.0 – better together

    OpenID Connect 和OAuth 2.o非常相似--实际上,OpenID Connect 是OAuth2.0的一个扩展,两个基本的安全问题,身份验证和API访问,被组合成一个单一的协议--通常是对安全令牌服务进行一次单独的访问。

    我们相信,在可预见的未来,OpenID Connect和OAuth2.0的结合是确保现代应用程序安全的最佳方式。身份识别是这两种协议的一种实现,它对解决当前mobile,native和web 应用程序的典型安全问题进行了高度优化。

    How IdentityServer4 can help

    IdentityServer 是一个中间件 ,符合规范的OpenID Connect和OAuth 2.0端点应用带任何ASP.NET Core应用程序。

    通常,您构建(或重用)一个包含登录和注销页面的应用程序(取决于你的需求),把IdentityServer middleware添加到必要的协议头,因此客户端应用程序可以使用这些标准协议与之进行通信。

    image

    托管应用程序可以像您希望的那样复杂,但是我们通常建议通过只包含与身份验证相关的UI来尽可能小地被攻击。

    Terminology(术语)

    规范,文档和object model 使用了一些您应该知道的术语。

    ../_images/terminology.png

    IdentityServer

    IdentityServer是一个OpenID Connect 提供者 - 它实现了OpenID Connect 和 OAuth 2.0协议。

    不同的文献使用不同的术语来表示相同的角色 - 你可能还会发现安全令牌服务security token service,身份提供者identity provider,授权服务器authorization server, IP-STS 等等

    但是,它们都是一样的:一款向客户端提供安全令牌的软件。

    IdentityServer有许多工作和特性 - 包含:

    • 保护你的资源

    • 通过外部扩展的identity provider或本地账户对用户进行身份验证。

    • 提供session 管理和单点登录

    • 管理和认证用户

    • 向clients发出标识issue identity和访问令牌。

    • 验证tokens

    User

    用户是一个使用注册客户端client访问资源的人,

    Client

    Client是一个软件,它从IdentityServer 请求token - 要么是访问资源(请求身份令牌identity token),要么是访问资源(请求访问令牌access token)。Client必须在请求tokens之前首先注册在IdentityServer 。

    Clients的例子是web applications ,native mobile,desktop applications,SPAs,服务器进程等。

    Resources

    Resources是您想要用IdentityServer 保护的东西 - 你的用户身份数据或者APIs.

    每个resource都有唯一的名称 - 并且 clients 使用这个名称来指定他们想要访问的资源。

    Identity data 关于用户的身份信息(aka claims) ,例如姓名或电子邮件地址。

    APIs APIs resources表示电子client 想要调用的功能 - 典型的模型是web api ,但也不一定。

    Identity Token

    identity token(身份token)允许连接 API resource。Clients请求access tokens和将他们转发到 API.

    Access tokens包含了client 的信息 和用户的(如果存在)。APIS使用这些信息来授权访问他们的数据。

    Supported Specifications

    IdentityServer implements the following specifications:

    OpenID Connect

    OpenID Connect Core 1.0 (spec)OpenID Connect Discovery 1.0 (spec)OpenID Connect Session Management 1.0 - draft 28 (spec)OpenID Connect Front-Channel Logout 1.0 - draft 02 (spec)OpenID Connect Back-Channel Logout 1.0 - draft 04 (spec)

    OAuth 2.0

    OAuth 2.0OAuth 2.0 (RFC 6749)OAuth 2.0 Bearer Token Usage (RFC 6750)OAuth 2.0 Multiple Response Types (spec)OAuth 2.0 Form Post Response Mode (spec)OAuth 2.0 Token Revocation (RFC 7009)OAuth 2.0 Token Introspection (RFC 7662)Proof Key for Code Exchange (RFC 7636)JSON Web Tokens for Client Authentication (RFC 7523)

    Packaging and Builds(包装和构建)

    IdentityServer 由很多nuget包组成。

    IdentityServer4

    nuget | github

    包含了核心的IdentityServer object model,services和middleware。只包含对内存配置和用户存储的支持,但是你可以通过配置对其他的存储进行插件支持。这是其它的 repos 和它的packages的内容。

    Quickstart UI

    github

    包含了一个简单的用户界面启动,包括登录,注销和同意页面。

    Access token validation handler

    nuget | github

    ASP.NET Core 身份验证handler 用于验证tokens 在APIs. handler允许在相同的API中支持JWT 和引用tokens

    ASP.NET Core Identity

    nuget | github

    ASP.NET Core Identity 集成了 package 对于 IdentityServer。package提供了一个简单的配置API来使用ASP.NET Identity 为你的IdentityServer users提供管理程序库。

    EntityFramework Core

    nuget | github

    EntityFramework Core 存储实现对于EntityFramework Core。这个package提供了EntityFramework的实现对于配置和在IdentityServer操作存储。

    Dev builds(开发构建)

    此外,我们还向MyGet发布了 dev/interim构建版本。如果你想试一试,把下面的内容添加到你的Visual Studio中。

    https://www.myget.org/F/identity/

    Support and Consulting Options

    We have several free and commercial support and consulting options for IdentityServer.

    Free support

    Free support is community-based and uses public forums

    StackOverflow

    There’s an ever growing community of people using IdentityServer that monitor questions on StackOverflow. If time permits, we also try to answer as many questions as possible

    You can subscribe to all IdentityServer4 related questions using this feed:

    https://stackoverflow.com/questions/tagged/?tagnames=identityserver4&sort=newest

    Please use the IdentityServer4 tag when asking new questions

    Gitter

    You can chat with other IdentityServer4 users in our Gitter chat room:

    https://gitter.im/IdentityServer/IdentityServer4

    Reporting a bug

    If you think you have found a bug or unexpected behavior, please open an issue on the Github issue tracker. We try to get back to you ASAP. Please understand that we also have day jobs, and might be too busy to reply immediately.

    Also check the contribution guidelines before posting.

    Commercial support

    We are doing consulting, mentoring and custom software development around identity & access control architecture in general, and IdentityServer in particular. Please get in touchwith us to discuss possible options.

    Training

    We are regularly doing workshops around identity & acess control for modern applications. Check the agenda and upcoming public dates here. We can also perform the training privately at your company. Contact us to request the training on-site.

    Admin UI, Identity Express and SAML2p support

    There are a couple of commercial add-on products available from our partners, check https://www.identityserver.com/products/.

    Demo Server and Tests 演示服务器和测试

    你可以使用你最喜欢的client library 来尝试IdentityServer4。我们有一个测试实例,在demo.identityserver.io. 在主页上,您可以找到关于如何配置client 和如何配置客户端和如何调用API的说明。

    Contributing

    We are very open to community contributions, but there are a couple of guidelines you should follow so we can handle this without too much effort.

    How to contribute?

    The easiest way to contribute is to open an issue and start a discussion. Then we can decide if and how a feature or a change could be implemented. If you should submit a pull request with code changes, start with a description, only make the minimal changes to start with and provide tests that cover those changes.

    Also read this first: Being a good open source citizen

    General feedback and discussions?

    Please start a discussion on the core repo issue tracker.

    Platform

    IdentityServer is built against ASP.NET Core 2 and runs on .NET Framework 4.6.1 (and higher) and .NET Core 2 (and higher).

    Bugs and feature requests?

    Please log a new issue in the appropriate GitHub repo:

    Other discussions

    https://gitter.im/IdentityServer/IdentityServer4

    Contributing code and content

    You will need to sign a Contributor License Agreement before you can contribute any code or content. This is an automated process that will start after you opened a pull request.

    Note

    We only accept PRs to the dev branch.

    Contribution projects

    We very much appreciate if you start a contribution project (e.g. support for Database X or Configuration Store Y). Tell us about it so we can tweet and link it in our docs.

    We generally don’t want to take ownership of those contribution libraries, we are already really busy supporting the core projects.

    Naming conventions

    As of October 2017, the IdentityServer4.* nuget namespace is reserved for our packages. Please use the following naming conventions:

    YourProjectName.IdentityServer4

    or

    IdentityServer4.Contrib.YourProjectName

    Setup and Overview(设置和概述)

    启动了一个新的IdentityServer 项目有两种基本方法:

    • 从头开始

    • 在vs中的 ASP.NET Identity 模板开始

    如果您从头开始,我们提供了几个帮助器和内存中的存储库,因此您不必从一开始就担心持久性。

    如果你从ASP.NET Identity开始,我们也提供了一种简单的方法来整合它。

    quickstarts为各种常见的IdentityServer提供步骤说明,它们从绝对基础开始,变得更加复杂,建议你按顺序来做。

    每一个快速启动quickstart都有一个参考的解决方案 --你可以在IdentityServer4.Samples repo张找到代码在quickstarts文件夹中。

    Basic setup

    屏幕截图显示的是Visual Studio-但是这不是一个需求。

    Creating the quickstart IdentityServer

    Start by creating a new ASP.NET Core project.

    image

    Then select the “Empty” option.

    image

    Next, add the IdentityServer4 nuget package:

    image

    或者,您可以使用Package Manager控制台通过运行以下命令来添c加依赖项:

    “Install-Package IdentityServer4”

    Note

    IdentityServer build numbers 1.x target ASP.NET Core 1.1, and IdentityServer build numbers 2.x targets ASP.NET Core 2.0 .

    IdentityServer使用常见的模式来配置和向ASP.NET Core host添加服务,在配置服务中,所需的服务被配置并添加到DI中 ConfigureServices,在配置胡总,中间件被添加到HTTP管道Configure中。

    Modify your Startup.cs file to look like this:

    <pre class="md-fences md-end-block" lang="c#" contenteditable="false" cid="n472" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: pre; display: block; break-inside: avoid; text-align: left; background-image: ; background-position: var(--code-block-bg-color); background-size: ; background-repeat: var(--code-block-bg-color); background-attachment: ; background-origin: ; background-clip: ; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(221, 221, 221); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
    public class Startup
    {
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddIdentityServer()
    .AddDeveloperSigningCredential();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }

    app.UseIdentityServer();
    }
    }</pre>

    AddIdentityServer 在DI中注册IdentityServer services,它还在运行时注册了一个内存存储库,这对于开发场景非常有用,对于生产场景,你需要一个持久化或共享的存储库,如数据库或者缓存,有关更多的信息,请参见 EntityFramework quickstart。

    The AddDeveloperSigningCredential 扩展为签署tokens创建临时密钥,这可能对开始工作有用,但是需要为生产环境替换持久性的关键材料,更多系想你请参见密码学文档 cryptography docs

    Note

    IdentityServer 还没有准备好启动,我们将在接下来的quickstarts中添加所需的服务。

    Modify hosting(修改主机)

    默认情况下,vs 使用IIS Express来托管你的web项目,这是完全没有问题的,除非你无法看到实际的时间日志输出到控制台。

    IdentityServer 广泛使用日志记录,而UI中的可见错误消息或者返回给客户端则故意含糊不清,

    我们建议在控制台主机中运行IdentityServer ,你可以通过在vs中切换启动 launch profile,你也不需要在每次你启动IdentityServer时启动浏览器 - 你也可以关闭它。

    image

    此外,对于这些quickstarts的一致URL运行IdentityServer是有帮助的,你可以配置这些URL在启动配置文件对话框launch profile dialog above,and use http://localhost:5000/. 在上面的截图中,你可以看到这个URL已经被配置。

    Note

    我们建议为IIS Express 和 self-hosting(自托管)配置相同的端口,通过这种方法,你可以在两者之间切换,而无需修改客户机的任何配置。

    要在启动时选择控制台主机,您必须在Visual Studio的启动菜单中选择它:

    image

    How to run the quickstart

    正如上面所提到的,每一个快速启动都有一个参考解决方案—您可以在以下代码中找到代码IdentityServer4.Samples repo 在 quickstarts 文件夹中

    运行quickstart解决方案的各个部分的最简单的方法是将启动模式选为 “Set Startup Projects”:

    image

    通常,您首先启动标识服务器,然后是API,然后是客户端client。如果您想要调试的话,只需要在调试器中运行。否则,Ctrl+F5是运行项目的最佳方式。

    Protecting an API using Client Credentials (使用Client 凭证保护API)

    quickstart提供了使用IdentityServer保护API的最基本场景

    在这个场景中,我们将定义一个API 和一个我们想要去访问的Client ,Client将在IdentityServer请求access token(访问令牌) 并使用它来访问API.

    Defining the API

    Scopes定义了你想要保护的系统中的资源,例如 APIs。

    哟偶遇我们使用的是内存配置进行演示 --你需要做的就是添加一个API,就是创建一个API类型的对象ApiResource ,并设置适当的属性。

    将一个文件(例如config.cs)添加到您的项目中,并添加以下代码:

    <pre class="md-fences md-end-block" lang="c#" contenteditable="false" cid="n549" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: pre; display: block; break-inside: avoid; text-align: left; background-image: ; background-position: var(--code-block-bg-color); background-size: ; background-repeat: var(--code-block-bg-color); background-attachment: ; background-origin: ; background-clip: ; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(221, 221, 221); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
    public static IEnumerable<ApiResource> GetApiResources()
    {
    return new List<ApiResource>
    {
    new ApiResource("api1", "My API")
    };
    }</pre>

    Defining the client

    下一步是定义一个Client可以访问这个API。

    对于这个场景,client 将不会有一个交互的用户,并将使用IdentityServer的 client secret 进行身份验证,在您的配置中添加以下代码:

    <pre class="md-fences md-end-block" lang="c#" contenteditable="false" cid="n559" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: pre; display: block; break-inside: avoid; text-align: left; background-image: ; background-position: var(--code-block-bg-color); background-size: ; background-repeat: var(--code-block-bg-color); background-attachment: ; background-origin: ; background-clip: ; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(221, 221, 221); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
    public static IEnumerable<Client> GetClients()
    {
    return new List<Client>
    {
    new Client
    {
    ClientId = "client",

    // no interactive user, use the clientid/secret for authentication
    AllowedGrantTypes = GrantTypes.ClientCredentials,

    // secret for authentication
    ClientSecrets =
    {
    new Secret("secret".Sha256())
    },

    // scopes that client has access to
    AllowedScopes = { "api1" }
    }
    };
    }</pre>

    Configure IdentityServer

    要配置 IdentityServer 去使用你的 scopes 和 client 定义,你需要向ConfigureServices 方法添加代码。你可以使用方便的扩展方法 ---在这些方法的下面,将相关的存储和数据添加到DI中。

    <pre class="md-fences md-end-block" lang="c#" contenteditable="false" cid="n567" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: pre; display: block; break-inside: avoid; text-align: left; background-image: ; background-position: var(--code-block-bg-color); background-size: ; background-repeat: var(--code-block-bg-color); background-attachment: ; background-origin: ; background-clip: ; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(221, 221, 221); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
    public void ConfigureServices(IServiceCollection services)
    {
    // configure identity server with in-memory stores, keys, clients and resources
    services.AddIdentityServer()
    .AddDeveloperSigningCredential()
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients());
    }</pre>

    就是这样,如果你运行服务器并浏览浏览器http://localhost:5000/.well-known/openid-configuration,你赢可以看到 所谓的 “discovery document” 发现文档,它将被使用在你的clients 和APIs去下载必要的配置数据。

    image

    Adding an API

    接下来,向您的解决方案添加一个API。

    你可以使用 ASP.NET Core API 模板,同样,我们建议你控制端口,使用和以前启动配置文件去配置 Kestrel。这个演示假设你已经配置了你的API来运行。http://localhost:5001.

    The controller

    Add a new controller to your API project:

    <pre class="md-fences md-end-block" lang="c#" contenteditable="false" cid="n591" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 0.9em; white-space: pre; display: block; break-inside: avoid; text-align: left; background-image: ; background-position: var(--code-block-bg-color); background-size: ; background-repeat: var(--code-block-bg-color); background-attachment: ; background-origin: ; background-clip: ; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(221, 221, 221); border-radius: 3px; padding: 8px 1em 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
    [Route("identity")]
    [Authorize]
    public class IdentityController : ControllerBase
    {
    [HttpGet]
    public IActionResult Get()
    {
    return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
    }
    }</pre>

    稍后你讲使用该 controller 来测试授权需求,并通过API对 claims identity进行可视化。

    Configuration

    最后一步,是将 authentication services 添加到 DI 和身份验证中间件到 管道,这些将:

    • 验证传入的token以确保它来自受信任的发行方。

    • 验证这个token是有效的能被用于这个api(既scope)。

    相关文章

      网友评论

        本文标题:原创 | Authentication & Author

        本文链接:https://www.haomeiwen.com/subject/yfseixtx.html