ASP.NET Core的身份认证框架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
ASP.NET Core的身份认证框架IdentityServer4(7)- 使用客户端证书控制API访问的更多相关文章
- ASP.NET Core的身份认证框架IdentityServer4(1)-特性一览
IdentityServer4是ASP.NET Core的一个包含OpenID和OAuth 2.0协议的框架.OpenID和OAuth 的区别请看 https://www.zhihu.com/ques ...
- ASP.NET Core的身份认证框架IdentityServer4(6)- 开始
安装和概述 启动一个新的IdentityServer项目有两种基本方法: 从头开始 从Visual Studio中的ASP.NET身份模板开始 如果从头开始,我们提供了一些文档.项目帮助和内存存储支持 ...
- ASP.NET Core的身份认证框架IdentityServer4(5)- 包和构建
包和构建 IdentityServer有许多nuget包 IdentityServer4 nuget | github 包含IdentityServer核心对象模型,服务和中间件. 仅支持内存配置和用 ...
- ASP.NET Core的身份认证框架IdentityServer4(9)-使用OpenID Connect添加用户认证
OpenID Connect OpenID Connect 1.0是OAuth 2.0协议之上的一个简单的身份层. 它允许客户端基于授权服务器执行的身份验证来验证最终用户的身份,以及以可互操作和类似R ...
- ASP.NET Core的身份认证框架IdentityServer4(3)-术语的解释
IdentityServer4 术语 IdentityServer4的规范.文档和对象模型使用了一些你应该了解的术语. 身份认证服务器(IdentityServer) IdentityServer是一 ...
- ASP.NET Core的身份认证框架IdentityServer4(8)- 使用密码认证方式控制API访问
前言 本文及IdentityServer这个系列使用的都是基于.net core 2.0的.上一篇博文在API项目中我使用了icrosoft.AspNetCore.Authentication.Jwt ...
- ASP.NET Core的身份认证框架IdentityServer4(4)- 支持的规范
IdentityServer实现以下规范: OpenID Connect OpenID Connect Core 1.0 (spec) OpenID Connect Discovery 1.0 (sp ...
- ASP.NET Core的身份认证框架IdentityServer4--入门
ASP.NET Core的身份认证框架IdentityServer4--入门 2018年08月11日 10:09:00 qq_42606051 阅读数 4002 https://blog.csdn ...
- ASP.NET Core的身份认证框架IdentityServer4--入门【转】
原文地址 Identity Server 4是IdentityServer的最新版本,它是流行的OpenID Connect和OAuth Framework for .NET,为ASP.NET Cor ...
随机推荐
- Linux学习-->linux系统在移动硬盘的安装
由于自己看了一些文章和linux的好奇,想来一窥Linux的奥秘,因此自己准备学习使用Linux系统,这里记录下自己的安装过程,方便以后自己重装系统时进行查阅. 参考的书籍是鸟哥的<Linux私 ...
- JAVA二维数组的复制
JAVA二维数组的复制 笔者今天做一道ccf题目时,遇到要将二维数组拷贝复制时,没有用常规的那种一个一个数的复制,用的是System.arraycopy()来进行复制,下面介绍这个函数的一些注意点: ...
- ABP+AdminLTE+Bootstrap Table权限管理系统第四节--仓储,服务,服务接口及依赖注入
在ABP框架中,仓储,服务,这块算是最为重要一块之一了.ABP框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块,一个程序集可看成一个模块, 一个模块可以通过一个类来定义这个模块,而给定义这 ...
- 如何快速高效地完成一个Android项目?
本文的内容有别于之前文章中纯技术的探讨,会从业务逻辑.技术.团队和方法论的角度探讨如何快速高效地完成一个Android项目.当然,快速高效是有前提的,第一,本文依然是从研发的角度来谈如何把控项目的,而 ...
- mybatis 详解(七)------一对一、一对多、多对多
前面几篇博客我们用mybatis能对单表进行增删改查操作了,也能用动态SQL书写比较复杂的sql语句.但是在实际开发中,我们做项目不可能只是单表操作,往往会涉及到多张表之间的关联操作.那么我们如何用 ...
- java中链接数据库的具体操作以及pstmt.setObject(i+1, objects[i])这行代码的意思
package dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStat ...
- Linux配置全局jdk
Linux配置全局jdk 1.确保相应文件夹下有apache-tomcat和jdk的压缩文件 注意:jdk文件必须为适应Linux版本的文件 (如果已经有了相应文件,可以跳过以下第2-3个步骤) 2. ...
- macOS Sierra 10.12.6 安装u盘制作
一.准备工作: 准备一个 8GB 或以上容量的 U 盘,确保里面的数据已经妥善备份好(该过程会抹掉 U 盘全部数据) 从这里下载苹果官方 OS X Yosemite 正式版的安装程序 (可选 AppS ...
- python_求相邻数
什么是相邻数? 比如5,相邻数为4和6,和5相差1的数,连续相差为1的一组数 需求: 遍历inputList 所有数字,取出所有数字,判断是否有相邻数, 不相邻数字 和 相邻数字 都以 “数组”形式 ...
- JavaScript高级程序设计 - 阅读笔记
[本博客为原创:http://www.cnblogs.com/HeavenBin/] 前言: 大致花费了一个星期的时间把这本书认真看了半本,下面是我做的阅读笔记,希望能够让看这本书的人有个大致的参考. ...