【WebAPI No.3】API的访问控制IdentityServer4
介绍:
IdentityServer是一个OpenID Connect提供者 - 它实现了OpenID Connect和OAuth 2.0协议。是一种向客户发放安全令牌的软件。
官网给出的功能解释是:
- 保护您的资源
- 使用本地帐户存储或通过外部身份提供商对用户进行身份验证
- 提供会话管理和单点登录
- 管理和认证客户
- 向客户发布身份和访问令牌
- 验证令牌
IdentityServe4的四种模式:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
以下是IdentityServer的一个大致流程图:

注册IdentityServe4认证服务器:
先在asp.net core我们选中空模版。因为本身写的业务也不多,只是为了做token的认证处理,所有建这个做测试比较方便。

创建代码示例:
什么时候都不要忘记添加引用哦:
NuGet命令行:Install-Package IdentityServer4
当然你也可以这样:

然后创建config.cs类来处理我们的一些业务:
//定义范围
#region 定义要保护的资源(webapi)
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("FirstAPI", "API接口安全测试")
};
}
#endregion #region 定义可访问客户端
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
//客户端id自定义
ClientId = "YbfTest", AllowedGrantTypes = GrantTypes.ClientCredentials, ////设置模式,客户端模式 // 加密验证
ClientSecrets = new List<Secret>
{
new Secret("secret".Sha256())
}, // client可以访问的范围,在GetScopes方法定义的名字。
AllowedScopes = new List<string>
{
"FirstAPI"
}
}
};
}
#endregion
以上就是一个基本的处理类了。然后我们开始在Startup.cs 配置IdentityServer4:
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources()) //配置资源
.AddInMemoryClients(Config.GetClients());//配置客户端
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//将IddiTyServer添加到管道中。
app.UseIdentityServer(); app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
这样就可以启动项目了,确认项目启动完成后,还要确认服务是否开启成功:在地址后增加地址:/.well-known/openid-configuration 例如:

出现以上结果就是启动成功了。
当然你也可以使用postMan测试工具测试:
需要输入
grant_type为客户端授权client_credentials,client_id为Config中配置的ClientIdClient_Secret为Config中配置的Secret
例如:

创建webAPI资源服务器
这个比较简单了,首先创建一个简单的webapi程序即可。
还是老规矩咯iuput,什么时候都不要忘记引用:
通过nuget添加即可:IdentityServer4.AccessTokenValidation

然后点击确定安装就可以了。
主要认证注册服务:
在Startup类里面的ConfigureServices方法里面添加注册
public void ConfigureServices(IServiceCollection services)
{
//注册IdentityServer
services.AddAuthentication(config => {
config.DefaultScheme = "Bearer"; //这个是access_token的类型,获取access_token的时候返回参数中的token_type一致
}).AddIdentityServerAuthentication(option => {
option.ApiName = "FirstAPI"; //资源名称,认证服务注册的资源列表名称一致,
option.Authority = "http://127.0.0.1:5000"; //认证服务的url
option.RequireHttpsMetadata = false; //是否启用https });
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
然后在在Startup的Configure方法里配置Authentication中间件:
//配置Authentication中间件
app.UseAuthentication();
然后添加一个控制器进行验证测试:
我这里写了一个获取value值简单检测一下。
// GET api/values
[HttpGet]
[Authorize]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
这里注意要添加[Authorize]特性。用来做验证是否有权限的。没有的话,以上做的没有意义。需要引用命名空间:using Microsoft.AspNetCore.Authorization;
看一下正确的请求结果:

如果不传token值请求:

注意这里就会返回401的未授权状态。
创建Client(客户端)
上面我们使用的是postman请求的以演示程序是否创建成功,这里我们假设一个用户的使用客户端,这里我们创建一个控制台来模拟一下真实的小场景。
既然是控制台就没什么好说的直接上代码main函数:
Task.Run(async () =>
{
//从元数据中发现终结点,查找IdentityServer
var disco = await DiscoveryClient.GetAsync("http://127.0.0.1:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
} //向IdentityServer请求令牌
var tokenClient = new TokenClient(disco.TokenEndpoint, "YbfTest", "YbfTest123");//请求的客户资源
var tokenResponse = await tokenClient.RequestClientCredentialsAsync("FirstAPI");//运行的范围 if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
} Console.WriteLine(tokenResponse.Json); //访问Api
var client = new HttpClient();
//把令牌添加进请求
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken);
//client.SetBearerToken(tokenResponse.AccessToken);
client.SetToken("Bearer", tokenResponse.AccessToken); var response = await client.GetAsync("http://localhost:42033/api/values");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
}); Console.ReadLine();
这里主要介绍一下请求资源时添加令牌主要有三种形式,我都在代码给出,根据api资源的注册形式选择适合的。api的注册我也写了两种形式。主要的区别就是token前面的Bearer,如果想写成自定义的和默认成Bearer就是这里的区分。
自定义就要使用:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",tokenResponse.AccessToken);
如果全局默认的形式就不比每次请求都要添加所以可以写成:
client.SetBearerToken(tokenResponse.AccessToken);
运行项目之后出现成功界面:

传送门
【WebAPI No.3】API的访问控制IdentityServer4的更多相关文章
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(二)
上文已经介绍了Identity Service的实现过程.今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关. 回顾 <Angular SPA基于Ocelot ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(四)
在上一讲中,我们已经完成了一个完整的案例,在这个案例中,我们可以通过Angular单页面应用(SPA)进行登录,然后通过后端的Ocelot API网关整合IdentityServer4完成身份认证.在 ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(三)
在前面两篇文章中,我介绍了基于IdentityServer4的一个Identity Service的实现,并且实现了一个Weather API和基于Ocelot的API网关,然后实现了通过Ocelot ...
- MVC4 WebAPI(二)——Web API工作方式
http://www.cnblogs.com/wk1234/archive/2012/05/07/2486872.html 在上篇文章中和大家一起学习了建立基本的WebAPI应用,立刻就有人想到了一些 ...
- MVC4.0 WebApi如何设置api支持namespace
1.自定义HttpControllerSelector /// <summary> /// 设置api支持namespace /// </summary> public cla ...
- WebApi生成在线API文档--Swagger
1.前言 1.1 SwaggerUI SwaggerUI 是一个简单的Restful API 测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON 配置显示API. 项目本身仅仅也只依赖 ...
- java EE技术体系——CLF平台API开发注意事项(3)——API安全访问控制
前言:提离职了,嗯,这么多年了,真到了提离职的时候,心情真的很复杂.好吧,离职阶段需要把一些项目中的情况说明白讲清楚,这篇博客就简单说一下在平台中对API所做的安全处理(后面讲网关还要说,这里主要讲代 ...
- Swagger实现API文档功能
介绍: wagger也称为Open API,Swagger从API文档中手动完成工作,并提供一系列用于生成,可视化和维护API文档的解决方案.简单的说就是一款让你更好的书写API文档的框架. 我们为什 ...
随机推荐
- CIKM 2012 papers to be downloaded
http://dl.acm.org/citation.cfm?id=2398426 http://dl.acm.org/citation.cfm?id=2396825 http://dl.ac ...
- Mesos源码分析(8): Mesos-Slave的初始化
Mesos-Slave的初始化在文件src/slave/slave.cpp里面 首先初始化资源预估器 初始化attributes 初始化hostname 初始化status ...
- 别以为真懂Openstack: 虚拟机创建的50个步骤和100个知识点(2)
二.nova-api 步骤3:nova-api接收请求 nova-api接收请求,也不是随便怎么来都接收的,而是需要设定rate limits,默认的实现是在ratelimit的middleware里 ...
- 【RL-TCPnet网络教程】第27章 DNS域名系统基础知识
第27章 DNS域名系统基础知识 本章节为大家讲解DNS(Domain Name System,域名系统),通过前面章节对TCP和UDP的学习,需要大家对DNS也有个基础的认识. (本章的知 ...
- 【安富莱原创开源应用第1期】花式玩转网络摄像头之TCP上位机软件实现,高端大气上档次,速度2MB/S,华丽丽的界面效果
说明:1.例子是两年前做的,一直没有顾上整理出来,今天特地整理出来,开源出来给大家玩.2.上位机是emWin模拟器开发的,大家估计很难猜到,所以你会emWin话的,就可以轻松制作上位机.做些通信和控制 ...
- Redis sortedset实现元素自动过期
这里的自动过期,Redis并没有提供相应的api,但是可以使用一下方法来实现. 需求背景: 给用户返回的文章要求七日内不能重复:文章是存放在java list里边:(这一块就是从db将文章拿出来,然后 ...
- [Swift]LeetCode705. 设计哈希集合 | Design HashSet
Design a HashSet without using any built-in hash table libraries. To be specific, your design should ...
- mysql与PHP建立连接实现增删查改
mysql与PHP连接的查询写法: <?php //1.建立与数据库的连接 //类似于宽字符集问题,mysqli是额外的扩展 //需要找到配置文件去开启扩展 //如果需要在调用函数 之前忽略错误 ...
- 构建multipart/form-data实现文件上传
构建multipart/form-data实现文件上传 通常文件上传都是通过form表单中的file控件,并将form中的content-type设置为multipart/form-data.现在我们 ...
- Pycharm、IDEA等汉化教程
本汉化教程对jetbrains全系列可用:IDEA.Pycharm.WebStorm.phpstorm.AndroidStudio.GoLand.RubyMine.CLion 此汉化无副作用,绝对安全 ...