使用客户端凭据保护 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. restframework序列化使用方法

    serializers.Serializer class Userinfoserializers(serializers.Serializer): username = serializers.Cha ...

  2. PHP-掌握基本的分布式架构思想

    虽然说写PHP目前都是接触的业务代码,发现写久了,也要熟悉相应的架构 在高并发,高可用的系统下,都是使用高性能的分布式架构,最近在学习相关知识 分享一张图片: 欢迎关注公众号[phper的进阶之路], ...

  3. Python 正则:前后界定和前后非界定

    在用正则去匹配识别手机号.QQ.微信号的时候,往往由于输入的文本可能非常的另类,比如,没有标点和隔断,这时`^`和`$`就用不上了. 不用其实也可以识别的,但是有个问题,手机后是11位数字,QQ是5~ ...

  4. Java实例 Part5:面向对象入门

    目录 Part5:面向对象入门 Example01:成员变量的初始化值 Example02:单例模式的应用 -----懒汉式 -----饿汉式 Example03:汉诺塔问题的求解 Example04 ...

  5. Security 安全框架1

    security 过滤器链 检查请求是否有请求信息-主要校验规则 UsernamePasswordAuthenticationFilter: 处理表单登录, 请求是否带用户名密码 BasicAuthe ...

  6. Python编程小坑

    在Pycharm中编辑文本文件,如果使用\r\n会产生两个空行? exit("xxx),会导致Process finished with exit code 1,所以如果要输入信息然后退出, ...

  7. python range,xrange区别

    range: 直接生成一个列表对象 xrange: 生成一个xrange对象 xrange使用: 操作一个非常大的数据时,而且没存比较吃紧的时,可以使用xrange来节省内存 xrange一般在循环里 ...

  8. express添加权限拦截

    express通过中间件的方式添加权限拦截 示例代码如下 app.get('/logout', checkLogin); app.get('/logout', function(req, res) { ...

  9. oracle-11g-64位安装和plaql

    1.oracle卸载 如果是新装,请跳过此步骤 卸载步骤: 1.停止所有服务 2.用自带删除软件,删除所有目录 3.打开注册表: -->运行regedit,删除HKEY_LOCAL_MACHIN ...

  10. tkinter事件高级用法实例

    from tkinter import * import threading, time trace = 0 class CanvasEventsDemo: def __init__(self, pa ...