有个需求,就是在. NET Core中,我们想在项目 启动时,获取LinCmsAuthorizeAttribute这个特性标签所有出现的地方,把他的参数,放入一个集合并缓存起来,以便后面使用此数据用于权限验证。

我们通过反射获取所有控制器下及方法的Attribute。

LinCmsAuthorizeAttribute是什么

其代码非常简单,用于自定义权限验证,通过重写OnAuthorizationAsync方法,实现固定权限可分配给动态角色(也能分配给动态用户)。主要就基于权限的授权的实现进行研究,实现方法级别的权限验证。

  • https://www.cnblogs.com/RainingNight/p/dynamic-authorization-in-asp-net-core.html

当然,这个只是部分代码,完整代码请查看最下方开源地址,其中LinCmsAuthorizeAttribute继承AuthorizeAttribute,拥有指定角色权限控制,当Permission未指定时,当过滤器与Authorize功能相同。Module是指模块,即多个权限,属于同一个模块,方便前台展示为树型结构。Permission属性的值不可重复。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]public class LinCmsAuthorizeAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter{public string Permission { get; set; }public string Module { get; set; }

public LinCmsAuthorizeAttribute()    {

    }

public LinCmsAuthorizeAttribute(string permission,string module)    {        Permission = permission;        Module = module;    }

public LinCmsAuthorizeAttribute(string permission,string module, string policy) : base(policy)    {        Permission = permission;        Module = module;    }

public async Task OnAuthorizationAsync(AuthorizationFilterContext context)    {if (Permission == null) return;var authorizationService = (IAuthorizationService)context.HttpContext.RequestServices.GetService(typeof(IAuthorizationService));var authorizationResult = await authorizationService.AuthorizeAsync(context.HttpContext.User, null, new OperationAuthorizationRequirement() { Name = Permission });if (!authorizationResult.Succeeded)        {            context.Result = new ForbidResult();        }    }

public override string ToString()    {return $"\"{base.ToString()}\",\"Permission:{Permission}\",\"Module:{Module}\",\"Roles:{Roles}\",\"Policy:{Policy}\",\"AuthenticationSchemes:{AuthenticationSchemes}\"";    }}

Controller

在 LinCms.Web中的Controller,至于为什么Permission为中文,目前的主要原因,此项目用于适配 Lin-CMS-VUE项目,所以于平常我们以某个字符串作为权限名不同,但不须大精小怪,道理相同。

[Route("cms/log")][ApiController]public class LogController : ControllerBase{private readonly ILogService _logService;

public LogController(ILogService logService)    {        _logService = logService;    }

    [HttpGet("users")]    [LinCmsAuthorize("查询日志记录的用户", "日志")]public List<string> GetLoggedUsers([FromQuery]PageDto pageDto)    {return _logService.GetLoggedUsers(pageDto);    }

    [HttpGet]    [LinCmsAuthorize("查询所有日志", "日志")]public PagedResultDtoGetLogs([FromQuery]LogSearchDto searchDto)    {return _logService.GetLogUsers(searchDto);    }

    [HttpGet("search")]    [LinCmsAuthorize("搜索日志", "日志")]public PagedResultDtoSearchLogs([FromQuery]LogSearchDto searchDto)    {return _logService.GetLogUsers(searchDto);    }}

测试类获取方法上的特定标签

in xunit test 项目工程中,开始我们的测试

[Fact]public void GetAssemblyMethodsAttributes(){    var assembly = typeof(Startup).Assembly.GetTypes().AsEnumerable()        .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToList();

    assembly.ForEach(r =>    {foreach (var methodInfo in r.GetMethods())        {foreach (Attribute attribute in methodInfo.GetCustomAttributes())            {if (attribute is LinCmsAuthorizeAttribute linCmsAuthorize)                {                    _testOutputHelper.WriteLine(linCmsAuthorize.ToString());                }            }        }    });}

方法结果

可在输出文本中查看,正是我们想要的东西,最后一行,是其他Controller中的内容,而且我们重写了ToString(),所以我们能看到其属性。

"LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:查询日志记录的用户","Module:日志","Roles:","Policy:","AuthenticationSchemes:""LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:查询所有日志","Module:日志","Roles:","Policy:","AuthenticationSchemes:""LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:搜索日志","Module:日志","Roles:","Policy:","AuthenticationSchemes:""LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:查看lin的信息","Module:信息","Roles:","Policy:","AuthenticationSchemes:"

获取控制器上特性标签

/// /// 获取控制器上的LinCmsAuthorizeAttribute/// </summary>/// "LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:","Module:","Roles:Administrator","Policy:","AuthenticationSchemes:"[Fact]public void GetControllerAttributes(){    var assembly = typeof(Startup).Assembly.GetTypes().AsEnumerable().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToList();    assembly.ForEach(d =>    {        var linCmsAuthorize = d.GetCustomAttribute();if (linCmsAuthorize != null)        {            _testOutputHelper.WriteLine(linCmsAuthorize.ToString());        }    });}

Controller结果

只有AdminController加了此标签,所以只有一行。

"LinCms.Zero.Authorization.LinCmsAuthorizeAttribute","Permission:","Module:","Roles:Administrator","Policy:","AuthenticationSchemes:"

此时Roles为Administrator,Permission及Module都是null, 这是因为只有AdminController中加了LinGroup.Administrator="Administrator"字符串,在登录过程中,已经给当前登录用户设置了 new Claim(ClaimTypes.Role,user.IsAdmin()?LinGroup.Administrator:user.GroupId.ToString()),即"Administrator,当用户访问AdminController中的方法时,LinCmsAuthorize并没有做相关验证,都是AuthorizeAttribute,实现了固定角色权限的判断及登录的判断。LinCmsAuthorize完成了固定权限设置为不同的动态角色后,判断用户是否拥有此权限。

[LinCmsAuthorize(Roles = LinGroup.Administrator)]public class AdminController : ControllerBase{    ...}

参考

  • c# – 如何在asp. net core rc2中获取控制器的自定义属性 https://codeday.me/bug/20181207/453278.html

开源地址

  • github.com/luoyunchong/lin-cms-dotnetcore

.net core 获取机器码_.NET Core 反射获取所有控制器及方法上特定标签相关推荐

  1. .NET Core 反射获取所有控制器及方法上特定标签

    有个需求,就是在. NET Core中,我们想在项目 启动时,获取LinCmsAuthorizeAttribute这个特性标签所有出现的地方,把他的参数,放入一个集合并缓存起来,以便后面使用此数据用于 ...

  2. java怎么通过字段去获取对象_通过java反射获取任意对象的字段名及字段值

    import java.lang.reflect.Field; public class ReflectClass3 { /** * @param args */ public static void ...

  3. java 反射获取父类的字段_java反射获取父类和子类字段值、赋值

    这里将告诉您java反射获取父类和子类字段值.赋值,具体操作过程:java反射获取字段值.赋值 import org.springframework.util.ReflectionUtils; imp ...

  4. java获取object属性值_java反射获取一个object属性值代码解析

    有些时候你明明知道这个object里面是什么,但是因为种种原因,你不能将它转化成一个对象,只是想单纯地提取出这个object里的一些东西,这个时候就需要用反射了. 假如你这个类是这样的: privat ...

  5. java socket 远程调用_使用Socket反射Java流操作进行方法的远程调用(模拟RPC远程调用)...

    写在前面 阅读本文首先得具备基本的Socket.反射.Java流操作的基本API使用知识:否则本文你可能看不懂... 服务端的端口监听 进行远程调用,那就必须得有客户端和服务端.服务端负责提供服务,客 ...

  6. java 获取参数的类型_java反射获取方法名称,参数类型

    package com.mysec.reflex; import java.lang.reflect.Constructor; import java.lang.reflect.Field; impo ...

  7. .net core 微服务_.NET 微服务实战之负载均衡(上)

    (给DotNet加星标,提升.Net技能) 转自:陈珙cnblogs.com/skychen1218/p/13327965.html 系列文章 .Net微服务实战之技术选型篇 .Net微服务实战之技术 ...

  8. core webapi缩略图_.Net Core WebApi上传图片的两种方式

    我这边主要是为了上传图片,话不多说,上代码. 方式一:通过Form表单上传 后端: /// /// 上传图片,通过Form表单提交 /// /// [Route("Upload/FormIm ...

  9. java 反射获取对象_使用Java反射机制获取对象

    本文由广州疯狂软件教育java培训分享: 构造接口Person,所有Person都会问好,但具体讲什么语言就不知道了! package interf; public interface Person ...

最新文章

  1. Cocos Creator里cc.tween的stopAllActions() 和 repeatForever的用法
  2. Python——pyiso8601
  3. SCCM2012R2之五创建系统集合
  4. 分区时磁盘上没有足够的空间完成此操作的解决方法
  5. bug之bootstrap switch Uncaught TypeError: Cannot read property 'apply' of undefined
  6. Vue中通过Axios向SpringBoot发送get和post请求
  7. 5G在工业互联网应用的机遇与挑战
  8. 字段缺失_区分Protobuf 3中缺失值和默认值
  9. mysql约束_不是吧,阿Sir,MySQL约束你竟然还不懂!
  10. java抽组件_Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor
  11. 不输入密码执行sudo命令方法介绍
  12. “Scrum 敏捷开发都是骗人的!”
  13. 芯片之路: 海思半导体前世今生
  14. 在网站中使用VideoJs视频播放器播放视频
  15. 【强化学习入门】人工智能、深度学习理论框架以及学习资料
  16. 双硬盘安装Windows+Ubuntu
  17. Windows 2003安装和配置活动目录服务 zz
  18. Python串口异步通信
  19. 修改MAC密码 Navicat每次打开都要输入密码
  20. php中预定义常量的,php预定义常量_PHP教程

热门文章

  1. jQuery学习笔记(二)
  2. container and Injection
  3. 通用mapper版+SpringBoot+MyBatis框架+mysql数据库的整合
  4. java解析xml的4种经典方法
  5. Python——调用shell命令的三种方法
  6. Cobar-Client 实现策略总结
  7. magento开发中文手册
  8. 在递归中使用Continuation来避免StackOverflow(查找第K大的数)
  9. UIApplication深入研究
  10. DlgProc对话框回调