IdentityService4简介

一套为应用程序构建身份认证和访问控制解决方案/框架,包括单点登录,身份认证,授权和API访问控制。

前文

今天介绍ClientCredentials认证类型,适用于服务器与服务器之间身份验证,一般用于定时程序。

开始

我们需要的东西:

Api:负责提供数据,被保护进程

IdentityService4:负责提供身份认证等功能

客户端:负责在认证之后调用Api执行某些操作

IdentityService4初始化

IdentityService4(简称is4)有两种初始化方式:

1 使用命令行安装is4模板

1)安装模板命令:dotnet new -i IdentityServer4.Templates

2)安装完成之后执行dotnet new命令如下图所示多出了一些模板

3)使用dotnet cli创建一个is4empty模板,is4项目初始化完成

注:也可以使用其他已经配置好的模板

2 创建空.net core项目进行配置

1) 选择好要创建的文件夹之后选择创建空模板:

2) 使用nuget添加is4的包

install-package IdentityService4

注:is4会顺带装上serilog

3) 创建一个Config.cs文件,文件内包含三个静态字段

public static IEnumerable<IdentityResource> Ids

定义身份资源

public static IEnumerable<ApiResource> Apis

定义Api资源

public static IEnumerable<Client> Clients

定义客户端

4) 定义我们的Api资源:

public static IEnumerable<ApiResource> Apis =>

new ApiResource[]

{

new ApiResource("api1","My Api")

};

其中api1为我们定义的资源名,后面客户端请求的时候需要用到,而My Api好像是显示名称基本用不到。

5) 定义客户端:

public static IEnumerable<Client> Clients =>

new Client[]

{

new Client(){

ClientId="client",

AllowedGrantTypes=GrantTypes.ClientCredentials,

ClientSecrets={

new Secret("secret".Sha256())

},

AllowedScopes={ "api1"}

}

};

ClientId:客户端的Id可以理解为用户名

AllowedGrantTypes:指定认证的类型,这里为ClientCredentials类型

ClientSecrets:可以片面理解为密码

AllowedScopes:这个客户端可以请求到哪些资源

6) 对is4进行配置

我们需要在ConfigureServices对is4进行注入,很简单只需要将config里面的三个字段注入到指定方法即可:

var builder = services.AddIdentityServer()

.AddInMemoryIdentityResources(Config.Ids)

.AddInMemoryApiResources(Config.Apis)

.AddInMemoryClients(Config.Clients);

7) 添加中间件

我们目前只需要错误页中间件和is4中间件即可

if (Environment.IsDevelopment())

{

app.UseDeveloperExceptionPage();

}

app.UseIdentityServer();

至此为止我们is4已经配置完成,可以启动项目,访问http://localhost:5000/.well-known/openid-configuration,如果页面显示一大堆json那么证明我们成功了。

Api

1) 创建Api项目过程不在赘述,项目创建完成之后,在launchSettings.json 文件中将Api的启动端口设置5001,避免与is4项目冲突。

2) 添加依赖包:

程序依赖于Microsoft.AspNetCore.Authentication.JwtBearer按照添加is4包的方式添加。

3) 创建控制器

因为用于测试所以我们Home下只存在一个Index方法,并且在Index方法中打印出所有的Claims信息。

整个home应该是这样的:

[Route("api/[controller]")]

[ApiController]

[Authorize]  //加上认证特性

public class IdentityController : ControllerBase{

[HttpGet]

public IActionResult Get()

{

return new JsonResult(from c in User.Claims select new { c.Type, c.Value });

}

}

4) ConfigureServices与Configure

首先需要定义一个名叫Bearer的Jwt认证方案

services.AddAuthentication("Bearer")

.AddJwtBearer("Bearer", options =>

{

options.Authority = "http://localhost:5000";

options.RequireHttpsMetadata = false;

options.Audience = "api1";

});

Authority:规定jwt必须由http://localhost:5000发放

RequireHttpsMetadata:规定权限地址是否需要https,因为项目还没有使用https所以为false

Audience:请求的资源名称。 这个我感觉我理解的有问题,请各位指正

Configure中添加中间件:

app.UseAuthentication();

app.UseAuthorization();

至此我们已经写好了Api,只差最后的客户端。

客户端

ClientCredentials模式一般用于服务器与服务器之间身份验证所以我们创建一个控制台进行模拟。首先我们需要安装IdentityModel包,然后当我们需要访问Api时需要做一下操作:

1)请求发现文档

var client = new HttpClient();

var disco=await

client.GetDiscoveryDocumentAsync("http://localhost:5000");

返回值为一个类,类的属性存储对应处理方法的地址

2)获取一个token

var tokenResponse = await

client.RequestClientCredentialsTokenAsync(

new ClientCredentialsTokenRequest() {

Address=disco.TokenEndpoint,

ClientId= "client",

ClientSecret= "secret",

Scope= "api1"

});

注:需要设置id(账号),secret(密码),scope(要请求的资源名称),其返回值时一个token

3)给httpclient设置头

client.SetBearerToken(tokenResponse.AccessToken);

4)请求Api,打印出返回的值

var response = await

client.GetAsync("http://localhost:5001/api/Identity");

var content = await response.Content.ReadAsStringAsync();

Console.WriteLine(JArray.Parse(content));

5) 打印结果:

总结

is4中配置时设定的clientid,ClientSecrets,资源名称等,要与客户端请求/api验证对应起来

is4中config的三个字段要定义完整

各个程序记得按顺序写好中间件

发现文档中有所有的地址

客户端请求时要记得设置http头

本文仅用于个人笔记,如果有错误请各位指正,谢谢!

IdentityService4学习笔记之Client Credentials的更多相关文章

  1. [No000091]SVN学习笔记2-TortoiseSVN Client初级操作update(获取)、commit(提交)

    SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...

  2. redis 学习笔记(2)-client端示例代码

    redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 <dependency> <groupId>redi ...

  3. IdentityService4学习笔记之Authorization Code

    前文 本文所有内容来自官方文档,如果有写不明白的地方请下方留言或查看官方文档. 今天介绍Authorization Code模式,适用于保密类型的客户端,保密类型客户端可以理解为在服务器端生成页面(比 ...

  4. go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用)

    目录 go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用) warden direct demo-server gr ...

  5. OAuth2.0学习(1-7)授权方式4-客户端模式(Client Credentials Grant)

    授权方式4-客户端模式(Client Credentials Grant) 客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提 ...

  6. gPRC学习笔记

    gPRC学习笔记 gPRC基础教程. gPRC官方文档. protobuf 3.0的简易教程. 什么是RPC RPC(remote procedure call) -- 远程过程调用(相对于本地调用的 ...

  7. Cobalt Strike学习笔记

    Cobalt Strike 一款以metasploit为基础的GUI的框架式渗透测试工具,集成了端口转发.服务扫描,自动化溢出,多模式端口监听,win exe木马生成,win dll木马生成,java ...

  8. OAuth 2.0学习笔记

    文章目录 OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动. OAuth在"客户端&quo ...

  9. SpringBoot学习笔记(十五:OAuth2 )

    @ 目录 一.OAuth 简介 1.什么是OAuth 2.OAuth 角色 3.OAuth 授权流程 4.OAuth授权模式 4.1.授权码 4.2.隐藏式 4.3.密码式 4.4.凭证式 二.实践 ...

随机推荐

  1. Lodash 严重安全漏洞背后 你不得不知道的 JavaScript 知识

    摘要: 详解原型污染. 原文:Lodash 严重安全漏洞背后 你不得不知道的 JavaScript 知识 作者:Lucas HC Fundebug经授权转载,版权归原作者所有. 可能有信息敏感的同学已 ...

  2. RPC 初识

    RPC是什么 RPC(Remote Procedure Call) 释义是远程过程调用,常存在于分布式系统中. 比如说现在有两台服务器A, B,一个在A服务器上的应用想要调用B服务器上的应用提供的某个 ...

  3. day 35

    目录 单表操作 分组 group by having order by limit 使用顺序 多表操作 外键 一对多 多对多 一对一 多表联查 单表操作 分组 group by 分组指的是:将所有记录 ...

  4. Ubuntu14 关机重启、版本、网络、防火墙

    关机.重启: 立即关机:halt.poweroff.shutdown -h now 延迟关机:shutdown -h 10  十分钟后关机 立即重启:reboot.shutdown -r now 延迟 ...

  5. Vue-router路由传参的三种方式

    本文简单介绍下三种路由传参: (1)在路由中配置 { path : ‘/home/:id’, name : ‘Dome’, component } 然后写调用的时候 this.$router.push ...

  6. JS高阶---闭包应用(自定义JS模块)

    [自定义JS模块] [闭包案例] (1)案例1 对应的模块文件 (2)案例2---使用匿名函数 对应的模块文件 案例2分析:因为内部函数引用了外部函数的变量,且存在嵌套关系,所以是闭包,分析结构图如下 ...

  7. JS onFocus和onBlur

    onFocus事件就是当光标落在文本框中时发生的事件. onBlur事件是光标失去焦点时发生的事件. <form action="/chat" method="ge ...

  8. 01-numpy-笔记-empty

    import numpy as np >>> a = np.empty([2,3]) >>> a array([[0.00000000e+000, 4.935933 ...

  9. Session技术

    Session 学习: 问题: Request 对象解决了一次请求内的不同 Servlet 的数据共享问 题,那么一个用户的不同请求的处理需要使用相同的数据怎么办呢? 解决: 使用 session 技 ...

  10. 数据结构——栈与递归(recursion)

    /* recursion.c */ /* 递归 */ #include <stdio.h> void interface(void); /* 斐波那契数列以及阶乘函数声明 */ long ...