IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)
一.前言
本文已更新到 .NET Core 2.2
本文包括后续的Demo都会放在github:https://github.com/stulzq/IdentityServer4.Samples (QuickStart的几个Demo随着本系列的更新,目前为从官方Demo仓库的拷贝,防止本文和Demo不匹配,因为官方Demo和文档一直在更新,本系列更新速度可能会慢一步)。
这里特别说明一下:快速入门以及Topic系列为了保持到最新,目前几乎都是翻译的官方文档(以往的不适合最新版本就换掉了),需要深入一点的请看实战系列。
二.使用客户端认证保护API
此示例介绍了使用IdentityServer保护API的最基本场景。
在这种情况下,我们将定义一个API和要访问它的客户端。 客户端将在IdentityServer上请求访问令牌,并使用它来访问API。
三.准备
创建一个名为QuickstartIdentityServer的ASP.NET Core Web 空项目(asp.net core 2.2),端口5000
创建一个名为Api的ASP.NET Core Web Api 项目(asp.net core 2.2),端口5001
创建一个名为Client的控制台项目(.net core 2.2)

四.定义API、Identity资源
在QuickstartIdentityServer项目中添加一个Config.cs文件:
public static class Config
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId()
};
}
public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("api1", "My API")
};
}
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的客户端模式进行身份验证。 将以下代码添加到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以使用Scope和客户端定义,您需要向ConfigureServices方法添加代码。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApis())
.AddInMemoryClients(Config.GetClients());
// rest omitted
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to support static files
//app.UseStaticFiles();
app.UseIdentityServer();
// uncomment, if you wan to add an MVC-based UI
//app.UseMvcWithDefaultRoute();
}
运行此项目,打开浏览器访问http://localhost:5000/.well-known/openid-configuration你将会看到IdentityServer的各种元数据信息。

首次启动时,IdentityServer将为您创建一个开发人员签名密钥,它是一个名为tempkey.rsa的文件。 您不必将该文件检入源代码管理中,如果该文件不存在,将重新创建该文件。
七.添加API
在项目Api中添加一个Controller:IdentityController
[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 });
}
}
最后一步是将身份验证服务添加到DI和身份验证中间件到管道。 这些将:
- 验证传入令牌以确保它来自受信任的颁发者
- 验证令牌是否有效用于此API(也称为 audience)
将Startup更新为如下所示:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "api1";
});
}
public void Configure(IApplicationBuilder app)
{
app.UseAuthentication();
app.UseMvc();
}
}
AddAuthentication 将身份认证服务添加到DI,并将“Bearer”配置为默认方案。 AddJwtBearer 将 JWT 认证处理程序添加到DI中以供身份认证服务使用。 UseAuthentication 将身份认证中间件添加到管道中,因此将在每次调用API时自动执行身份验证。
如果在浏览器访问(http:// localhost:5001/identity),你会得到HTTP 401的结果。 这意味着您的API需要凭据。
就是这样,API现在受 IdentityServer 保护。
八.创建客户端
为 "Client" 项目添加 Nuget 包:IdentityModel
IdentityModel 包括用于发现 IdentityServer 各个终结点(EndPoint)的客户端库。这样您只需要知道 IdentityServer 的地址 - 可以从元数据中读取实际的各个终结点地址:
// discover endpoints from metadata
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
DiscoveryClient 已在最新版移除
接下来,您可以使用从 IdentityServer 元数据获取到的Token终结点请求令牌:
// request token
var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
Scope = "api1"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
九.调用API
要将Token发送到API,通常使用HTTP Authorization标头。 这是使用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));
}
输出应如下所示:

默认情况下,Token将包含有关 Scope,生命周期(nbf和exp),客户端ID(client_id)和颁发者名称(iss)的身份信息单元(Claim)。
十.使用Postman调试

十一.项目所用代码
github地址: https://github.com/stulzq/IdentityServer4.Samples/tree/master/Quickstarts/1_ClientCredentials
IdentityServer4(7)- 使用客户端认证控制API访问(客户端授权模式)的更多相关文章
- IdentityServer4[3]:使用客户端认证控制API访问(客户端授权模式)
使用客户端认证控制API访问(客户端授权模式) 场景描述 使用IdentityServer保护API的最基本场景. 我们定义一个API和要访问API的客户端.客户端从IdentityServer请求A ...
- ASP.NET Core的身份认证框架IdentityServer4(7)- 使用客户端证书控制API访问
前言 今天(2017-9-8,写于9.8,今天才发布)一口气连续把最后几篇IdentityServer4相关理论全部翻译完了,终于可以进入写代码的过程了,比较累.目前官方的文档和Demo以及一些相关组 ...
- API访问客户端
API访问客户端(WebApiClient适用于MVC/WebForms/WinForm) 这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前 ...
- Identity Server 4客户端认证控制访问API
项目源码: 链接:https://pan.baidu.com/s/1H3Y0ct8xgfVkgq4XsniqFA 提取码:nzl3 一.说明 我们将定义一个api和要访问它的客户端,客户端将在iden ...
- .NET Core IdentityServer4实战 第一章-入门与API添加客户端凭据
内容:本文带大家使用IdentityServer4进行对API授权保护的基本策略 作者:zara(张子浩) 欢迎分享,但需在文章鲜明处留下原文地址. 本文将要讲述如何使用IdentityServer4 ...
- ASP.NET Core的身份认证框架IdentityServer4(8)- 使用密码认证方式控制API访问
前言 本文及IdentityServer这个系列使用的都是基于.net core 2.0的.上一篇博文在API项目中我使用了icrosoft.AspNetCore.Authentication.Jwt ...
- IdentityServer4(8)- 使用密码认证方式控制API访问(资源所有者密码授权模式)
一.前言 本文已经更新到 .NET Core 2.2 OAuth 2.0 资源所有者密码模式允许客户端向令牌服务发送用户名和密码,并获取代表该用户的访问令牌. 除了通过无法浏览器进行交互的应用程序之外 ...
- 【WEB API项目实战干货系列】- API访问客户端(WebApiClient适用于MVC/WebForms/WinForm)(四)
这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前最新的代码已经通过Sqlite + NHibernate + Autofac满足了我们基本的 ...
- Identity Server 4资源拥有者密码认证控制访问API
基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码: Identity Server 4客户端认证控制访问API 一.QuickStartIdenti ...
随机推荐
- ----关于JS中迭代的三个“FOR”----
for each...in 使用一个变量迭代一个对象的所有属性值,对于每一个属性值,有一个指定的语句块被执行. 一些对象的内置属性是无法被遍历到的,包括所有的内置方法,例如String对象的index ...
- Python3 在操作excel时报PermissionError: [Errno 13] Permission denied: 'D:/workstation/yhdx_auto/config/case.xls'错误
此问题为文件被拒绝访问,主要是该文件已经被打开了.关闭此excel文件后在执行excel的相关操作就ok了.
- asp.net core web 项目附加进程调试
之前asp.net web项目在部署IIS站点的时候可以直接选择项目目录,不用发布,然后附加进程的时候,找到w3wp.exe开头的进程,再根据用户名找到要附加的进程,就可以附加进程调试了.但asp.n ...
- 解决Xcode8模拟器无法删除应用的问题
关闭模拟器的3DTouch.Hardware →Touch Pressure→Use Trackpad Force.
- Python Day 11
阅读目录 内容回顾 函数的参数 函数的嵌套调用 ##内容回顾 # 什么是函数:具体特定功能的代码块 - 特定功能代码块作为一个整体,并给该整体命名,就是函数 # 函数的优点: # 1.减少代码的冗余 ...
- SAS 选取部分观测
SAS 对部分观测得处理 在建立新数据集时,有以下两种方式可以从已经存在的数据集中选取观测到新数据集中. ·通过删除不满足条件的观测来保留想要的观测. ·仅接受满足条件的观测. 条件可以由IF语句. ...
- js 控制光标到指定位置
js控制光标到指定节点位置(适用于富文本编辑器中) function placeCaretAtEnd(el) { //传入光标要去的jq节点对象 el.focus(); if (typeof wind ...
- php5.6,Ajax报错,Warning: Cannot modify header information - headers already sent in Unknown on line 0
php5.6ajax报错 Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be remo ...
- STM32的SWD调试进不了main函数
玩了那么久STM32,还没有用SWD调试过程序(一直都是用printf调试程序),觉得有些落后了,于是开始搞起了SWD调试. 很快通过查阅资料,知道了keil里面的配置和ST-Link与STM32的连 ...
- 画线代码V1.0.0
画线代码: 最终效果图: 优点: 1.效果还行,计算量也不大(就一点2维直线一般式能有多少运算量). 缺点: 1.每条线怎么也是建模,可能会有点开销. 2.编辑起来很是麻烦. 代码部分: /***** ...