Я думаю, что есть два ключа для правильного решения:
Несколько обработчиков
Сначала создайте простое требование:
public class CustomPolicyRequirement : IAuthorizationRequirement { }
Затем создайте для него необходимые обработчики.Я сделал несколько очень простых примеров обработчиков на основе описанных вами политик:
public class MondaysRequirementHandler : AuthorizationHandler<CustomPolicyRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomPolicyRequirement requirement)
{
// Allow John in on Mondays
if (DateTime.Now.DayOfWeek == DayOfWeek.Monday && context.User.Identity.Name == "John")
context.Succeed(requirement);
return Task.CompletedTask;
}
}
public class EveningsOnlyRequirementHandler : AuthorizationHandler<CustomPolicyRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomPolicyRequirement requirement)
{
var now = DateTime.Now;
// Allow Richard in, as long as it's between 18:00 and 22:00
if (now.Hour >= 18 && now.Hour < 22 && context.User.Identity.Name == "Richard")
context.Succeed(requirement);
return Task.CompletedTask;
}
}
public class ProhibitedUserRequirementHandler : AuthorizationHandler<CustomPolicyRequirement>
{
readonly IProhibitedUsersService prohibitedUsersService;
public ProhibitedUserRequirementHandler(IProhibitedUsersService prohibitedUsersService)
=> this.prohibitedUsersService = prohibitedUsersService;
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomPolicyRequirement requirement)
{
// Don't let prohbited users in, even if other handlers are satisfied
if (prohibitedUsersService.IsUserProhibited(context.User.Identity))
context.Fail();
return Task.CompletedTask;
}
}
Поскольку все обработчики связаны с CustomPolicyRequirement
, требование будет удовлетворяться до тех пор, пока хотя бы один обработчик будет успешным, ини один из них не сможет.Обработчики, которые ни преуспевают, ни терпят неудачу, не влияют на результат.
Динамические данные
Третий примерный обработчик зависит от службы, внедряемой зависимостями:
public interface IProhibitedUsersService
{
bool IsUserProhibited(IIdentity user);
}
Эта служба можетбыть реализован для извлечения данных из базы данных SQL (или любого другого источника), что позволит корректировать правила во время работы приложения.