将参数传递给ASP.NET MVC 6中的需求/策略

时间:2015-08-24 11:39:12

标签: asp.net-core asp.net-core-mvc

我试图在ASP.NET vNext中创建一个自定义授权属性,直到我在这篇文章中找到@blowdart的这个优秀答案:

https://stackoverflow.com/a/31465227/1756978

表示授权要求现在是可行的方法。答案非常明确,但没有说明如何将参数传递给此要求/政策。

我要做的是移植具有此签名的MVC 5自定义授权属性:

[Autorizacion(Requires = enumPermission.DeleteCustomer)]

因为我使用在后端/前端镜像的一组非常自定义的权限作为枚举/字符串。

由于这些功能仍然没有记录,我觉得有点迷失......有人可以提供指导吗?

提前致谢

2 个答案:

答案 0 :(得分:0)

确实,@ blowdart的帖子非常有见地,根据我的理解,要理解的关键是以下内容:

  

对身份的授权法。身份由...创建   认证

所以看来身份是由身份验证过程创建的。

然后(如果您愿意)您可以启动授权流程。这意味着创建一个自定义authorization requirements,此要求将查看这些身份并对其采取行动。

用简单的英语说,这就是我认为正在发生的事情:

  1. 正如在blowdart的帖子中提到的,我们应该有某种形式 认证中间件碰巧做了实际的 认证。一旦成功通过身份验证,您就可以采取任 您想从现在经过身份验证的用户那里获得的信息并创建一个 经过身份验证的ClaimsPrincipal

    例如,我们可以存储ClaimsPrincipal个集合 用户拥有的权限。

  2. 然后,当您创建authorization requirement时,您会看到 ClaimsPrincipal,从中提取权限集 ClaimsPrincipal并根据任何事情采取适当的行动 你想要的商业规则。

    假设您无法将权限集存储到 ClaimsPrincipal由于某种原因,可以轻松存储UserId 从需求中,从中读取UserId ClaimsPrincipal,调用数据库并获取权限集 然后对他们采取行动。

  3. 结论:

    所以简而言之,我认为你传递东西并不符合要求,我认为你ClaimsPrincipal获得

    在您的示例中,您可以创建一个读取ClaimsPrincipal的要求,并将与Enum的任何值进行比较并对其采取行动。

    告诉我们您的设施以及是否有效。

    如果我对此的理解是错误的,那么无论如何,请随意纠正我,因为所有这些都是新的东西: - )

答案 1 :(得分:0)

我碰巧提出了一种可以满足我的要求的工作环境,希望它也能对您有所帮助。

就我而言,我需要将IHttpContextAccessor和EFCore的AppDbContext传递给我的Requirement类。

在我的Startup.cs中,我这样写:

services.AddAuthorization(options =>
{
    options.AddPolicy("ThePolicy", policy => policy.Requirements.Add( new ThePolicyRequirement() ));
});
services.AddScoped<IAuthorizationHandler, ThePolicyAuthorizationHandler>();

ThePolicyAuthorizationHandler类:

public class ThePolicyAuthorizationHandler : AuthorizationHandler<ThePolicyRequirement>
{
    readonly AppDbContext _appContext;
    readonly IHttpContextAccessor _contextAccessor;

    public ThePolicyAuthorizationHandler(AppDbContext c, IHttpContextAccessor ca)
    {
        _appContext = c;
        _contextAccessor = ca;
    }

    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ThePolicyRequirement requirement)
    {
        var result = await requirement.isPass(_appContext, _contextAccessor, context);
        if (result)
            context.Succeed(requirement);
        else
            context.Fail(requirement);
    }
}

ThePolicyRequirement类:

public class ThePolicyRequirement : IAuthorizationRequirement
{
    AppDbContext _context;
    IHttpContextAccessor _contextAccessor;
    AuthorizationHandlerContext _authHandlerContext;

    public async Task<bool> isPass(AppDbContext context, IHttpContextAccessor contextAccessor, AuthorizationHandlerContext authorizationHandlerContext)
    {
        _context = context;
        _contextAccessor = contextAccessor;
        _authHandlerContext = authorizationHandlerContext;

        //logic here

        return result;
    }
}

关键思想是使用ThePolicyAuthorizationHandler获得尽可能多的所有所需对象,并将其传递给ThePolicyRequirement以执行授权机制的逻辑。