authorization - 根据路径过滤
问题描述
我正在制作一个基于各种 API 控制器的系统。使用适当的 jwt 令牌。(此令牌包含用户,以及他可以访问的客户)目前控制器需要按照惯例检查给定用户是否可以访问相关客户。
我想知道我是否可以更优雅地做到这一点:) - 假设基本 url 总是 /api/customer//,那么最好的解决方案是制作一个“东西”,总是检查是否是给定用户的一部分宣称。
解决方案
您可以在 ASP.NET Core中使用基于策略的授权。
为了满足您的要求,首先创建授权策略:
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";
}
当然,您也可以在您的应用程序中全局注册该策略。
推荐阅读
- linux - 如何在 linux bash 提示符下拆分模式上的字符串并返回模式的最后一个实例以及之后的所有内容
- php - 使用 file_get_contents 获取属性值
- python - 数据未附加到我的输出文件中,python csv 模块 3.6
- ruby-on-rails - Rspec 测试关联导致失败
- node.js - express 能否同时处理两个或多个请求?
- javascript - 如何实现确定性/基于刻度的游戏循环?
- tensorflow - 多值张量上的 TensorFlow 优化器
- javascript - 如何让 Sweetalert 返回真/假以确认没有承诺?
- mysql - 如何按用户每台设备选择最后一条消息
- memory - 无法移出作为参数传递的可选成员的借用内容