当前位置: 首页 > news >正文

网站源码官网招聘网站内容建设

网站源码官网,招聘网站内容建设,水墨风格网站源码,亚马逊海外购一、概述ASP.NET Core MVC 提供了基于角色( Role )、声明( Chaim ) 和策略 ( Policy ) 等的授权方式。在实际应用中#xff0c;可能采用部门#xff08; Department , 本文采用用户组 Group #xff09;、职位 ( 可继续沿用 Role )、权限( Permission )的方式进行授权。要达… 一、概述ASP.NET Core MVC 提供了基于角色( Role )、声明( Chaim ) 和策略 ( Policy ) 等的授权方式。在实际应用中可能采用部门 Department , 本文采用用户组 Group 、职位 ( 可继续沿用 Role )、权限( Permission )的方式进行授权。要达到这个目的仅仅通过自定义 IAuthorizationPolicyProvider 是不行的。本文通过自定义 IApplicationModelProvide 进行扩展。二、PermissionAuthorizeAttribute : IPermissionAuthorizeDataAuthorizeAttribute 类实现了 IAuthorizeData 接口namespace Microsoft.AspNetCore.Authorization{  /// summary  /// Defines the set of data required to apply authorization rules to a resource.  /// /summary  public interface IAuthorizeData  {   /// summary   /// Gets or sets the policy name that determines access to the resource.   /// /summary   string Policy { get; set; }   /// summary   /// Gets or sets a comma delimited list of roles that are allowed to access the resource.   /// /summary   string Roles { get; set; }   /// summary   /// Gets or sets a comma delimited list of schemes from which user information is constructed.   /// /summary   string AuthenticationSchemes { get; set; }  }}使用 AuthorizeAttribute 不外乎如下几种形式[Authorize][Authorize(SomePolicy)][Authorize(Roles 角色1,角色2)][Authorize(AuthenticationSchemes JwtBearerDefaults.AuthenticationScheme)]当然参数还可以组合起来。另外Roles 和 AuthenticationSchemes 的值以半角逗号分隔是 Or 的关系多个 Authorize 是 And 的关系Policy 、Roles 和 AuthenticationSchemes 如果同时使用也是 And 的关系。如果要扩展 AuthorizeAttribute先扩展 IAuthorizeData 增加新的属性public interface IPermissionAuthorizeData : IAuthorizeData{    string Groups { get; set; }    string Permissions { get; set; }}然后定义 AuthorizeAttribute:[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple true, Inherited true)]public class PermissionAuthorizeAttribute : Attribute, IPermissionAuthorizeData{    public string Policy { get; set; }    public string Roles { get; set; }    public string AuthenticationSchemes { get; set; }    public string Groups { get; set; }    public string Permissions { get; set; }}现在在 Controller 或 Action 上就可以这样使用了[PermissionAuthorize(Roles 经理,副经理)] // 经理或部门经理[PermissionAuthorize(Groups 研发部,生产部, Roles 经理] // 研发部经理或生成部经理。Groups 和 Roles 是 And 的关系。[PermissionAuthorize(Groups 研发部,生产部, Roles 经理, Permissions 请假审批] // 研发部经理或生成部经理并且有请假审批的权限。Groups 、Roles 和 Permission 是 And 的关系。数据已经准备好下一步就是怎么提取出来。通过扩展 AuthorizationApplicationModelProvider 来实现。三、PermissionAuthorizationApplicationModelProvider : IApplicationModelProviderAuthorizationApplicationModelProvider 类的作用是构造 AuthorizeFilter 对象放入 ControllerModel 或 ActionModel 的 Filters 属性中。具体过程是先提取 Controller 和 Action 实现了 IAuthorizeData 接口的 Attribute如果使用的是默认的DefaultAuthorizationPolicyProvider则会先创建一个 AuthorizationPolicy 对象作为 AuthorizeFilter 构造函数的参数。创建 AuthorizationPolicy 对象是由 AuthorizationPolicy 的静态方法 public static async TaskAuthorizationPolicy CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authorizeData) 来完成的。该静态方法会解析 IAuthorizeData 的数据但不懂解析 IPermissionAuthorizeData。因为 AuthorizationApplicationModelProvider 类对 AuthorizationPolicy.CombineAsync 静态方法有依赖这里不得不做一个类似的 PermissionAuthorizationApplicationModelProvider 类在本类实现 CombineAsync 方法。暂且不论该方法放在本类是否合适的问题。       public static AuthorizeFilter GetFilter(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authData)       {           // The default policy provider will make the same policy for given input, so make it only once.           // This will always execute synchronously.           if (policyProvider.GetType() typeof(DefaultAuthorizationPolicyProvider))           {               var policy CombineAsync(policyProvider, authData).GetAwaiter().GetResult();               return new AuthorizeFilter(policy);           }           else           {               return new AuthorizeFilter(policyProvider, authData);           }       }       private static async TaskAuthorizationPolicy CombineAsync(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authorizeData)       {           if (policyProvider null)           {               throw new ArgumentNullException(nameof(policyProvider));           }           if (authorizeData null)           {               throw new ArgumentNullException(nameof(authorizeData));           }           var policyBuilder new AuthorizationPolicyBuilder();           var any false;           foreach (var authorizeDatum in authorizeData)           {               any true;               var useDefaultPolicy true;               if (!string.IsNullOrWhiteSpace(authorizeDatum.Policy))               {                   var policy await policyProvider.GetPolicyAsync(authorizeDatum.Policy);                   if (policy null)                   {                       //throw new InvalidOperationException(Resources.FormatException_AuthorizationPolicyNotFound(authorizeDatum.Policy));                       throw new InvalidOperationException(nameof(authorizeDatum.Policy));                   }policyBuilder.Combine(policy);                   useDefaultPolicy false;               }               var rolesSplit authorizeDatum.Roles?.Split(,);               if (rolesSplit ! null rolesSplit.Any())               {                   var trimmedRolesSplit rolesSplit.Where(r !string.IsNullOrWhiteSpace(r)).Select(r r.Trim());                   policyBuilder.RequireRole(trimmedRolesSplit);                   useDefaultPolicy false;               }               if(authorizeDatum is IPermissionAuthorizeData permissionAuthorizeDatum )               {                   var groupsSplit permissionAuthorizeDatum.Groups?.Split(,);                   if (groupsSplit ! null groupsSplit.Any())                   {                       var trimmedGroupsSplit groupsSplit.Where(r !string.IsNullOrWhiteSpace(r)).Select(r r.Trim());                       policyBuilder.RequireClaim(Group, trimmedGroupsSplit); // TODO: 注意硬编码                       useDefaultPolicy false;                   }                   var permissionsSplit permissionAuthorizeDatum.Permissions?.Split(,);                   if (permissionsSplit ! null permissionsSplit.Any())                   {                       var trimmedPermissionsSplit permissionsSplit.Where(r !string.IsNullOrWhiteSpace(r)).Select(r r.Trim());                       policyBuilder.RequireClaim(Permission, trimmedPermissionsSplit);// TODO: 注意硬编码                       useDefaultPolicy false;                   }               }               var authTypesSplit authorizeDatum.AuthenticationSchemes?.Split(,);               if (authTypesSplit ! null authTypesSplit.Any())               {                   foreach (var authType in authTypesSplit)                   {                       if (!string.IsNullOrWhiteSpace(authType))                       {                           policyBuilder.AuthenticationSchemes.Add(authType.Trim());                       }                   }               }               if (useDefaultPolicy)               {policyBuilder.Combine(await policyProvider.GetDefaultPolicyAsync());               }           }           return any ? policyBuilder.Build() : null;       }if(authorizeDatum is IPermissionAuthorizeData permissionAuthorizeDatum ) 为扩展部分。四、Startup注册 PermissionAuthorizationApplicationModelProvider 服务需要在 AddMvc 之后替换掉 AuthorizationApplicationModelProvider 服务。services.AddMvc();services.Replac(ServiceDescriptor.TransientIApplicationModelProvider,PermissionAuthorizationApplicationModelProvider());五、Jwt 示例[Route(api/[controller])][ApiController]public class ValuesController : ControllerBase{    private readonly JwtSecurityTokenHandler _tokenHandler new JwtSecurityTokenHandler();    [HttpGet]    [Route(SignIn)]    public async TaskActionResultstring SignIn()    {        var user new ClaimsPrincipal(new ClaimsIdentity(new[]        {            // 备注Claim Type: Group 和 Permission 这里使用的是硬编码应该定义为类似于 ClaimTypes.Role 的常量另外下列模拟数据不一定合逻辑。            new Claim(ClaimTypes.Name, Bob),            new Claim(ClaimTypes.Role, 经理),  // 注意不能使用逗号分隔来达到多个角色的目的下同。            new Claim(ClaimTypes.Role, 副经理),            new Claim(Group, 研发部),            new Claim(Group, 生产部),            new Claim(Permission, 请假审批),            new Claim(Permission, 权限1),            new Claim(Permission, 权限2),        }, JwtBearerDefaults.AuthenticationScheme));        var token new JwtSecurityToken(            SignalRAuthenticationSample,            SignalRAuthenticationSample,            user.Claims,            expires: DateTime.UtcNow.AddDays(30),            signingCredentials: SignatureHelper.GenerateSigningCredentials(1234567890123456));        return _tokenHandler.WriteToken(token);    }    [HttpGet]    [Route(Test)]    [PermissionAuthorize(Groups 研发部,生产部, Roles 经理, Permissions 请假审批] // 研发部经理或生成部经理并且有请假审批的权限。Groups 、Roles 和 Permission 是 And 的关系。    public async TaskActionResultIEnumerablestring Test()    {        var user HttpContext.User;        return new string[] { value1, value2 };    } }六、问题AuthorizeFilter 类显示实现了 IFilterFactory 接口的 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.GetRequiredServiceIAuthorizationPolicyProvider();    return AuthorizationApplicationModelProvider.GetFilter(policyProvider, AuthorizeData);}竟然对 AuthorizationApplicationModelProvider.GetFilter 静态方法产生了依赖。庆幸的是如果通过 AuthorizeFilter(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authorizeData) 或 AuthorizeFilter(AuthorizationPolicy policy) 创建 AuthorizeFilter 对象不会产生什么不良影响。七、下一步[PermissionAuthorize(Groups 研发部,生产部, Roles 经理, Permissions 请假审批] 这种形式还是不够灵活哪怕用多个 Attribute, And 和 Or 的逻辑组合不一定能满足需求。可以在 IPermissionAuthorizeData 新增一个 Rule 属性实现类似的效果[PermissionAuthorize(Rule (Groups:研发部,生产部)(Roles:请假审批||Permissions:超级权限)]通过 Rule 计算复杂的授权。八、如果通过自定义 IAuthorizationPolicyProvider 实现另一种方式是自定义 IAuthorizationPolicyProvider 不过还需要自定义 AuthorizeFilter。因为当不是使用 DefaultAuthorizationPolicyProvider 而是自定义 IAuthorizationPolicyProvider 时AuthorizationApplicationModelProvider或前文定义的 PermissionAuthorizationApplicationModelProvider会使用 AuthorizeFilter(IAuthorizationPolicyProvider policyProvider, IEnumerableIAuthorizeData authorizeData) 创建 AuthorizeFilter 对象而不是 AuthorizeFilter(AuthorizationPolicy policy)。这会造成 AuthorizeFilter 对象在 OnAuthorizationAsync 时会间接调用 AuthorizationPolicy.CombineAsync 静态方法。这可以说是一个设计上的缺陷不应该让 AuthorizationPolicy.CombineAsync 静态方法存在哪怕提供个 IAuthorizationPolicyCombiner 也好。另外上文提到的 AuthorizationApplicationModelProvider.GetFilter 静态方法同样不是一种好的设计。等微软想通吧。参考资料https://docs.microsoft.com/zh-cn/aspnet/core/security/authorization/iauthorizationpolicyprovider?viewaspnetcore-2.1 排版问题http://blog.tubumu.com/2018/11/28/aspnetcore-mvc-extend-authorization/
http://www.pierceye.com/news/608406/

相关文章:

  • 网站如何布局wordpress 商城系统
  • 深圳专业设计网站平台网站开发国内外现状研究
  • 哪个建站软件比较好带论坛无锡网站推广优化公司
  • 英文网站建设方案 ppt模板国内代理ip免费网址
  • 城乡建设网站 资料员深圳定制型网站建设
  • 浦江网站建设微信开发手机html编辑器
  • 做网站的个人总结论坛内网站怎么建设
  • 那里有个人做网站的如何建设网页制作的网站
  • 佛山网站建设玲念建站会议管理系统
  • 网站开发需要什么资质天马行空网站建设
  • 猎聘网网站建设目标怎么做网站上的模拟动画
  • 南通制作企业网站福州做网站设计
  • 上什么网站做会计教育wordpress cookies
  • 山东网站备案号四川省建筑信息网
  • 网站开发可以用哪些语言中国十二冶金建设有限公司网站
  • 中药网站模板襄阳seo优化服务
  • 做爰片免费观看网站会展企业网站建设方案
  • 国内空间没备案可以打开网站吗dw做网站 怎么做背景图片
  • host绑定网站国外网站风格
  • 安顺建设局网站wordpress 分页
  • 重庆做网站个人外网登录不了WordPress
  • 医药平台网站建设网站排名做不上去
  • 网站关键词优化培训怎样使用wordpress
  • wordpress多站做网站空间百度云和阿里云区别
  • 衡水企业网站制作公司3000块钱在朋友圈投放广告
  • 做网站没有公网北京网页制作教程
  • 运城哪家做网站的公司好小商铺装修
  • 如何访问win7下做的网站时间轴网站模板
  • html5网站制作软件做app找哪个网站吗
  • 网站名称怎么备案外贸商城网站模板