仅所有者的ASP.NET Core授权

时间:2018-12-04 22:15:45

标签: asp.net razor asp.net-core razor-pages

我有一个类似于Owner based Authorization

的问题

是否可以使用resource-based authorizationpolicy-based authorization仅允许模型所有者查看/编辑/删除模型?

类似

[Authorize(Policy = "OwnerAuthorization")]
public class EditModel : PageModel

还是我必须在每个页面的每个OnGet / OnPost上添加逻辑以处理授权?

1 个答案:

答案 0 :(得分:0)

  

我是否必须在每个页面的每个OnGet / OnPost上添加逻辑以处理授权?

您不必这样做,但是为了获得更好的性能,您应该为每个页面上的每个OnGet / OnPost添加逻辑。

要以 resource-based authorization 的方式授权请求,我们首先需要知道资源是什么,然后我们才能授权用户使用该资源,并且政策

通常,我们需要从服务器加载资源,然后我们才能知道该资源是否属于当前用户。由于通常是在action方法内完成从服务器加载资源的操作,因此我们通常会在action方法内授权请求。这正是official document中描述的内容。

   var authorizationResult = await _authorizationService
            .AuthorizeAsync(User, Document, "EditPolicy");

   if (authorizationResult.Succeeded)
   {
       return Page();
   }
   else if (User.Identity.IsAuthenticated)
   {
       return new ForbidResult();
   }
   else
   {
      return new ChallengeResult();
   }

但是,如果我们选择仅用[Authorize(Policy = "OwnerAuthorization")]装饰页面模型,而不在action方法中调用_authZService.AuthorizeAsync(User, resource, "OwnerAuthorization");,则必须在授权处理程序中加载资源(或一个简单的功能)。换句话说,我们将两次查询数据库。假设用户想要编辑Foo模型,然后向/Foo/Edit?id=1发出HTTP GET请求以显示表单。 OnGetAsync(int? id)方法是:

    public async Task<IActionResult> OnGetAsync(int? id)
    {
        if (id == null){ return NotFound(); }
        // load foo from database
        Foo = await _context.Foos.FirstOrDefaultAsync(m => m.Id == id);

        if (Foo == null){ return NotFound(); }
        return Page();
    }

现在,基于资源的授权将从数据库中加载Foo实体并检查所有者。如果成功,则该操作方法将验证model.id并再次从数据库中加载资源。