前言

目前公司采用的开发框架是ABP VNext微服务框架

最近突然发现一个问题,ABP中如果控制器或服务层没有加 Authorize特性的话,则不会走身份认证,且不会认证Token

如图:

但是项目已开发大半,一个个去补Authorize特性,工作量比较大,也容易产生遗漏

就想着以前做单体应用的时候,有个全局添加特性的方法,也就是如下代码:

Services.AddMvc(setupAction =>
{
setupAction.Filters.Add<AuthorizeFilter>();
});

本以为这样就万事大吉了,没想到还有坑在里面..

我们都知道,ABP提供了服务间的动态API通讯功能,它的原理是先获取对应服务的描述,然后通过描述来访问对应的服务节点,

也就是 api/abp/api-definition 这个描述JSON

我们用以上的代码添加了全局授权之后会发现api-definition也被权限管控了,由于api-definition是由ABP框架自动生成的,我们也无法在这个终结点上添加类似  AllowAnonymous 的过滤特性

正文

那么应该如何解决这个问题呢?

首先想到的就是实现自己的授权特性,只需要继承 IAsyncAuthorizationFilter,即可

但是如果采用自己的AuthorizationFilter,则需要重写整个 OnAuthorizationAsync 事件.

ABP提供了角色之类的授权信息就都需要自行重写.

后来想到,可以继承AuthorizeFilter ,添加我们想要的过滤之后直接执行父类的方法,说干就干,我们继承AuthorizeFilter ,代码实现如下:

    public class AbpAuthorizeFilter : AuthorizeFilter
{ public AbpAuthorizeFilter()
: base()
{
} public override Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
//过滤动态API
if (context.HttpContext.Request.Path.Value.EndsWith("/api-definition"))
{
return Task.CompletedTask;
}
return base.OnAuthorizationAsync(context);
} }

可是当我们信心满满的把这个拦截器注入之后,会发现整个授权管道,压根就不走自己的这个重写方法.

找了很多资料,最终在官方的issues中找到了类似的疑问,Overrided OnAuthorizationAsync function from AuthorizeFilter can't work in customer class. · Issue #30025 · dotnet/aspnetcore (github.com)

是因为在.NET 5.0 之后,AuthorizeFilter继承了 IFilterFactory,所以在生成实例的时候其实是来自于IFilterFactory的CreateInstance方法, 我们没有重写这个方法,所以一直产生的还是AuthorizeFilter 实例

我们修改代码如下:

    public class AbpAuthorizeFilter2 : AuthorizeFilter
{ public AbpAuthorizeFilter2()
: base()
{
} public override Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
//过滤动态API
if (context.HttpContext.Request.Path.Value.EndsWith("/api-definition"))
{
return Task.CompletedTask;
}
return base.OnAuthorizationAsync(context);
} IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
return this;
}
}

运行后发现,在执行到这个拦截器的时候,就会报错,提示PolicyProvider 不能为空.  这就很纳闷了,最终选择去查看一下AuthorizeFilter的源码,aspnetcore/src/Mvc/Mvc.Core/src/Authorization/AuthorizeFilter.cs at 1bda10b33b6cc6f3bbaceabbadb4ddd18ca6e68e · dotnet/aspnetcore (github.com)

我们发现他这个PolicyProvider对象来自于IOC容器,且在CreateInstance方法中判断了这个类是否为空,如果为空则返回基类自己,代码如下:

IFilterMetadata IFilterFactory.CreateInstance(IServiceProvider serviceProvider)
{
if (Policy != null || PolicyProvider != null)
{
// The filter is fully constructed. Use the current instance to authorize.
return this;
} Debug.Assert(AuthorizeData != null);
var policyProvider = serviceProvider.GetRequiredService<IAuthorizationPolicyProvider>();
return AuthorizationApplicationModelProvider.GetFilter(policyProvider, AuthorizeData);
}

那我们就好办了,直接从IOC容器中拿到IAuthorizationPolicyProvider这个实现类,提供给基类即可,我们修改代码如下:

    public class AbpAuthorizeFilter:AuthorizeFilter
{ public AbpAuthorizeFilter(IServiceProvider serviceProvider)
: base(policyProvider: serviceProvider.GetRequiredService<IAuthorizationPolicyProvider>(), authorizeData: new[] { new AuthorizeAttribute() })
{
}
public void OnAuthorization(AuthorizationFilterContext context)
{
OnAuthorizationAsync(context);
} public override Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
//过滤动态API
if (context.HttpContext.Request.Path.Value.EndsWith("/api-definition"))
{
return Task.CompletedTask;
}
return base.OnAuthorizationAsync(context);
} }

然后修改HostModule中全局授权的方法如下(.NETCORE 是Startup)

context.Services.AddMvc(setupAction =>
{
//添加自定义的全局拦截器
setupAction.Filters.Add<AbpAuthorizeFilter>(); });

至此,我们就完成了过滤abp的描述控制器的工作.

后记

碰到奇葩问题,多看看官方源码还是有好处的,有些实现并不是想当然的东西,还是需要实践

ABP VNext添加全局认证(如何继承AuthorizeFilter)的更多相关文章

  1. [Abp vNext 源码分析] - 2. 模块系统的变化

    一.简要说明 本篇文章主要分析 Abp vNext 当中的模块系统,从类型构造层面上来看,Abp vNext 当中不再只是单纯的通过 AbpModuleManager 来管理其他的模块,它现在则是 I ...

  2. ABP VNext框架基础知识介绍(1)--框架基础类继承关系

    在我较早的时候,就开始研究和介绍ABP框架,ABP框架相对一些其他的框架,它整合了很多.net core的新技术和相关应用场景,虽然最早开始ABP框架是基于.net framework,后来也全部转向 ...

  3. [Abp vNext微服务实践] - 添加中文语言

    简介 abp vNext中提供了多语言功能,默认语言是英文,没有提供中文语言包.在业务开发中,定义权限后需要用中文的备注提供角色选择,本篇将介绍如何在abp vNext中加入中文语言. step1:添 ...

  4. [Abp vNext 源码分析] - 7. 权限与验证

    一.简要说明 在上篇文章里面,我们在 ApplicationService 当中看到了权限检测代码,通过注入 IAuthorizationService 就可以实现权限检测.不过跳转到源码才发现,这个 ...

  5. [Abp vNext 源码分析] - 11. 用户的自定义参数与配置

    一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 23 日晚 更新日期:暂无 ABP vNext 针对用户可编辑的配置,提供了单独的 Volo. ...

  6. [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)

    一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...

  7. [Abp vNext 源码分析] - 14. EntityFramework Core 的集成

    一.简要介绍 在以前的文章里面,我们介绍了 ABP vNext 在 DDD 模块定义了仓储的接口定义和基本实现.本章将会介绍,ABP vNext 是如何将 EntityFramework Core 框 ...

  8. 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  9. [Abp vNext 源码分析] - 21. 界面与文字的本地化

    一.简介 ABP vNext 提供了全套的本地化字符串支持,具体用法可以参考官方使用文档.vNext 本身是对 Microsoft 提供的本地化组件进行了实现,通过 JSON 文件提供本地化源,这一点 ...

  10. 源码解析-Abp vNext丨LocalEventBus

    前言 基础篇已经更新完了,从本篇开始我们进入,中级篇(学习部分源代码)我会挑一些我个人认为比较重要的知识点结合部分开源项目进行源码讲解,咱们废话不说直接上车. Abp vNext的事件总线分2种,一种 ...

随机推荐

  1. AndroidApp加密数据明文抓取测试方法——hook方式

    0x00 前言 在做移动安全的app渗透或者说移动app的漏洞挖掘时,往往会碰到一种情况:好不容易绕过了app的反抓包机制,通过burp抓到了app传输的数据包,这时想对这部分数据做一些爆破.篡改之类 ...

  2. Vue的生命周期的详解

    Vue的生命周期   Vue的生命周期是每个使用Vue框架的前端人员都需要掌握的知识,以此作为记录.   Vue的生命周期就是vue实例从创建到销毁的全过程,也就是new Vue() 开始就是vue生 ...

  3. 关于java中的多态和对实例化对象的一些理解

    java面向对象三大特征即为:继承封装多态.而多态需要三大必要条件.分别是:继承.方法重写.父类引用指向子类对象.我们先一个一个来理解. 1.首先是继承和重写.这个很简单.因为多态就是建立在不同的重写 ...

  4. day10-好友关注

    功能05-好友关注 6.功能05-好友关注 6.1关注和取关 6.1.1需求分析 在探店图文的详情页面中,可以关注发布笔记的作者: 关注和取关:点击关注按钮就会发出请求(上图):http://127. ...

  5. ctfshow菜狗杯(一)

    CTFshow菜狗杯,web签到 传参. 需要注意的是传参的时候要对中文字符进行编码输出. 得到flag. 第二关 come-to_s1gn 打开页面源代码 这里好像给了一半的flag,另一半好像说在 ...

  6. 前端Vue项目打包性能优化方案

    一.前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们不再需要去考虑如何操作 DOM 以及如何最高效地操作 DOM:但 Vue 项目中仍 ...

  7. 2022-07-27:小红拿到了一个长度为N的数组arr,她准备只进行一次修改, 可以将数组中任意一个数arr[i],修改为不大于P的正数(修改后的数必须和原数不同), 并使得所有数之和为X的倍数。

    2022-07-27:小红拿到了一个长度为N的数组arr,她准备只进行一次修改, 可以将数组中任意一个数arr[i],修改为不大于P的正数(修改后的数必须和原数不同), 并使得所有数之和为X的倍数. ...

  8. python爬虫防止IP被封的一些措施(转)

    python爬虫防止IP被封的一些措施(转) 在编写爬虫爬取数据的时候,因为很多网站都有反爬虫措施,所以很容易被封IP,就不能继续爬了.在爬取大数据量的数据时更是瑟瑟发抖,时刻担心着下一秒IP可能就被 ...

  9. weex 开发APP 多行文本溢出处理

    weex中文字溢出不能使用常规的overflow:hidden 如: .text { overflow: hidden; text-overflow: ellipsis; white-space: n ...

  10. 分布式机器学习(Parameter Server)

    分布式机器学习中,参数服务器(Parameter Server)用于管理和共享模型参数,其基本思想是将模型参数存储在一个或多个中央服务器上,并通过网络将这些参数共享给参与训练的各个计算节点.每个计算节 ...