Adding .Net Core Policy with variable Parameters on Requirements

♀尐吖头ヾ 提交于 2019-12-19 11:53:55

问题


I am trying to implement a Policy that is quite granular level. The idea is like in the image.

Each entity has always the One-To-Many relation with the entity on the right. One Institution can have many Courses, each Course can have many Subjects, each Subject can have many Syllabus, etc...

There are 3 Roles: Administrator, Contributor, Viewer

If you have a Role in one of the top entities this role will be propagated to the rest bellow. E.g: If you are an Administrator of Course you are administrator of Subject, Syllabus, etc...

If you are Contributor of one of the Syllabus you will be Contributor for bellow Lessons and Videos of this Syllabus.

I have tried to solve it using Custom Policies:

Adding a requirement like below:

public class AdministratorRequirement : IAuthorizationRequirement
    {
        public int UserId { get; private set; }
        public EntityType EntityType { get; private set; }
        public int EntityId { get; private set; }

        public AdministratorRequirement(int userId, EntityType entityType, int entityId)
        {
            UserId = userId;
            EntityType = entityType;
            EntityId = entityId;
        }
    }

And adding the Policy Handler as bellow:

public class AdministratorHandler : AuthorizationHandler<AdministratorRequirement>
    {
        public IRolesRepository RolesRepository {get;set;}

        public AdministratorHandler(IRolesRepository rolesRepository)
        {
            RolesRepository = rolesRepository;
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdministratorRequirement requirement)
        {
            // Save User object to access claims
            bool isAdministrator = RolesRepository.CheckUserRole(requirement.UserId, requirement.EntityType, requirement.EntityId, "Administrator");

            if (isAdministrator)
                context.Succeed(requirement);

            return Task.CompletedTask;

        }
    }

The problem is that I would like to define variable requirement on the Startup class:

  options.AddPolicy("CourseAdministrator",
                                    policy => policy
                                            .Requirements
                                            .Add(
                                                    new AdministratorRequirement(
                                                    /*userId - should be variable*/ 0,
                                                    EntityType.Course,
                                                    /*int entityId - should be variable*/ 0))

And use it on something like

    [Authorize(/*pass some parameters in here like user Id and course Id*/)]
    [HttpPost]
    [Route("create")]
    public async Task<IActionResult> CreateCourse([FromBody] Course course)
    {
        //Or call the policy handler programatically in here.
        CleanCacheOnUpdateCourse();
        return Ok(await Services.CreateCourse(course, EmauaUser));
    }

Do you know if there is such a solution?


回答1:


For Policy, you need to pass the satic variable.

If you want to check the permission dynamically, you could implement your own IAuthorizationFilter like

  1. custom IAuthorizationFilter

    public class CustomAuthorize : IAuthorizationFilter         
    {
            private readonly int _input;
    
            public CustomAuthorize(int input)
            {
                _input = input;
            }
    
            public void OnAuthorization(AuthorizationFilterContext context)
            {
                //custom validation rule
                if (_input == 1)
                {
                    context.Result = new ForbidResult();
                }
            }
    }
    
    1. Custom CustomAuthorizeAttribute

              public class CustomAuthorizeAttribute : TypeFilterAttribute
              {
                    public CustomAuthorizeAttribute(int input) : base(typeof(CustomAuthorize))
                    {
                        Arguments = new object[] { input };
                    }
              }
      
    2. Use

           [CustomAuthorizeAttribute(1)]
          public IActionResult About()        
      


来源:https://stackoverflow.com/questions/58859199/adding-net-core-policy-with-variable-parameters-on-requirements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!