我是否必须为每个页面上的每个 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")] 装饰页面模型,并且不在操作方法中调用_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 实体并检查所有者。如果成功,则 action 方法将验证 model.id 并再次从数据库加载资源。