使用客户端凭据保护 API

quickstart 介绍了使用 IdentityServer 保护 API 的最基本场景。

接下来的场景,我们将定义一个 API 和一个想要访问它的客户端。 客户端将在 IdentityServer 上请求访问令牌并使用它来访问 API。

定义 API

在系统中定义您需要保护的资源的范围,比如 APIs。

由于我们演示的项目使用的是内存存储 - 您需要添加一个 API,它创建了一个类型为 ApiResource 的对象并设置了一些属性。

在您的项目中添加一个文件 (比如 Config.cs) ,然后把下面的代码放进去:

public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}

定义客户端(client)

接下来就是定义一个用于访问这个 API 的客户端。

当前场景下,客户端是不需要用户操作的,并且 IdentityServer 校验客户端密钥。 将下面的代码添加到 Config.cs 文件中:

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" }
}
};
}

配置 IdentityServer

配置 IdentityServer 使您定义的范围(scopes)和客户端(client)生效,您需要把一下代码添加到 ConfigureServices 方法中。 您可以像下面一样,使用一些扩展方法,就能很方便的将相应的存储方式和数据注册到 DI 系统中

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());
}

就是这样 - 当您运行服务器并在浏览器中输入 http://localhost:5000/.well-known/openid-configuration,您可以看到所谓(so-called)的发现文档。 您的客户端和 API 将用它来下载一些必要的配置数据。

添加 API

下面,添加一个 API 到你的解决方案。

您可以使用 ASP.NET Core Web API 模板。 同样,我们建议您使用与之前相同的方法来配置 Kestrel 和启动配置文件。 本演示项目假定您已将您的 API 配置为 http://localhost:5001。

controller

在 API 中新建一个新的 controller:

[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 });
}
}

该 controller 将用于请求授权测试,并通过 API 视角来显示声明标识(claims identity)。

配置

最后一步是将认证服务添加到 DI 并把认证中间件(middleware)添加到管道中(pipeline)。这将会:

  • 验证传入的令牌以确保它来自受信任的颁发者
  • 验证该令牌是否可以访问该 API(又名作用域)

添加 IdentityServer4.AccessTokenValidation NuGet 包到你的项目中。

像下面这样更新你的 Startup

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters(); services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false; options.ApiName = "api1";
});
} public void Configure(IApplicationBuilder app)
{
app.UseAuthentication(); app.UseMvc();
}
}

AddAuthentication 将认证服务注册到 DI 并把 "Bearer" 配置为默认方案。 AddIdentityServerAuthentication 将 IdentityServer 访问令牌验证处理程序注册到 DI 以供认证服务使用。 UseAuthentication 把认证中间件(middleware)添加到管道,因此每次访问主机(host)都会自动执行认证。

如果您使用浏览器导航到 Identity 控制器 (http://localhost:5001/identity),返回的则应该是 401 状态码。这意味着您需要一个凭据才能访问这个 API 。

像这样,这个 API 就受到了 IdentityServer 的保护。

创建客户端(client)

最后一步,就是写一个客户端,用来请求访问令牌人,然后使用这个令牌去访问 API。因此,在您的解决方案中添加一个控制台程序 (完整代码请查看  这里)。

IdentityServer 中的令牌节点实现了 OAuth 2.0 协议,您可以使用原始的 HTTP 来访问它。但是,我们有一个名为 IdentityModel 的客户端使用库,它将协议交互封装在易于使用的 API 中。

在您的项目中添加 IdentityModel NuGet 包。

IdentityModel 包含一个发现节点(discovery endpoint)的客户端使用库。 这样您只需要知道 IdentityServer 的基地址(base-address) - 实际节点地址可以从元数据中获取

// discover endpoints from metadata
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}

接下来,您可以使用 TokenClient 类来请求令牌。创建实例您只需要传递一个令牌节点地址,客户端 ID 和 密钥。

然后您可以使用 RequestClientCredentialsAsync 方法为您的 API 请求一个令牌

// request token
var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1"); if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
} Console.WriteLine(tokenResponse.Json);

Note

将访问令牌从控制台复制和粘贴到 jwt.io 以检查原始令牌。

最后一步就是调用 API。

将访问令牌发送到 API,您通常使用 HTTP 授权标头。 在这里使用 SetBearerToken 扩展方法来完成

// call api
var client = new HttpClient();
client.SetBearerToken(tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:5001/identity");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}

输出看起来应该像这样:

Note

默认情况下,访问令牌的声明将包含访问边界(scope),生命周期(lifetime (nbf and exp)),客户端 ID (client_id) 和发行者名称(issuer name (iss))。

进一步实验

到目前为止,该演示项目主要聚焦于

  • 客户端可以成功的请求令牌
  • 客户端能使用令牌访问 API

您现在可以尝试引发错误以便了解系统的运行方式,例如

  • 在 IdentityServer 没有运行的情况下,尝试连接它 (不可用)
  • 尝试使用无效的客户端ID或密钥来请求令牌
  • 尝试使用有效令牌访问该令牌可访问边界外的资源
  • 尝试在 API 没有运行的情况下,调用它 (不可用)
  • 不发送令牌到 API
  • 将 API 配置到令牌可访问边界外的资源范围中去

原文地址:https://github.com/ganqiyin/IdentityServer4/blob/dev/docs_cn/quickstarts/1_client_credentials.rst

【IdentityServer4文档】- 使用客户端凭据保护 API的更多相关文章

  1. asp.net core系列 54 IS4用客户端凭据保护API

    一. 概述 本篇开始进入IS4实战学习,从第一个示例开始,该示例是 “使用客户端凭据保护API”,这是使用IdentityServer保护api的最基本场景.该示例涉及到三个项目包括:Identity ...

  2. 第9章 使用客户端凭据保护API - Identity Server 4 中文文档(v1.0.0)

    快速入门介绍了使用IdentityServer保护API的最基本方案. 我们将定义一个API和一个想要访问它的客户端. 客户端将通过提供ClientCredentials在IdentityServer ...

  3. IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API

    IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API 原文:http://docs.identityserver.io/en/release/quickstarts/ ...

  4. .NET Core 3.0 使用Nswag生成Api文档和客户端代码

    摘要 在前后端分离.Restful API盛行的年代,完美的接口文档,成了交流的纽带.在项目中引入Swagger (也称为OpenAPI),是种不错的选择,它可以让接口数据可视化.下文将会演示 利用N ...

  5. 软件工程第4次作业------石墨文档Android客户端案例分析

    作业要求的博客链接:https://edu.cnblogs.com/campus/nenu/2016CS/homework/2505 分析产品:石墨文档Android客户端 第一部分 调研和评测 1. ...

  6. 使用 Swagger 文档化和定义 RESTful API

    大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Services Descript ...

  7. Atitit.论垃圾文件的识别与清理 文档类型垃圾文件 与api概要设计pa6.doc

    Atitit.论垃圾文件的识别与清理 文档类型垃圾文件 与api概要设计pa6.doc 1. 俩个问题::识别垃圾文件与清理策略1 1.1. 文件类型:pic,doc,v,m cc,isho pose ...

  8. Elasticsearch 7.x 之文档、索引和 REST API 【基础入门篇】

    前几天写过一篇<Elasticsearch 7.x 最详细安装及配置>,今天继续最新版基础入门内容.这一篇简单总结了 Elasticsearch 7.x 之文档.索引和 REST API. ...

  9. 【IdentityServer4文档】- 术语&演示服务器和测试

    术语 你需要了解一下,规范.文档和对象模型使用的术语有哪些. IdentityServer IdentityServer 是一个 OpenID Connect 提供程序 - 它实现了 OpenID C ...

随机推荐

  1. html5手机浏览器启动微信客户端支付实例

    html5手机浏览器启动微信客户端支付实例,外部浏览器html5微信支付技术,如何在手机浏览器微信支付,在微信客户端外的移动端网页使用微信支付 首先在微信支付官网https://pay.weixin. ...

  2. 改脚本之dbscaner

    默认的DBscaner只是用了ipy模块支持一个段的解析,但是我想让他加载脚本进行检测 所以,直接看 def __init__(self, target, thread): self.target = ...

  3. 004---IO模型

    io模型 同步.异步.阻塞.非阻塞概念 同步:发出一个功能调用时,在没有得到结果之前,该调用就不会返回,原地等待 异步:相反,不需要等待 阻塞:调用结果返回之前,当前线程会被挂起,如io操作,只有在得 ...

  4. SQL 查询某时间段的数据 datadiff 计算时间差

    datediff语法格式:datediff(day,开始时间,结束时间) 一.应用举例: 上面的代码,将查询 'created_time' > '2016-09-20'  的所有记录. 如果要查 ...

  5. 工作和面试中的gdb

    gdb是C/C++程序员必备的专业技能,工作中gdb最常用的场景有两个,一个是分析core文件,另一个是调试程序. 分析core文件的方法如下: 1.gdb 程序名 core文件名 2.bt或wher ...

  6. C语言复习20170716

    C语言复习20170716 C数据类型 图片来自:C语言基本数据类型简介 C语言程序处理的数据有常量和变量两种形式. 常量是在程序中不能改变其值的量.例如:整型常量.实型常量.字符常量.字符串常量和枚 ...

  7. js Date对象要注意的问题(时间转换)

    1.时间戳和时间对象可以灵活转变: let n = new Date() // 返回的是当前时间对应的国际时间 let nt =n.getTime() let n2 =new Date(nt) con ...

  8. html查漏补缺之meta标签

    什么是meta标签? meta标签是html标记head区的一个关键标签,它位于HTML文档的<head>和<title>之间(有些也不是在<head>和<t ...

  9. Selenium2+python自动化-环境搭建

    一.selenium简介 Selenium 是用于测试 Web 应用程序用户界面 (UI) 的常用框架.它是一款用于运行端到端功能测试的超强工具.您可以使用多个编程语言编写测试,并且 Selenium ...

  10. katalon系列十七:报告&Katalon Analytics

    一.邮件报告Suite执行完后,严格来说这个不算报告,只是邮件通知执行结果,具体设置请看katalon系列三 二.文件报告Suite执行完后,会在项目文件夹下/Report/Suite Name/ti ...