Asp Core MVC 2.1授权基于每个用户的策略?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Asp Core MVC 2.1授权基于每个用户的策略?相关的知识,希望对你有一定的参考价值。

在我的Web应用程序中,我想以这种方式根据用户应用策略。例如,我有3个政策;

  1. 允许周一进入。
  2. 允许在某个小时进入。
  3. 禁止进入。
  4. ...

用户John已激活策略1,而用户Richard仅激活了策略2.例如,如果用户John在我的应用程序中注册了ok,但在某个控制器中将不允许该步骤,因为它是星期一。这些条件可以在执行时间内改变。如何在动作控制器中动态添加策略?

我一直在寻找,但我在asp.net核心中看到的是我必须向启动注册策略,这不符合我的逻辑。

答案

我认为干净利落地解决这个问题有两个关键:

多个处理程序

首先,创建一个简单的要求:

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数据库(或任何其他源)获取数据,这将允许在应用程序运行时调整规则。

以上是关于Asp Core MVC 2.1授权基于每个用户的策略?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Azure AD 的 Asp.net core mvc 基于角色的授权

EF Core 中的 ASP.NET Core 5 MVC 和 Identity - 基于资源的授权

ASP.NET Core MVC 授权的扩展:自定义 Authorize Attribute 和 IApplicationModelProvide

如何使用基于声明的授权保护 asp.net core 2.1 中的静态文件夹

在 ASP.NET Core 中的每个操作之前查询数据库以获得角色授权

深入浅出 ASP.NET Core 基于JWT的认证和授权