前言

在使用 abp 开发业务功能时,会遇到公用同一个类的情况,在给这个类配置权限时,就要添加多个 AuthorizeAttribute,类似下面这样:

    [Authorize(DcsPermissions.DocCenter.Doc.Default)]
[Authorize(DcsPermissions.WorkingPlatform.MyDraft.Default)]
public class DocAppService : DcsAppServiceBase, IDocAppService
{
// ......
}

但是 abp 在验证时,会以且的方式验证这两个 Policy,只要一个没有权限,则返回 403 状态码。如果想以或的方式(只要有一个有权限,那么就返回有权限)验证如何做呢?通过查看 abp 源码,我们可以新增一个 IMethodInvocationAuthorizationService 接口的实现替换掉 abp 默认的实现 MethodInvocationAuthorizationService 。这个类实现的唯一目的就是通过 AuthorizeAttribute 构造出 AuthorizationPolicy 然后使用 IAbpAuthorizationService 验证权限。下面看看我如何实现或的方式进行验证权限吧。

实现

代码不多,就直接看下面的代码吧

    [Dependency(ReplaceServices = true)]
public class MyMethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency
{
private readonly IAbpAuthorizationService _abpAuthorizationService; public AutobioMethodInvocationAuthorizationService(IAbpAuthorizationService abpAuthorizationService)
{
this._abpAuthorizationService = abpAuthorizationService;
} public async Task CheckAsync(MethodInvocationAuthorizationContext context)
{
if ( this.AllowAnonymous(context))
{
return;
} var policyNames = this.GetAuthorizationDataPolicyNames(context.Method);
if ( policyNames.Any() )
{
var isGranted = await this._abpAuthorizationService.IsGrantedAnyAsync(policyNames);
if ( !isGranted )
{
throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted);
}
}
} protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context)
=> context.Method.GetCustomAttributes(true).OfType<IAllowAnonymous>().Any(); protected virtual string[] GetAuthorizationDataPolicyNames(MethodInfo methodInfo)
{
var attributes = methodInfo
.GetCustomAttributes(true)
.OfType<IAuthorizeData>(); if (methodInfo.IsPublic && methodInfo.DeclaringType != null)
{
attributes = attributes
.Union(
methodInfo.DeclaringType
.GetCustomAttributes(true)
.OfType<IAuthorizeData>()
);
} return attributes.Where(_ => !string.IsNullOrWhiteSpace(_.Policy)).Select(_ => _.Policy).ToArray();
}
}

这里面主要利益于 abp 提供了 IsGrantedAnyAsync 扩展方法。

总结

打算把这个想法提个 PR 给 abp 项目。整个扩展过程下来的感觉 abp 挺灵活的。abp 默认达不到的要求,几乎都可以通过扩展它来解决掉。

最新文章

  1. Linux shell编程
  2. where T : class的含义
  3. 318. Maximum Product of Word Lengths ——本质:英文单词中字符是否出现可以用26bit的整数表示
  4. SQL Server数据库学习笔记-设计表时应该考虑的因素
  5. POJ 2774 (后缀数组 最长公共字串) Long Long Message
  6. js实现hashtable的赋值、取值、遍历
  7. OFBIZ bug_ControlServlet.java:239:ERROR
  8. awk巩固练习题
  9. linkin大话面向对象--包装类
  10. 434个H5游戏源码
  11. vps install ss
  12. MySQL 基础知识梳理学习(四)----GTID
  13. 在vue.js中使用echarts,数据动态刷新
  14. 【CTSC2017】【BZOJ4903】吉夫特 卢卡斯定理 DP
  15. 【BZOJ1013】【JSOI2008】球形空间产生器 高斯消元
  16. MySQL 用户连接与用户线程
  17. android -------- android studio 中设置创建类时的说明信息(包含 作者 ,创建时间,注释说明等)
  18. 【Linux】python 2.x 升级 python3.x 之后 yum命令出现except OSError, e: ^ SyntaxError: invalid syntax
  19. java项目连接jdbc报错:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server
  20. MySQL 性能测试

热门文章

  1. Groovy+Spock单元测试
  2. 阿里云rds分区
  3. 0x800b010a 证书
  4. 使用let实现循环小例子
  5. Kickstart部署之FTP架构
  6. Java网络编程之TCP
  7. Packing问题
  8. appium+python运行自动化测试提示“find_element() takes from 1 to 3 positional arguments but 14 were given”错误
  9. 稚晖君-最小linux服务器运行 nginx + netcore
  10. WEB漏洞——CSRF、SSRF