使用客户端凭据保护 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. jQuery实现列表的增加和删除

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. webstorm累计

    websorm官网下载安装: 1.一下粗略截图说明,点击下一步下一步安装到合适的路径下. 2.next下一步下一步安装成功后弹出,点击ok就行. 2.再次运行webstorm快捷方式打开:界面如下: ...

  3. Java HashMap 源代码分析

    Java HashMap jdk 1.8 Java8相对于java7来说HashMap变化比较大,在hash冲突严重的时候java7会退化为链表,Java8会退化为TreeMap 我们先来看一下类图: ...

  4. golang 切片小记

    1 切片初始化 func printSlice(s []int) { fmt.Printf("len=%d cap=%d underlying array:%p, %v\n", l ...

  5. Vivado 调用自定义IP核

    关于Vivado如何创建自定义IP核有大量的参考文章,这里就不多加阐述了,本文目的主要是解决如何在新建工程中引用其它工程已经自定义封装好的IP核,从而实现自定义IP核的灵活复用. 举个例子,我们的目标 ...

  6. Java基本修饰符

    java中的修饰符分为类修饰符,字段修饰符,方法修饰符.根据功能的不同,主要分为以下几种: *权限访问修饰符(可以用来修饰类.方法和字段) 适用范围<访问权限范围越小,安全性越高> 访问权 ...

  7. Ajax的跨域请求——JSONP的使用

    一.什么叫跨域 域当然是别的服务器 (说白点就是去别服务器上取东西) 只要协议.域名.端口有任何一个不同,都被当作是不同的域. 总而言之,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源( ...

  8. 2017-2018-1 20155329《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155329<信息安全技术>实验二--Windows口令破解 实验原理 口令破解方法 字典破解: 指通过破解者对管理员的了解,猜测其可能使用某些信息作为密码,利 ...

  9. 【BZOJ4543】Hotel加强版

    [BZOJ4543]Hotel加强版 题面 bzoj 洛谷 $ps:$在洛谷看题在bzoj交... 题解 我们分析一下这个问题,要怎么样的点才满足三点距离两两相等呢? 1.存在三个点有共同的$LCA$ ...

  10. javaweb(十)——HttpServletRequest对象(一)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...