ASP.NET MVC服务层复杂授权

ASP.NET MVC service layer complex authorization

我对 authorization/Validation 在服务层中执行任何数据库更新之前的用户操作有疑问。

我有一个 JobPostingController,它提供了 create/update/delete 职位发布的方法。

我希望用户只有当他是实体的所有者时才能 update/delete 发布职位。 (在我的 JobPosting 实体中有类似 JobPostingOwner 的东西)

是否有一种简单的方法来创建自定义控制器操作过滤器来实现此目的?

根据我的理解,检查是否允许用户 update/delete 特定实体应该在服务层中,但不知道是否有比

更简单的方法
public void UpdateJobPosting(JobPosting jobPosting, User user)
{
    if(jobPostingOwnerId == user.Id) --> OK
    else --> not OK
}

另一个简单的例子:

/JobPosting/Edit/(id)

我想始终检查是否真的允许用户编辑此职位发布。 所以在服务层我会做:

public JobPosting GetJobPosting(int id, User user)
{
    var query = from item in context.JobPostings
                where item.id == id
                && item.OwnerId == user.Id
                select item;

    ....
}

这是执行此操作的正确方法还是有其他模式?

首先你需要在你的服务层中使用这样的方法:

public bool IsUserAllowed(int potingId, User user)
{
            var query = from item in context.JobPostings
                        where item.id == potingId
                        && item.OwnerId == user.Id
                        select item;
            var result = query.FirstOrDefault();
            return result != null;
}

然后创建一个自定义操作过滤器(一个 class 命名为 CustomActionFilterAttribute 派生自 AuthorizeAttribute),在 AuthorizeCore 方法中您可以简单地检查用户的权限:

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
            base.AuthorizeCore(httpContext);
            var routeData = httpContext.Request.RequestContext.RouteData;
            var jobPostingId = (routeData.Values["id"] as string) ?? (httpContext.Request["id"] as string);
            var user = UserManager.FindUser(httpContext.User.Identity.GetUserId<int>());
            return _jobPosting.IsUserAllowed(int.Parse(jobPostingId), user);
}

最后,您必须使用自定义操作过滤器修饰您的 Edit 操作方法:

[CustomActionFilter]
[HttpPost]
public ActionResult Edit(int id)
{
  // ....
}