MVC - 仅允许用户编辑自己的数据

时间:2015-06-08 22:59:30

标签: c# asp.net asp.net-mvc

我正在编写一个具有相对复杂数据模型的MVC 5应用程序。

我有列表和列表与相关的相册。

为了开始,我只是确保当用户试图调用控制器的Edit函数时,该用户是该对象的所有者。像这样:

     // Listing Controller
public bool VerifyOwnership(int? id)
        {
            if (id == null) return false;

            Listing listingModel = db.Listings.Find(id);
            if (listingModel == null)
            {
                return false;
            }
            else
            {
                return User.Identity.GetUserId() == listingModel.SellerID;
            }
        }

但是,此检查现在在我的代码库中传播。由于相册属于商家信息,因此此代码对我来说似乎可怕

// AlbumController    
public ActionResult Edit(int? id, int listingId)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Album a = db.Albums.Find(id);
            if (a == null)
            {
                return HttpNotFound();
            }

            var l = new ListingController();
            if (!l.VerifyOwnership(listingId))
                return new HttpStatusCodeResult(HttpStatusCode.Forbidden);


            ViewBag.ListingID = listingId;

            return View(a);
        }

我认为我这样做错误

理想情况下,Album控制器不会仅仅为了检查所有权而实例化ListingController。我可以将所有权逻辑从ListingController中复制出来并粘贴到AlbumController中,但现在我要复制粘贴代码。呸。

我读了这篇关于创建自定义Authorize属性的文章 - ASP.NET MVC Attribute to only let user edit his/her own content,除了我不确定如何在AuthorizeCore覆盖中实例化ApplicationDbContext对象以便我可以查找所有者之外,这似乎没问题。上市并做我的检查。可以毫不费力地创建ApplicationDbContext对象吗?它们是与持久性数据库连接相关还是抽象的?

1 个答案:

答案 0 :(得分:0)

这是你出错的地方......

 Album a = db.Albums.Find(id);

我可以输入任何ID,您的应用会去取得它,然后执行不需要的所有权验证......

从另一端解决问题,如果我们根据用户首先访问的内容确定结果的范围,然后在用户有权访问的范围内搜索相册,该怎么办?以下是一些例子,让您了解我的意思。

db.Users.Where(user => user.Id == this.CallerId)
        .SelectMany(user => user.Albums)
        .Where(album => album.Id == "foo");

db.Albums.Where(album => album.OwnerId == this.CallerId)
         .Where(album => album.Id == "bar");

这一切都将归结为数据库的布局以及映射实体模型的方式,但概念是相同的。