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

本文介绍了一个在.NET Core项目启动时获取自定义权限特性`LinCmsAuthorizeAttribute`的需求。通过反射,遍历所有控制器及其方法,收集并缓存特性参数以供后续权限验证使用。文章详细讲解了`LinCmsAuthorizeAttribute`的用途和测试过程,并提供了参考链接和开源项目地址。
摘要由CSDN通过智能技术生成

有个需求,就是在. 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

ce0384b6e2cf6f26c06f2911ca7c36a4.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值