我正在建立一个基于各种API控制器的系统。使用适当的jwt令牌。 (此令牌包含用户以及他有权访问的客户) 当前,根据惯例,控制器需要检查给定用户是否可以访问所讨论的客户。
我想知道是否可以做得更好一些:)-可以说,如果基本URL始终是/ api / customer //,那么最好的解决方案是制作一个“东西”,该东西始终检查是否是其中一部分的特定用户声明。
答案 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";
}
当然,您也可以在应用程序中全局注册策略。