当前位置:首页 > 旅游指南

authorize ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide

一.概述

ASP.NET核心MVC提供基于角色、Chaim和策略的授权方式。在实际应用中,授权可以通过部门(本文中的用户组)、职位(角色可以继续)、权限等方式进行。为了实现这一目标,不可能只定制IAuthorizationPolicyProvider。本文通过定制IApplicationModelProvide进行了扩展。

第二,permissionauthorizeattribute:ipermisteruthorizedata

AuthorizeAttribute类实现IAuthorizeData接口:

namespace Microsoft.AspNetCore.Authorization

{

/// <。摘要>。

///定义将授权规则应用于资源所需的数据集。

/// <。/summary>。

公共接口IAuthorizeData

{

/// <。摘要>。

///获取或设置确定对资源的访问权限的策略名称。

/// <。/summary>。

字符串策略{ get设置;}

/// <。摘要>。

///获取或设置允许访问资源的角色的逗号分隔列表。

/// <。/summary>。

字符串角色{ get设置;}

/// <。摘要>。

///获取或设置以逗号分隔的方案列表,从中构造用户信息。

/// <。/summary>。

string AuthenticationSchemes { get;设置;}

}

}

AuthorizeAttribute的使用只不过是以下几种形式:

[Authorize]

[授权(“某些政策”)]

[授权(角色=“角色1,角色2”)]

[Authorize(AuthenticationSchemes = JwtBearerDefaults。AuthenticationScheme)]

当然,参数也可以组合。此外,角色和身份验证架构的值由逗号分隔,这是或的关系;许多“授权”处于“与”的关系中;如果同时使用策略、角色和身份验证方案,它们也处于和的关系中。

要扩展AuthorizeAttribute,首先扩展IAuthorizeData以添加新属性:

public interface IPermissionAuthorizeData : IAuthorizeData

{

字符串组{ get设置;}

字符串权限{ get设置;}

}

然后定义AuthorizeAttribute:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]

公共类PermissionAuthorizeAttribute:属性,IPermissionAuthorizeData

{

公共字符串策略{ get设置;}

公共字符串角色{ get设置;}

公共字符串身份验证架构{ get设置;}

公共字符串组{ get设置;}

公共字符串权限{ get设置;}

}

现在,它可以在控制器或操作上使用,如下所示:

[PermissionAuthorize(Roles = "经理,副经理")] // 经理或部门经理

【权限权限(group = " R&D部门,生产部门",Roles = "经理" 】//R&D部门经理或代部门经理。组和角色是“和”。

【权限权限(group = " R&D部门,生产部门",Roles = "经理",Permissions = "请假审批"】//R&D部门经理或生产部门经理,有请假审批权限。组、角色和权限是“和”关系。

数据准备好了,下一步就是如何提取。可以通过扩展授权应用modelprovider来实现。

三.许可授权应用程序模型提供程序:应用程序模型提供程序

authorizationapplicationmodelprovider类的作用是构造AuthorizeFilter对象,并将其放入ControllerModel或ActionModel的Filters属性中。具体过程是提取实现IAuthorizeData接口的控制器和动作的属性。如果使用默认的授权策略提供程序,将创建一个授权策略对象作为AuthorizeFilter构造函数的参数。

授权策略对象由授权策略的静态方法公共静态异步任务创建

因为authorizationapplicationmodelprovider类依赖于authorizationpolicy。combineasync静态方法,我们要在这里做一个类似permissionautorizationapplicationmodelprovider的类,在这个类中实现CombineAsync方法。先不说这个方法是否适合这个类别。

public static AuthorizeFilter GetFilter(IAuthorizationPolicyProvider policyProvider, IEnumerable<IAuthorizeData> authData)

{

//默认策略提供者会为给定的输入制定相同的策略,所以只制定一次。

//这将始终同步执行。

if (policyProvider。GetType()= = type of(DefaultAuthorizationPolicyProvider))

{

var policy = CombineAsync(policy provider,authData)。geta服务员()。GetResult();

返回新的AuthorizeFilter(策略);

}

其他

{

返回新的授权过滤器(策略提供者,授权数据);

}

}

私有静态异步任务& lt授权策略>。CombineAsync(iauthorizationpolicy provider policy provider,IEnumerable & ltIAuthorizeData & gtauthorizeData)

{

if (policyProvider == null)

{

引发新的ArgumentNullException(name of(PolicyProvider));

}

if (authorizeData == null)

{

引发新的ArgumentNullException(name of(authorizeData));

}

var PolicyBuilder = new authorizationPolicyBuilder();

var any = false

foreach(var authorized atum in authorized data)

{

any = true

var useDefaultPolicy = true

if(!字符串。isnullorhitespace(authorized usual。政策))

{

var policy = await policyProvider。GetPolicyAsync(AuthorizedItalum。政策);

if(策略== null)

{

//抛出新的InvalidOperationException(参考资料。format exception _ authorizationpolicy not found(authorized torm。政策));

引发新的InvalidOperationException(名称为(authorizeDatum)。政策));

}

policyBuilder。合并(政策);

useDefaultPolicy = false

}

var rolesSplit = authorizeDatum。角色?。Split(',');

if (rolesSplit!= null & amp& amp角色点亮。Any())

{

var trimmedRolesSplit = rolesSplit。其中(r = & gt!字符串。isnullorhitespace(r))。选择(r = & gtr . Trim());

policyBuilder。require role(triedlesplit);

useDefaultPolicy = false

}

if(authorized torm是ipermisterauthorized data permissional authorized torm)

{

var groups slit = Permissionauthorized trum。团体?。Split(',');

if(GroupSplit!= null & amp& ampgroupsSplit。Any())

{

var TrimbedGroupSplit = GroupSplit。其中(r = & gt!字符串。isnullorhitespace(r))。选择(r = & gtr . Trim());

policyBuilder。required claim(" Group ",triedgroupsplit);// TODO:注意硬编码

useDefaultPolicy = false

}

var Permissions slit = Permissionauthorized trum。权限?。Split(',');

if(Permissions Lit!= null & amp& amppermissionsSplit。Any())

{

var triedpermissionssplit = permissionsSplit。其中(r = & gt!字符串。isnullorhitespace(r))。选择(r = & gtr . Trim());

policyBuilder。required claim(" Permission ",triedpermissionsPlit);// TODO:注意硬编码

useDefaultPolicy = false

}

}

var AuthTypeSplit = AuthorizedItum。身份验证方案?。Split(',');

if(authtysplit!= null & amp& ampauthTypesSplit。Any())

{

foreach(在authTypesSplit中的变量验证类型)

{

if(!字符串。isnullorhitespace(authType))

{

policyBuilder。身份验证架构。添加(身份验证类型。trim());

}

}

}

if (useDefaultPolicy)

{

policyBuilder。合并(等待策略提供商。getDefaultPolicyAsync());

}

}

退货吗?policyBuilder。build():null;

}

如果(授权数据是网上授权数据许可授权状态)是一个扩展。

四.启动

要注册权限授权应用程序模型提供程序服务,您需要在添加Mvc后替换授权应用程序模型提供程序服务。

services.AddMvc();

服务。Replac(ServiceDeor。瞬态<。IApplicationModelProvider,Permissionauthorizationapplicationmodelprovider & gt;());

五、Jwt 示例[Route("api/[controller]")]

[速度控制器]

公共类值控制器:控制器数据库

{

private readonly Jwtsecuritytokenhandler _ token handler = new Jwtsecuritytokenhandler();

[HttpGet]

[路线(“登录”)]

公共异步任务& ltActionResult<。string>。>。登录()

{

var user = new ClaimSprincipal(new ClaimSidenty(new[]

{

//注意:声明类型:组和权限在这里是硬编码的,应该定义为类似于声明类型的常量。角色;此外,以下模拟数据可能不符合逻辑。

新索赔类型。姓名,“鲍勃”),

新索赔类型。角色,“经理”),//注意:不能用逗号分隔多个角色,下同。

新索赔类型。角色,“副经理”),

新索赔(“集团”、“R&D部”),

新索赔(“集团”、“生产部门”),

新申请(“许可”、“许可”),

新声明(“许可”、“许可1”),

新声明(“许可”、“许可2”),

},JwtBearerDefaults。AuthenticationScheme));

var token = new JwtSecurityToken(

“信号和验证示例”,

“信号和验证示例”,

用户。索赔,

过期时间:DateTime。现在。添加天数(30),

签名证书:签名帮助。generatedesigningcredentials(" 1234567890123456 ");

return _tokenHandler。write token(token);

}

[HttpGet]

[路线(“测试”)]

【权限权限(group = " R&D部门,生产部门",Roles = "经理",Permissions = "请假审批"】//R&D部门经理或生产部门经理,有请假审批权限。组、角色和权限是“和”关系。

公共异步任务& ltActionResult<。IEnumerable<。string>。>。>。测试()

{

var user = HttpContext。用户;

返回新字符串[] { "value1 "," value 2 " };

}

}

六、问题

AuthorizeFilter类显示实现IFilterFactory接口的CreateInstance方法:

IFilterMetadata IFilterFactory.CreateInstance(IServiceProvider serviceProvider)

{

如果(政策!= null || PolicyProvider!= null)

{

//过滤器已完全构建。使用当前实例进行授权。

归还这个;

}

调试。Assert(AuthorizeData!= null);

var PoLicy Provider = ServiCe Provider。GetRequiredService<。iauthorizationpolicy provider & gt。();

返回AuthorizationApplicationModelProvider。GetFilter(policyProvider,AuthorizeData);

}

出乎意料的是,它依赖于authorizationapplicationmodelprovider . getfilter的静态方法..幸运的是,如果授权过滤器(iauthorization policy provider,ienumerable

七、下一步

[PermissionAuthOrize(group = " R&D部门,生产部门",Roles = "经理",Permissions = "请假审批"]仍然不够灵活,即使使用了多个Attribute,and,And或or的逻辑组合也不一定能满足需求。您可以在网上授权数据中添加一个规则属性,以达到类似的效果:

[PermissionAuthorize(Rule = "(Groups:研发部,生产部)&&(Roles:请假审批||Permissions:超级权限)"]

复杂授权按规则计算。

八、如果通过自定义IAuthorizationPolicyProvider?

另一种方法是自定义IAuthorizationPolicyProvider,但您还需要自定义AuthorizeFilter。因为当您自定义IAuthorizationPolicyProvider而不是DefaultAuthorizationPolicyprovider时,authorizationapplicationmodeprovider(或上面定义的permissionautorizationapplicationmodeprovider)使用authorizefilter(IAuthorizationPolicyProvider,ienumerable

这可以说是一个设计缺陷,静态方法authorizationpolicy。combineasync不应该存在,即使提供了IAuthorizationPolicyCombiner。另外,上面提到的authorizationapplicationmodelprovider . get filter的静态方法也不是很好的设计。等微软想明白了再说。

参考数据

https://docs . Microsoft . com/zh-cn/aspnet/core/security/authorization/iauthorizationpolicy provider?view=aspnetcore-2.1

排版问题:http://blog . tubumu . com/2018/11/28/aspnetcore-MVC-extend-authorization/

1.《authorize ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《authorize ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/junshi/1522373.html

上一篇

广东实验中学 广东实验中学深圳学校来了!明年秋季开学

下一篇

扁都口 张掖至汶川高速公路张掖至扁都口段建成通车

阿甘正传珍妮人物分析 角色人物分析——电影《阿甘正传》... | 演员经纪汇.角色功课...

  • 阿甘正传珍妮人物分析 角色人物分析——电影《阿甘正传》... | 演员经纪汇.角色功课...
  • 阿甘正传珍妮人物分析 角色人物分析——电影《阿甘正传》... | 演员经纪汇.角色功课...
  • 阿甘正传珍妮人物分析 角色人物分析——电影《阿甘正传》... | 演员经纪汇.角色功课...
李寅崟 李寅崟《演员的品格》总决赛获胜,成功出道获爱奇艺IP剧《未来的秘密》角色

李寅崟 李寅崟《演员的品格》总决赛获胜,成功出道获爱奇艺IP剧《未来的秘密》角色

在大多数人的认知中,演员是一个“天道酬勤”的职业。作为一个演员,自身硬件条件是最基本的门槛,面值和身材的指标很硬。每年都有大量的“白眉”和“高帅”表演艺术考生进入影视院校,准备跻身演员行列。但是只讲皮囊之流的时代早就被...

动漫人物的画法 【动漫人物画法】各个角度的动漫角色人物画法

  • 动漫人物的画法 【动漫人物画法】各个角度的动漫角色人物画法
  • 动漫人物的画法 【动漫人物画法】各个角度的动漫角色人物画法
  • 动漫人物的画法 【动漫人物画法】各个角度的动漫角色人物画法

动漫人物画法 【动漫人物画法】各个角度的动漫角色人物画法

  • 动漫人物画法 【动漫人物画法】各个角度的动漫角色人物画法
  • 动漫人物画法 【动漫人物画法】各个角度的动漫角色人物画法
  • 动漫人物画法 【动漫人物画法】各个角度的动漫角色人物画法

我妻草灯 软乎乎毛茸茸——动漫中可萌可萌的兽耳角色~

动物耳朵可谓是柔软可爱的宠物和少女的完美结合。动物耳朵作为动画中的一个独特属性,孕育出了许多迷人的角色,其中一些是拟人化的野兽女孩,而另一些则经常用类似于动物耳朵的发型或发带表现人的可爱角色。今天我们来盘点一下动物耳朵...

海贼王所有女性角色 推荐十四位《海贼王》美女角色,喜欢就拿走!

《一片》博雅·汉考克,世界政府统治下的七大洋中唯一的女人,高傲自恋,对除路飞之外的所有男人都免疫。“一体”尼科·罗宾,草帽海盗团成员,是一位多才多艺的女性历史学家。她高贵但不是陌陌,温柔但坚强。很多海贼都说她很完美,没...

海贼王美女 推荐十四位《海贼王》美女角色,喜欢就拿走!

《一片》博雅·汉考克,世界政府统治下的七大洋中唯一的女人,高傲自恋,对除路飞之外的所有男人都免疫。“一体”尼科·罗宾,草帽海盗团成员,是一位多才多艺的女性历史学家。她高贵但不是陌陌,温柔但坚强。很多海贼都说她很完美,没...

玛琪诺 推荐十四位《海贼王》美女角色,喜欢就拿走!

《一片》博雅·汉考克,世界政府统治下的七大洋中唯一的女人,高傲自恋,对除路飞之外的所有男人都免疫。“一体”尼科·罗宾,草帽海盗团成员,是一位多才多艺的女性历史学家。她高贵但不是陌陌,温柔但坚强。很多海贼都说她很完美,没...