Добавление политики .Net Core с переменными параметрами по требованиям

Я пытаюсь реализовать политику на довольно детальном уровне. Идея как на картинке.

введите описание изображения здесь

Каждый объект всегда имеет отношение Один ко многим с объектом справа. Одно учебное заведение может иметь несколько курсов, каждый курс может включать множество предметов, каждый предмет может быть много учебных программ и т. д.

Есть 3 роли: Administrator, Contributor, Viewer

Если у вас есть роль в одной из верхних сущностей, эта роль будет распространена на остальные, указанные ниже. Например: если вы являетесь администратором курса, вы являетесь администратором предмета, учебной программы и т. Д.

Если вы являетесь участником одной из программ, вы будете участником следующих уроков и видео этой программы.

Я попытался решить эту проблему с помощью Custom Policies:

Добавление требования, как показано ниже:

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;
        }
    }

И добавляем обработчик политики, как показано ниже:

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;

        }
    }

Проблема в том, что я хотел бы определить требование переменной для класса Startup:

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

И используйте это на чем-то вроде

    [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));
    }

Вы знаете, есть ли такое решение?


person Tito    schedule 14.11.2019    source источник


Ответы (1)


Для политики вам необходимо передать переменную satic.

Если вы хотите динамически проверять разрешение, вы можете реализовать свой собственный IAuthorizationFilter, например

  1. индивидуальный 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. Пользовательский CustomAuthorizeAttribute

              public class CustomAuthorizeAttribute : TypeFilterAttribute
              {
                    public CustomAuthorizeAttribute(int input) : base(typeof(CustomAuthorize))
                    {
                        Arguments = new object[] { input };
                    }
              }
      
    2. Использовать

           [CustomAuthorizeAttribute(1)]
          public IActionResult About()        
      
person Edward    schedule 15.11.2019