.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网关的概念. 本系列教程 ...
随机推荐
- Spring Bean前置后置处理器的使用
Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...
- JVM详解之:运行时常量池
目录 简介 class文件中的常量池 运行时常量池 静态常量详解 String常量 数字常量 符号引用详解 String Pool字符串常量池 总结 简介 JVM在运行的时候会对class文件进行加载 ...
- 阿里面试官:这些软件测试面试题都答对了,I want you!
[ 你悄悄来,请记得带走一丝云彩 ] 测试岗必知必会 01请描述如何划分缺陷与错误严重性和优先级别? 给软件缺陷与错误划分严重性和优先级的通用原则: 1. 表示软件缺陷所造成的危害和恶劣程度. 2. ...
- 使用 maven 创建项目模板
前言 配置 demo 工程 生成模板 生成项目 上传模板到仓库 参看链接 前言 微服务的概念越来越流行,随着服务粒度越来越细,拆分的模块越来越明确,我们的工程项目也变得越来越多. 有时候一个项目搭建, ...
- Java冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序
冒泡排序 冒泡排序是一种简单的排序算法.它重复地走访过要排序地数列,一次比较两个元素,如果它们地顺序错误就把它们交换过来.走访数列地工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. ...
- 167两数之和II-输入有序数组
from typing import List# 这道题很容易能够想到,只需要遍历两边列表就可以了# 两层循环class Solution: def twoSum(self, numbers: Lis ...
- Jmeter(十八) - 从入门到精通 - JMeter后置处理器 -下篇(详解教程)
1.简介 后置处理器是在发出“取样器请求”之后执行一些操作.取样器用来模拟用户请求,有时候服务器的响应数据在后续请求中需要用到,我们的势必要对这些响应数据进行处理,后置处理器就是来完成这项工作的.例如 ...
- ISE第三方编辑器的使用
刚开始使用ISE时候感觉ISE自带的编辑器并没有什么难用的,但是在看到了小梅哥的视频教学中那样行云流水般的操作让我心动不已,由此找到了相关的编辑器.为了以后看着方便直接摘取了前人的经验在我自己的博客中 ...
- Thinkphp5-0-X远程代码执行漏洞分析(2019-1-11)
周五下午爆洞能不能让人们好好休个周末! 分析过程 本次漏洞关键位置:/thinkphp/library/think/Request.php,lines:501由图可以看到在method函数中引入了可控 ...
- php实现导出数据分类合并单元格功能
<?php $conn = mysql_connect("localhost","root","root"); $db = mysql ...