c# - 如何根据 WebAPI 权限限制 HATEOAS 导航链接?
问题描述
我正在考虑将HATEOAS
类型链接添加到从我的路由返回的数据中,WebAPI
这将为客户端提供关于任何给定数据可用哪些操作的线索。
所以,我可能有类似的东西:
clients: {
data: [
{data: {id: 1, name: "Client One", age: 1},
_links: {
self: {href: ".../api/clients/1}, method: "get"}
edit: {href: ".../api/clients/1}, method: "put"}
delete: {href: ".../api/clients/1}, method: "delete"}
}
}
],
_links: {
self: {href: ".../api/clients", method: "get"},
add: {href: ".../api/clients", method: "post"}
}
}
我看过很多帖子都在讨论如何包含链接,这样那部分就不是问题了。
问题
背后的部分想法HATEOAS
是让您的数据自定义/自动导航。所以,我想看到的是我_links
只包括那些基于他/她的权限可供用户使用的内容。IOW,如果允许用户访问Edit
客户端而不是Delete
客户端,则_links
应该包括编辑而不是删除。
那么问题是,在生成链接时,我实际上需要评估Authorization Policy
Action/Route 以确定是否应该包含链接。
所以给定这样的东西(这是一个谈话要点——不是实际的代码):
[Route("api/v1/[controller]")]
[APIController]
[Authorize(Policy="HR")]
public class UsersController : ControllerBase {
[HttpGet]
public async Task<IActionResult> GetClients() {
var results = new List<dynamic>();
var list = context.Clients.Select(u => new BasicClient(u.Id, u.Name))
.ToList();
foreach(var client in list){
//If user has access to GetClient Action
if(??) {
client._links.Self.Href = Url.Action("GetClient", new {id = client.Id});
}
//If user has access to DeleteClient Action
if(??) {
client._links.Delete.Href = Url.Action("DeleteClient", new {id = client.Id});
}
...
}
[HttpGet("{id}", Name="GetClient")]
[Authorize(Policy="ViewClient")]
public async Task<IActionResult> GetClient(int id){ ... }
[HttpDelete("{id}", Name="DeleteClient")]
[Authorize(Policy="DeleteClient")]
public async Task<IActionResult> DeleteClient(int id) { ... }
用户需要满足HR
和ViewClients
策略所需的权限才能获取self
链接,另外还需要满足DeleteClients
策略来获取delete
链接。
这可能吗?我想错了吗?有没有更好的办法?
澄清
虽然可以使用AuthorizationService
来检查特定的策略,但我想要做的是避免使用硬编码的策略。策略已经在我试图访问的Controller
和上定义。Actions
我想知道是否有一种方法可以针对某个用户验证用户Action
(并让框架整理出需要应用什么策略)。
因此,与Url.Action("GetClient",...)
使用 an 的名称Action
并根据定义的路由构建正确链接的方式相同,我想要类似的东西AuthService.AuthorizeAction("GetClient", User)
来确定哪些权限是必要的,以及用户是否具有这些权限。
希望 .NetCore 有内置的东西可以做到这一点。如果没有,我想我可以使用反射和IAuthorizationService
来做到这一点。
解决方案
IAuthorizationService
是您正在寻找的服务。这是一个代码片段:
var result = await authorization.AuthorizeAsync(User, "IsLucky");
IsLucky = result.Succeeded;
推荐阅读
- java - Java Stream 为什么reduce需要函数式接口的两个参数?
- javascript - 在黄瓜 js 中获取覆盖率统计数据的最佳方法是什么?
- moodle - Moodle的安装
- reactjs - 与 Axios 一起在 Material ui 中进行表单验证
- cmake - 在我的项目中使用 dlib 库作为依赖项时禁用 CUDA
- java - 如何在 android studio 中恢复丢失的 keystore.jks 密码
- django - 如何在 Django admin `list_display` 中显示外键和多对多字段?
- python - vscode & python 3.9.1 - 未解决的导入
- javascript - azure storage上传图片文件并获取其url以显示img标签
- deep-learning - conv2d 的输出通道到 conv2d 的下一个输入形状可以不同吗?