序言:这是一个哲学问题.我正在寻找更好的"正确"方式来做到这一点而不是"一种"方式来做到这一点.
让我们假设我有一些产品,以及在这些产品上执行CRUD的ASP.NET MVC应用程序: -
mysite.example/products/1
mysite.example/products/1/edit
Run Code Online (Sandbox Code Playgroud)
我正在使用存储库模式,因此这些产品来自何处并不重要: -
public interface IProductRepository
{
IEnumberable<Product> GetProducts();
....
}
Run Code Online (Sandbox Code Playgroud)
我的存储库还描述了一个用户列表,以及他们管理的产品(用户和产品之间的许多产品).在应用程序的其他地方,Super-Admin正在对用户执行CRUD并管理用户与他们被允许管理的产品之间的关系.
任何人都可以查看任何产品,但只允许为特定产品指定为"管理员"的用户调用例如编辑操作.
我应该如何在ASP.NET MVC中实现它?除非我错过了什么,否则我不能使用内置的ASP.NET Authorize属性,因为我需要为每个产品使用不同的角色,其次我不知道要检查哪个角色直到我从存储库中检索了我的产品.
显然,您可以将此场景概括为大多数内容管理方案 - 例如,用户只能编辑自己的论坛帖子.StackOverflow用户只能编辑他们自己的问题 - 除非他们有2000或更多代表...
作为一个例子,最简单的解决方案是:
public class ProductsController
{
public ActionResult Edit(int id)
{
Product p = ProductRepository.GetProductById(id);
User u = UserService.GetUser(); // Gets the currently logged in user
if (ProductAdminService.UserIsAdminForProduct(u, p))
{
return View(p);
}
else
{
return RedirectToAction("AccessDenied");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
我可能会保持这个更新,因为我自己有想法,但我非常渴望听到你的想法!
提前致谢!
编辑
只是在这里添加一些细节.我遇到的问题是,我希望业务规则"只有具有权限的用户可以编辑产品"才能包含在一个且只有一个地方.我觉得确定用户是否可以对"编辑"操作进行GET或POST的相同代码也应该负责确定是否在"索引"或"详细信息"视图上呈现"编辑"链接.也许这不可能/不可行,但我觉得应该...... …
我正在寻找一种方法来自定义我的授权属性,以便我可以使用我自己的MembershipProvider正确实现它.
我需要的是拥有IsInRoles(字符串角色,int perm),换句话说,我想让它替换为新的IsinRoles,或者可能创建另一种方法来存档此结果.
可能吗?或者我需要写一个不同的授权属性?
非常感谢您的关注......
PS:我在ASP.net MVC上工作,所以我需要启动[授权]过滤器.