上篇文章【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis 我们介绍了网关使用
Redis
进行缓存,并介绍了如何进行缓存实现,缓存信息清理接口的使用。本篇我们将介绍如何实现网关自定义客户端授权,实现可以为不同的接入客户端设置不同的访问权限。.netcore项目实战交流群(637326624),有兴趣的朋友可以在群里交流讨论。
一、功能描述
网关重点功能之一鉴权,需要实现对不同的客户端进行授权访问,禁止访问未经授权的路由地址,且需要对无权访问的请求,返回通用的格式。
比如网关有1-10个可用路由,客户端A只能访问1-5,客户端B只能访问6-10,这时我们就无法通过Ocelot
配置授权来进行自定义认证,这块就需要我们增加自定义的认证管道来实现功能,尽量不影响网关已有的功能。
下面我们就该功能如何实现展开讲解,希望大家先理解下功能需求,然后在延伸到具体实现。
二、数据库设计
我在第三章 网关篇-数据库存储配置(1)中讲解了我们网关配置信息设计,本篇将在那个基础上增加客户端认证需要用到的表的相关设计,设计客户端授权结构如下。其中客户端使用的IdentityServer4
客户端表结构。
设计好概念模型后,我们生成物理模型,然后生成数据库脚本。
设计思想为可以添加自定义的授权组,为每一个授权分配能够访问的路由,然后为网关授权的客户端分配一个或多个授权组,每次客户端请求时,如果路由设置了授权访问,就校验客户端是否存在路由访问权限,如果无访问权限,直接返回401未授权提醒。
感觉是不是很简单呢?有了这个自定义的客户端认证,那么我们后端服务可以专注于自己的业务逻辑而无需再过多了进行权限处理了。
三、功能实现
1、功能开启配置
网关应该支持自定义客户端授权中间件是否启用,因为一些小型项目是不需要对每个客户端进行单独授权的,中型和大型项目才有可能遇到自定义配置情况,所以我们需要在配置文件增加配置选项。在AhphOcelotConfiguration.cs
配置类中增加属性,默认不开启,而且需要知道客户端标识名称。
那我们如何把自定义的授权增加到网关流程里呢?这块我们就需要订制自己的授权中间件。
2、实现客户端授权中间件
首先我们定义一个自定义授权中间件AhphAuthenticationMiddleware
,需要继承OcelotMiddleware
,然后我们要实现Invoke
方法,详细代码如下。
有了这个中间件,那么如何添加到Ocelot的管道里呢?这里就需要查看Ocelot源代码了,看是如何实现管道调用的,OcelotMiddlewareExtensions
实现管道部分如下,BuildOcelotPipeline
里具体的流程。其实我在之前的Ocelot源码解读里也讲解过原理了,奈斯,既然找到了,那么我们就加入我们自定义的授权中间件即可。
添加使用自定义授权中间件扩展AhphAuthenticationMiddlewareExtensions
,代码如下。
有了这个中间件扩展后,我们就在管道的合适地方加入我们自定义的中间件。我们添加我们自定义的管道扩展OcelotPipelineExtensions
,然后把自定义授权中间件加入到认证之后。
有了这个自定义的管道扩展后,我们需要应用到网关启动里,修改我们创建管道的方法如下。
代码很简单,就是从缓存中查找看是否有数据,如果存在直接返回,如果不存在,就从仓储中提取访问权限,然后写入缓存,写入缓存的时间可由配置文件写入,默认为30分钟,可自行根据业务需要修改。
现在我们还需要解决2个问题,这个中间件才能正常运行,第一IClientAuthenticationRepository
接口未实现和注入;第二IOcelotCache<ClientRoleModel>
未注入,那我们接下来实现这两块,然后就可以测试我们第一个中间件啦。
新建SqlServerClientAuthenticationRepository
类,来实现IClientAuthenticationRepository
接口,实现代码如下。
现在需要注入下实现,这块应该都知道在哪里加入了吧?没错ServiceCollectionExtensions
扩展又用到啦,现在梳理下流程感觉是不是很清晰呢?
builder.Services.AddSingleton<IClientAuthenticationRepository, SqlServerClientAuthenticationRepository>();builder.Services.AddSingleton<IAhphAuthenticationProcessor, AhphAuthenticationProcessor>();
再添加缓存的注入实现,到此我们的第一个中间件全部添加完毕了,现在可以开始测试我们的中间件啦。
builder.Services.AddSingleton<IOcelotCache<ClientRoleModel>, InRedisCache<ClientRoleModel>>();
4、测试授权中间件
我们先在数据库插入客户端授权脚本,脚本如下。
这块设置了客户端2可以访问路由/cjy/values
,客户端1可以访问路由/cjy/values 和 /ctr/values/{id}
,开始使用PostMan
来测试这个中间件看是否跟我设置的一毛一样,各种dotnet run
启动吧。启动前别忘了在我们网关配置文件里,设置启动客户端授权 option.ClientAuthorization = true;
,是不是很简单呢?
为了测试授权效果,我们需要把网关项目增加认证,详细看代码,里面就是定义了授权认证,启动我们默认的认证地址。
测试结果如下,达到我们预期目的。
终于完成了我们的自定义客户端授权啦,此处应该掌声不断。
5、增加mysql支持
看过我前面的文章应该知道,支持mysql
太简单啦,直接重写IClientAuthenticationRepository
实现,然后注入到UseMySql
里,问题就解决啦。感觉是不是不可思议,这就是.netcore
的魅力,简单到我感觉到我再贴代码就是侮辱智商一样。
6、重构认证失败输出,保持与Ocelot一致风格
前面我们定义了未授权使用自定义的ClientRoleModel
输出,最后发现这样太不优雅啦,我们需要简单重构下,来保持与Ocelot
默认管道一致风格,修改代码如下。
再测试下未授权,返回状态为401,强迫症患者表示舒服多了。
四、总结及预告
本篇我们讲解的是网关如何实现自定义客户端授权功能,从设计到实现一步一步详细讲解,虽然只用一篇就写完了,但是涉及的知识点还是非常多的,希望大家认真理解实现的思想,看我是如何从规划到实现的,为了更好的帮助大家理解,从本篇开始,我的源代码都是一个星期以后再开源,大家可以根据博客内容自己手动实现下,有利于消化,如果在操作中遇到什么问题,可以加.NET Core项目实战交流群(QQ群号:637326624)
咨询作者。
下一篇开始讲解自定义客户端限流,在学习下篇前可以自己先了解下限流相关内容,然后自己试着实现看看,带着问题学习可能事半功倍哦。
相关文章:
AspNetCore中使用Ocelot之 IdentityServer4
Ocelot-基于.NET Core的开源网关实现
.NET Core微服务之基于Ocelot+IdentityServer实现统一验证与授权
Swagger如何访问Ocelot中带权限验证的API
Ocelot.JwtAuthorize:一个基于网关的Jwt验证包
.NET Core微服务之基于Ocelot实现API网关服务
.NET Core微服务之基于Ocelot实现API网关服务(续)
.NET微服务体系结构中为什么使用Ocelot实现API网关
Ocelot简易教程(一)之Ocelot是什么
Ocelot简易教程(二)之快速开始1
Ocelot简易教程(二)之快速开始2
Ocelot简易教程(三)之主要特性及路由详解
Ocelot简易教程(四)之请求聚合以及服务发现
Ocelot简易教程(五)之集成IdentityServer认证以及授权
Ocelot简易教程(六)之重写配置文件存储方式并优化响应数据
Ocelot简易教程(七)之配置文件数据库存储插件源码解析
ASP.NET Core中Ocelot的使用:API网关的应用
ASP.NET Core中Ocelot的使用:基于Spring Cloud Netflix Eureka的动态路由
ASP.NET Core中Ocelot的使用:基于服务发现的负载均衡
【.NET Core项目实战-统一认证平台】第一章 功能及架构分析
定制Ocelot来满足需求
【.NET Core项目实战-统一认证平台】第三章 网关篇-数据库存储配置(1)
【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置(2)
【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis
原文地址: https://www.cnblogs.com/jackcao/p/9973765.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com