Я пытаюсь реализовать политику на довольно детальном уровне. Идея как на картинке.
Каждый объект всегда имеет отношение Один ко многим с объектом справа. Одно учебное заведение может иметь несколько курсов, каждый курс может включать множество предметов, каждый предмет strong > может быть много учебных программ и т. д.
Есть 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));
}
Вы знаете, есть ли такое решение?