IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API
IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API
原文:http://docs.identityserver.io/en/release/quickstarts/1_client_credentials.html
上一篇:IdentityServer4 中文文档 -8- (快速入门)设置和概览
下一篇:IdentityServer4 中文文档 -10- (快速入门)使用密码保护API
当前快速入门展示了使用 IdentityServer 保护 API 的最基础的场景。
在这个场景中,我们定义一个 API,同时定义一个 想要访问这个 API 的 客户端。客户端将从 IdentityServer 请求获得一个访问令牌,然后用这个令牌来获得 API 的访问权限。
定义 API
范围(Scopes)用来定义系统中你想要保护的资源,比如 API。
由于当前演练中我们使用的是内存配置 —— 添加一个 API,你需要做的只是创建一个 ApiResource 类型的实例,并为它设置合适的属性。
向你的项目中添加一份文件(比如:Config.cs),然后添加如下代码:
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api1", "我的 API")
};
}
定义 客户端
下一步是定义能够访问上述 API 的客户端。
在该场景中,客户端不会有用户参与交互,并且将使用 IdentityServer 中所谓的客户端密码(Client Secret)来认证。添加如下代码到你的配置中:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client",
// 没有交互性用户,使用 clientid/secret 实现认证。
AllowedGrantTypes = GrantTypes.ClientCredentials,
// 用于认证的密码
ClientSecrets =
{
new Secret("secret".Sha256())
},
// 客户端有权访问的范围(Scopes)
AllowedScopes = { "api1" }
}
};
}
配置 IdentityServer
为了让 IdentityServer 使用你的 Scopes 和 客户端 定义,你需要向 ConfigureServices 方法中添加一些代码。你可以使用便捷的扩展方法来实现 —— 它们在幕后会添加相关的存储和数据到 DI 系统中:
public void ConfigureServices(IServiceCollection services)
{
// 使用内存存储,密钥,客户端和资源来配置身份服务器。
services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
}
现在,如果你运行服务器并将浏览器导航到 http://localhost:5000/.well-known/openid-configuration,你应该看能到所谓的 发现文档。你的客户端和 API 将使用这些信息来下载所需要的配置数据。

添加 API
下一步,向你的解决方案中添加 API。
你可以使用 ASP.NET Core Web API 模板,或者添加 Microsoft.AspNetCore.Mvc 程序包到你的项目中。再一次建议你像之前一样,控制所使用的端口并使用与之前配置 Kestrel 和启动资料相同的技术。该演练假设你已经将你的 API 配置为运行于 http://localhost:5001 之上。
控制器
添加一个新的控制器到你的 API 项目中:
[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 });
}
}
这个控制器将在后面被用于测试授权需求,同时通过API的眼睛(浏览工具)来可视化身份信息。
配置
接下来,添加认证中间件到 API 宿主。该中间件的主要工作是:
- 验证输入的令牌以确保它来自可信任的发布者(IdentityServer);
- 验证令牌是否可用于该 api(也就是 Scope)。
将 IdentityServer4.AccessTokenValidation NuGet 程序包添加到你的 API 项目:

你还需要添加中间件到你的 HTTP 管道中 —— 必须在添加 MVC 之前添加,比如:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1"
});
app.UseMvc();
}
如果你使用浏览器导航到上述控制器(http://localhost:5001/identity),你应该收到返回的 401 状态码。这意味着你的 API 要求提供证书。
这样一来, API 就是受 IdentityServer 保护的了。
创建客户端
最后一个步骤是编写一个客户端来请求访问令牌,然后使用这个令牌来访问 API。为此你需要为你的解决方案添加一个控制台应用程序。
IdentityServer 上的令牌端点实现了 OAuth 2.0 协议,你应该使用合法的 HTTP 来访问它。然而,我们有一个叫做 IdentityModel 的客户端库,它将协议交互封装到了一个易于使用的 API 里面。
添加 IdentityModel NuGet 程序包到你的客户端项目中。

IdentityModel 包含了一个用于 发现端点 的客户端库。这样一来你只需要知道 IdentityServer 的基础地址 —— 实际的端点地址可以从元数据中读取:
// 从元数据中发现端口
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
接着你可以使用 TokenClient 类型来请求令牌。为了创建一个该类型的实例,你需要传入令牌端点地址、客户端id和密码。
然后你可以使用 RequestClientCredentialsAsync 方法来为你的目标 API 请求一个令牌:
// 请求以获得令牌
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);
注意:从控制台中复制和粘贴访问令牌到 jwt.io 以检查令牌的合法性。
最后是调用 API。
为了发送访问令牌到 API,你一般要使用 HTTP 授权 header。这可以通过 SetBearerToken 扩展方法来实现:
// 调用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));
}
最终输出看起来应该是这样的:

注意:默认情况下访问令牌将包含 scope 身份信息,生命周期(nbf 和 exp),客户端 ID(client_id) 和 发行者名称(iss)。
进一步实践
当前演练目前主要关注的是成功的步骤:
- 客户端可以请求令牌
- 客户端可以使用令牌来访问 API
你现在可以尝试引发一些错误来学习系统的相关行为,比如:
- 尝试在 IdentityServer 未运行时(unavailable)连接它
- 尝试使用一个非法的客户端id或密码来请求令牌
- 尝试在请求令牌的过程中请求一个非法的 scope
- 尝试在 API 未运行时(unavailable)调用它
- 不向 API 发送令牌
- 配置 API 为需要不同于令牌中的 scope
上一篇:IdentityServer4 中文文档 -8- (快速入门)设置和概览
下一篇:IdentityServer4 中文文档 -10- (快速入门)使用密码保护API
IdentityServer4 中文文档 -9- (快速入门)使用客户端凭证保护API的更多相关文章
- IdentityServer4 中文文档 -16- (快速入门)使用 EntityFramework Core 存储配置数据
IdentityServer4 中文文档 -16- (快速入门)使用 EntityFramework Core 存储配置数据 原文:http://docs.identityserver.io/en/r ...
- IdentityServer4 中文文档 -15- (快速入门)添加 JavaScript 客户端
IdentityServer4 中文文档 -15- (快速入门)添加 JavaScript 客户端 原文:http://docs.identityserver.io/en/release/quicks ...
- IdentityServer4 中文文档 -14- (快速入门)使用 ASP.NET Core Identity
IdentityServer4 中文文档 -14- (快速入门)使用 ASP.NET Core Identity 原文:http://docs.identityserver.io/en/release ...
- IdentityServer4 中文文档 -13- (快速入门)切换到混合流并添加 API 访问
IdentityServer4 中文文档 -13- (快速入门)切换到混合流并添加 API 访问 原文:http://docs.identityserver.io/en/release/quickst ...
- IdentityServer4 中文文档 -12- (快速入门)添加外部认证支持
IdentityServer4 中文文档 -12- (快速入门)添加外部认证支持 原文:http://docs.identityserver.io/en/release/quickstarts/4_e ...
- IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证
IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证 原文:http://docs.identityserver.io/en/releas ...
- IdentityServer4 中文文档 -8- (快速入门)设置和概览
IdentityServer4 中文文档 -8- (快速入门)设置和概览 原文:http://docs.identityserver.io/en/release/quickstarts/0_overv ...
- IdentityServer4 中文文档 -10- (快速入门)使用密码保护API
IdentityServer4 中文文档 -10- (快速入门)使用密码保护API 原文:http://docs.identityserver.io/en/release/quickstarts/2_ ...
- IdentityServer4 中文文档 -7- (简介)贡献
IdentityServer4 中文文档 -7- (简介)贡献 原文:http://docs.identityserver.io/en/release/intro/contributing.html ...
随机推荐
- 别人的Linux私房菜(11)认识与学习BASH
Linux下使用BASH Bourne Again Shell 另外一种由用于Unix的伯克利大学的Bill Joy设计的C Shell 系统中合法的shell会写入到/etc/sh ...
- fly插件飞向购物车
首先载入jQuery库文件和jquery.fly.min.js插件. 插件官方: https://github.com/amibug/fly, 官方例子: http://codepen.io/hzxs ...
- [solution] JZOJ-5795 词典
[solution]JZOJ-5795 词典 题面 Description 小C有$n$个字符串$T_1 T_n$,给出$m$个询问 第$i$个询问给出一个字符串$S_i$,对于每个询问,我们可以得到 ...
- bzoj3929(sam)
因为题目中树的特殊性暴力dfs建sam就好了.然后sam有一个有意思的性质是一个点代表的子串个数等于mx[i]-mx[fail[i]],至于为什么,我不会严谨的证明,但想想还是可以的,就是当前串的所有 ...
- ubuntu 14.04下搭建esp32开发环境
esp32是乐鑫出品的一款集成了wifi和蓝牙的集成模块,板上自带两个哈佛结构的Xtensa LX6 CPU双核处理器,本文主要讲解如何在linux下搭建其编译开发环境. 首先ctrl+alt+t打开 ...
- day13_雷神_前端01
#前端 html 服务器端返回的就是一个字符串,浏览器根据html规则去渲染这个字符串. html 是超文本标记语言,相当于定义统一的一套规则,大家都遵守它,这样就可以让浏览器根据标记语言的规则去解释 ...
- 如何将uniurlframe中html调用delphi的函数
uniGUI总群中台中cmj朋友为我们总结了如下内容,对于利用delphi+uniGUI开发应用,可以说是精品,必须掌握. 一句话,如何在html与delphi间交互代码,是最好的答案. [Clien ...
- git 中Pull/Request 的初步
1. 目的: pull/request (简称PR) 是 项目管理者(管理者)和项目开发者(开发者)之间提交和确认工作成果的机制. 2. 流程: 开发者: 在本地创建特性分支. > git ch ...
- Hadoop 综合揭秘——HBase的原理与应用
前言 现今互联网科技发展日新月异,大数据.云计算.人工智能等技术已经成为前瞻性产品,海量数据和超高并发让传统的 Web2.0 网站有点力不从心,暴露了很多难以克服的问题.为此,Google.Amazo ...
- DevExpress--TreeList节点添加图片
这个过程相对来说比较简单,网上也有不少资料,但是自己在做过之后为了记住,算是给自己写一个博客吧. 下面直接上具体的流程 1.前提 控件使用的都是DevExpress和winform的原生控件两种: 2 ...