.NET Core 微服务—API网关(Ocelot) 教程 [三]
前言:
前一篇文章《.NET Core 微服务—API网关(Ocelot) 教程 [二]》已经让Ocelot和目录api(Api.Catalog)、订单api(Api.Ordering)通过网关方式运行起来了。但在日常开发中Api并不是所有人都能访问的,是添加了认证、授权的。那么本篇文章就将继续介绍Ocelot如何和 IdentityServer4 认证服务如何配合使用的。
创建认证服务(Api.IdentityServer)
1、创建一个空的WebApi项目-Api.IdentityServer,并添加IdentityServer4项目引用:如下图:
Install-Package IdentityServer4

2、要启用IdentityServer服务,不仅要把 IdentityServer 注册到容器中, 还需要配置一下内容:
- Authorization Server 保护了哪些 API (资源);
哪些客户端 Client(应用) 可以使用这个 Authorization Server;
指定可以使用 Authorization Server 授权的 Users(用户)
a) 创建文件 InMemoryConfig.cs,用于设置以上相关内容:

using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; namespace Api.IdentityServer
{
public class InMemoryConfig
{
public static IEnumerable<IdentityResource> GetIdentityResourceResources()
{
return new List<IdentityResource>
{
//必须要添加,否则报无效的scope错误
new IdentityResources.OpenId(),
};
} /// <summary>
/// api资源列表
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApiResources()
{
//可访问的API资源(资源名,资源描述)
return new List<ApiResource>
{
new ApiResource("Api.Catalog", "Api.Catalog"),
new ApiResource("Api.Ordering", "Api.Ordering")
};
} /// <summary>
/// 客户端列表
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "client_Catalog", //访问客户端Id,必须唯一
//使用客户端授权模式,客户端只需要clientid和secrets就可以访问对应的api资源。
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "Api.Catalog", IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
},
new Client
{
ClientId = "client_Ordering",
ClientSecrets = new [] { new Secret("secret".Sha256()) },
//这里使用的是通过用户名密码和ClientCredentials来换取token的方式. ClientCredentials允许Client只使用ClientSecrets来获取token. 这比较适合那种没有用户参与的api动作
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
AllowedScopes = { "Api.Ordering", IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile }
}
};
} /// <summary>
/// 指定可以使用 Authorization Server 授权的 Users(用户)
/// </summary>
/// <returns></returns>
public static IEnumerable<TestUser> Users()
{
return new[]
{
new TestUser
{
SubjectId = "",
Username = "cba",
Password = "abc"
}
};
}
}
}
GetApiResources:这里指定了name和display name, 以后api使用authorization server的时候, 这个name一定要一致
GetClients: 认证客户端列表
Users: 这里的内存用户的类型是TestUser, 只适合学习和测试使用, 实际生产环境中还是需要使用数据库来存储用户信息的, 例如接下来会使用asp.net core identity. TestUser的SubjectId是唯一标识.
b) 在Startup.cs中启用IdentityServer服务

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; namespace Api.IdentityServer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(); services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(InMemoryConfig.GetApiResources())
.AddInMemoryClients(InMemoryConfig.GetClients())
.AddTestUsers(InMemoryConfig.Users().ToList()); services.AddAuthentication();//配置认证服务
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseRouting(); app.UseIdentityServer(); app.UseAuthentication();
app.UseAuthorization(); app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
为ocelot项目集成IdentityServer
1、添加IdentityServer4.AccessTokenValidation的包,也可以通过程序包管理控制台执行以下命令
Install-Package IdentityServer4.AccessTokenValidation
添加包引用后,在Startup中的 ConfigureServices 中分别注册两个认证方案 Configure 中配置IdentityServer服务。
public void ConfigureServices(IServiceCollection services)
{ services.AddAuthentication()
.AddJwtBearer("Api.Catalog", i =>
{
i.Audience = "Api.Catalog";
i.Authority = "http://localhost:5332";
i.RequireHttpsMetadata = false;
}).AddJwtBearer("Api.Ordering", y =>
{
y.Audience = "Api.Ordering";
y.Authority = "http://localhost:5331";
y.RequireHttpsMetadata = false;
}); services.AddOcelot();//注入Ocelot服务 services.AddControllers();
}
2、修改ocelot配置文件,在Routes中添加授权信息
调整ApiGateway.Ocelot项目中ocelot.json配置文件如下:
{
"GlobalConfiguration": {
},
"Routes": [
{
"DownstreamPathTemplate": "/api/{controller}/{action}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port":
}
],
"UpstreamPathTemplate": "/Catalog/{controller}/{action}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
//授权信息
"AuthenticationOptions": {
"AuthenticationProviderKey": "Api.Catalog",
"AllowedScopes": []
}
},
{
"DownstreamPathTemplate": "/api/{controller}/{action}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port":
}
],
"UpstreamPathTemplate": "/Ordering/{controller}/{action}",
"UpstreamHttpMethod": [ "Get", "Post" ],
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
//授权信息
"AuthenticationOptions": {
"AuthenticationProviderKey": "Api.Ordering",
"AllowedScopes": []
}
}
]
}
Ocelot会去检查Routes是否配置了AuthenticationOptions节点。如果有会根据配置的认证方案进行身份认证。如果没有则不进行身份认证。
AuthenticationProviderKey 是刚才注册的认证方案。
AllowedScopes 是 AllowedScopes中配置的授权访问范围。
验证效果
1、根据网关设置访问:目录api:http://localhost:5330/Ordering/Values/1
如图:401 Unauthorized 未认证

2、先获取Token后再访问该接口:

根据获取Token在http://localhost:5330/Ordering/Values/1 请求时,添加认证头信息,即可请求成功

回顾总结
1、在IdentityServer注册相关资源服务和客户端信息。
2、Ocelot通过注册认证方案,在配置文件中指定路由的认证方案
3、该认证是在Ocelot网关层对相关资源进行认证,并非资源服务认证
4、认证调用失败时,尝试把IdentityServer包版本降低尝试
源码:https://github.com/cwsheng/ocelot.Demo.git
.NET Core 微服务—API网关(Ocelot) 教程 [三]的更多相关文章
- .NET Core 微服务—API网关(Ocelot) 教程 [二]
上篇文章(.NET Core 微服务—API网关(Ocelot) 教程 [一])介绍了Ocelot 的相关介绍. 接下来就一起来看如何使用,让它运行起来. 环境准备 为了验证Ocelot 网关效果,我 ...
- .NET Core 微服务—API网关(Ocelot) 教程 [一]
前言: 最近在关注微服务,在 eShop On Containers 项目中存在一个API网关项目,引起想深入了解下它的兴趣. 一.API网关是什么 API网关是微服务架构中的唯一入口,它提供一个单独 ...
- .NET Core 微服务—API网关(Ocelot) 教程 [四]
前言: 上一篇 介绍了Ocelot网关和认证服务的结合使用,本篇继续介绍Ocelot相关请求聚合和Ocelot限流 一.请求聚合 Ocelot允许声明聚合路由,这样可以把多个正常的Routes打包并映 ...
- .NET Core微服务二:Ocelot API网关
.NET Core微服务一:Consul服务中心 .NET Core微服务二:Ocelot API网关 .NET Core微服务三:polly熔断与降级 本文的项目代码,在文章结尾处可以下载. 本文使 ...
- .NET Core微服务之基于Ocelot实现API网关服务
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.啥是API网关? API 网关一般放到微服务的最前端,并且要让API 网关变成由应用所发起的每个请求的入口.这样就可以明显的简化客户端 ...
- .NET Core微服务之基于Ocelot实现API网关服务(续)
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.负载均衡与请求缓存 1.1 负载均衡 为了验证负载均衡,这里我们配置了两个Consul Client节点,其中ClientServic ...
- .NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.案例结构总览 这里,假设我们有两个客户端(一个Web网站,一个移动App),他们要使用系统,需要通过API网关(这里API网关始终作为 ...
- .NET Core微服务之基于Ocelot+Butterfly实现分布式追踪
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.什么是Tracing? 微服务的特点决定了功能模块的部署是分布式的,以往在单应用环境下,所有的业务都在同一个服务器上,如果服务器出现错 ...
- 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul
通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...
随机推荐
- ShaderLab-坐标转换
观察空间就是相机的空间 投影矩阵本质就是对x.y.z分量进行不同程度的缩放(z还做了平移),结果就是视锥体近切面远切面变成正方形.视锥体的中心在(0,0). (对于正交相机,这一步已经得到了立方体) ...
- C++中类继承public,protected和private关键字作用详解及派生类的访问权限
注意:本文有时候会用Visual Studio Code里插件的自动补全功能来展示访问权限的范围(当且仅当自动补全范围等价于对象访问权限范围的时候),但是不代表只要是出现在自动补全范围内的可调用对象/ ...
- Python过滤掉numpy.array中非nan数据实例
代码 需要先导入pandas arr的数据类型为一维的np.array import pandas as pd arr[~pd.isnull(arr)] 补充知识:python numpy.mean( ...
- Linux字符集的查看及修改[转]
一·查看字符集字符集在系统中体现形式是一个环境变量,以CentOS6.5为例,其查看当前终端使用字符集的方式可以有以下几种方式: 1.[root@david ~]# echo $LANGzh_CN.G ...
- 图表可视化seaborn风格和调色盘
seaborn是基于matplotlib的python数据可视化库,提供更高层次的API封装,包括一些高级图表可视化等工具. 使用seaborn需要先安装改模块pip3 install seaborn ...
- OceanBase安装和使用
链接 https://mp.weixin.qq.com/s?spm=a2c6h.12873639.0.0.41f92c9bH5FL2Y&__biz=MzU3OTc2MDQxNg==&m ...
- pandas_DateFrame的创建
# DateFrame 的创建,包含部分:index , column , values import numpy as np import pandas as pd # 创建一个 DataFrame ...
- Python os.mknod() 方法
概述 os.mknod() 方法用于创建一个指定文件名的文件系统节点(文件,设备特别文件或者命名pipe).高佣联盟 www.cgewang.com 语法 mknod()方法语法格式如下: os.mk ...
- Python 字典(Dictionary) type()方法
Python 字典(Dictionary) type()方法 描述 Python 字典(Dictionary) type() 函数返回输入的变量类型,如果变量是字典就返回字典类型.高佣联盟 www.c ...
- PHP flock() 函数
定义和用法 flock() 函数锁定或释放文件. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 flock(file,lock,block) 参数 描述 file 必需.规定要 ...