.NET Core-统一认证平台之自定义客户端授权(6)

一、功能描述

网关重点功能之一鉴权,需要实现对不同的客户端进行授权访问,禁止访问未经授权的路由地址,且需要对无权访问的请求,返回通用的格式。
比如网关有1-10个可用路由,客户端A只能访问1-5,客户端B只能访问6-10,这时我们就无法通过Ocelot配置授权来进行自定义认证,这块就需要我们增加自定义的认证管道来实现功能,尽量不影响网关已有的功能。

下面我们就该功能如何实现展开讲解,希望大家先理解下功能需求,然后在延伸到具体实现。

二、数据库设计

我在第三章 网关篇-数据库存储配置(1)中讲解了我们网关配置信息设计,本篇将在那个基础上增加客户端认证需要用到的表的相关设计,设计客户端授权结构如下。其中客户端使用的IdentityServer4客户端表结构。
【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

设计好概念模型后,我们生成物理模型,然后生成数据库脚本。

设计思想为可以添加自定义的授权组,为每一个授权分配能够访问的路由,然后为网关授权的客户端分配一个或多个授权组,每次客户端请求时,如果路由设置了授权访问,就校验客户端是否存在路由访问权限,如果无访问权限,直接返回401未授权提醒。

感觉是不是很简单呢?有了这个自定义的客户端认证,那么我们后端服务可以专注于自己的业务逻辑而无需再过多了进行权限处理了。

三、功能实现

1、功能开启配置

网关应该支持自定义客户端授权中间件是否启用,因为一些小型项目是不需要对每个客户端进行单独授权的,中型和大型项目才有可能遇到自定义配置情况,所以我们需要在配置文件增加配置选项。在AhphOcelotConfiguration.cs配置类中增加属性,默认不开启,而且需要知道客户端标识名称。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

那我们如何把自定义的授权增加到网关流程里呢?这块我们就需要订制自己的授权中间件。

2、实现客户端授权中间件

首先我们定义一个自定义授权中间件AhphAuthenticationMiddleware,需要继承OcelotMiddleware,然后我们要实现Invoke方法,详细代码如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

有了这个中间件,那么如何添加到Ocelot的管道里呢?这里就需要查看Ocelot源代码了,看是如何实现管道调用的,OcelotMiddlewareExtensions实现管道部分如下,BuildOcelotPipeline里具体的流程。其实我在之前的Ocelot源码解读里也讲解过原理了,奈斯,既然找到了,那么我们就加入我们自定义的授权中间件即可。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

添加使用自定义授权中间件扩展AhphAuthenticationMiddlewareExtensions,代码如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

有了这个中间件扩展后,我们就在管道的合适地方加入我们自定义的中间件。我们添加我们自定义的管道扩展OcelotPipelineExtensions,然后把自定义授权中间件加入到认证之后。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

有了这个自定义的管道扩展后,我们需要应用到网关启动里,修改我们创建管道的方法如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

代码很简单,就是从缓存中查找看是否有数据,如果存在直接返回,如果不存在,就从仓储中提取访问权限,然后写入缓存,写入缓存的时间可由配置文件写入,默认为30分钟,可自行根据业务需要修改。

现在我们还需要解决2个问题,这个中间件才能正常运行,第一IClientAuthenticationRepository接口未实现和注入;第二IOcelotCache<ClientRoleModel>未注入,那我们接下来实现这两块,然后就可以测试我们第一个中间件啦。

新建SqlServerClientAuthenticationRepository类,来实现IClientAuthenticationRepository接口,实现代码如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

现在需要注入下实现,这块应该都知道在哪里加入了吧?没错ServiceCollectionExtensions扩展又用到啦,现在梳理下流程感觉是不是很清晰呢?

builder.Services.AddSingleton<IClientAuthenticationRepository, SqlServerClientAuthenticationRepository>();builder.Services.AddSingleton<IAhphAuthenticationProcessor, AhphAuthenticationProcessor>();

再添加缓存的注入实现,到此我们的第一个中间件全部添加完毕了,现在可以开始测试我们的中间件啦。

builder.Services.AddSingleton<IOcelotCache<ClientRoleModel>, InRedisCache<ClientRoleModel>>();

4、测试授权中间件

我们先在数据库插入客户端授权脚本,脚本如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

这块设置了客户端2可以访问路由/cjy/values,客户端1可以访问路由/cjy/values 和 /ctr/values/{id},开始使用PostMan来测试这个中间件看是否跟我设置的一毛一样,各种dotnet run启动吧。启动前别忘了在我们网关配置文件里,设置启动客户端授权 option.ClientAuthorization = true;,是不是很简单呢?

为了测试授权效果,我们需要把网关项目增加认证,详细看代码,里面就是定义了授权认证,启动我们默认的认证地址。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

测试结果如下,达到我们预期目的。
【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权
【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权


终于完成了我们的自定义客户端授权啦,此处应该掌声不断。


5、增加mysql支持

看过我前面的文章应该知道,支持mysql太简单啦,直接重写IClientAuthenticationRepository实现,然后注入到UseMySql里,问题就解决啦。感觉是不是不可思议,这就是.netcore的魅力,简单到我感觉到我再贴代码就是侮辱智商一样。

6、重构认证失败输出,保持与Ocelot一致风格

前面我们定义了未授权使用自定义的ClientRoleModel输出,最后发现这样太不优雅啦,我们需要简单重构下,来保持与Ocelot默认管道一致风格,修改代码如下。

【.NET Core项目实战-统一认证平台】第六章 网关篇-自定义客户端授权

再测试下未授权,返回状态为401,强迫症患者表示舒服多了。


未经允许不得转载:996ICU » .NET Core-统一认证平台之自定义客户端授权(6)

赞 (0) 打赏