【问题标题】:How to restrict HATEOAS navigation links based on WebAPI permissions?如何根据 WebAPI 权限限制 HATEOAS 导航链接?
【发布时间】:2020-02-28 03:40:22
【问题描述】:

我正在考虑将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 应该包括编辑而不是删除。

那么问题在于,在生成链接时,我实际上需要评估 Action/Route 的 Authorization Policy 以确定是否应包含链接。

所以给出这样的东西(这是一个谈话要点——不是实际的代码):

[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) { ... }

用户需要满足HRViewClients 策略所需的权限才能获得self 链接,另外还需要满足DeleteClients 策略才能获得delete 链接。

这可能吗?我在想这个错误吗?有没有更好的办法?

澄清

虽然可以使用AuthorizationService 来检查特定的策略,但我想要做的是避免使用硬编码的策略。策略已经在我试图访问的ControllerActions 上定义。我想知道是否有办法根据Action 验证用户(并让框架整理出需要应用什么策略)。

因此,就像Url.Action("GetClient",...) 采用Action 的名称并根据定义的路由构建正确的链接一样,我想要类似AuthService.AuthorizeAction("GetClient", User) 的东西,它会确定哪些权限是必要的,如果用户拥有这些权限。

希望 .NetCore 有内置的东西可以做到这一点。如果没有,我想我可以使用反射和IAuthorizationService 来做到这一点。

【问题讨论】:

    标签: c# rest asp.net-core-webapi hateoas


    【解决方案1】:

    IAuthorizationService 是您正在寻找的服务。这是一个代码sn-p:

    var result = await authorization.AuthorizeAsync(User, "IsLucky");
    IsLucky = result.Succeeded;
    

    信用:https://odetocode.com/blogs/scott/archive/2019/05/30/evaluating-asp-net-core-authorization-policies.aspx

    【讨论】:

    • 我可能解释得不够清楚。我正在尝试做的是根据路由上定义的内容测试每条路由的策略——而不是通过硬编码。 IOW,在我的示例中,DeleteClient 路由定义了 DeleteClient 策略。我想以某种方式检查用户是否拥有DeleteClient 路由的权限,而无需对DeleteClient 策略进行硬编码。如果政策在未来发生变化,我不想在我的代码中搜索该政策的硬编码检查。
    • @RHarris 正如您在编辑中解释的那样,如果您想自动化它,反射似乎是要走的路。你也可以使用常量,这样你就不需要到处更改了。
    猜你喜欢
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 2015-08-23
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    相关资源
    最近更新 更多