根据路径过滤

时间:2019-05-13 21:29:31

标签: authorization asp.net-core-webapi

我正在建立一个基于各种API控制器的系统。使用适当的jwt令牌。 (此令牌包含用户以及他有权访问的客户) 当前,根据惯例,控制器需要检查给定用户是否可以访问所讨论的客户。

我想知道是否可以做得更好一些:)-可以说,如果基本URL始终是/ api / customer //,那么最好的解决方案是制作一个“东西”,该东西始终检查是否是其中一部分的特定用户声明。

1 个答案:

答案 0 :(得分:0)

您可以在ASP.NET Core中使用Policy-based authorization

要满足您的要求,请首先创建授权策略:

services.AddAuthorization(options =>
{
    options.AddPolicy("CustomRequire", policy =>
        policy.Requirements.Add(new CustomerRequirement()));
});

注册一个需求,创建CustomerRequirement.cs

public class CustomerRequirement : IAuthorizationRequirement
{
    public CustomerRequirement()
    {
    }
}

创建CustomerHandler.cs

public class CustomerHandler : AuthorizationHandler<CustomerRequirement>
{
    IHttpContextAccessor _httpContextAccessor = null;

    public CustomerHandler(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                CustomerRequirement requirement)
    {

        HttpContext httpContext = _httpContextAccessor.HttpContext;


        var path = httpContext.Request.Path;

        //split the path to get the customer base on your path .

        var customerName = "customerFromPath";

        if (!context.User.HasClaim(c => c.Type == "customer"))
        {
            return Task.CompletedTask;
        }

        var customer = context.User.FindAll(c => c.Type == "customer" ).FirstOrDefault();

        if (customerName.Equals(customer.Value.ToString()))
        {
            context.Succeed(requirement);
        }

        //TODO: Use the following if targeting a version of
        //.NET Framework older than 4.6:
        //      return Task.FromResult(0);
        return Task.CompletedTask;
    }
}

要使用IHttpContextAccessor,您可能需要在DI设置中进行注册,如下所示:

services.AddHttpContextAccessor();

在配置期间在服务集合中注册处理程序:

services.AddSingleton<IAuthorizationHandler, CustomerHandler>();

现在您可以将策略应用于MVC控制器:

[Authorize(Policy = "CustomRequire")]
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
    return "value";
}

当然,您也可以在应用程序中全局注册策略。