我正在为 ASP.NET MVC 2 中的特许经营服务业务构建基于 Web 的 CRM + CMS 的第二次迭代。我需要根据用户为该特许经营分配的角色来控制对每个特许经营服务的访问。
4个例子:
Receptionist
应该能够为她的“大西洋海岸”特许经营权预订服务工作,但不做任何报告。Technician
应该能够更改服务工作,但不能修改发票。Managers
应该能够为其商店内的工作发票应用折扣。Owner
应该能够提取他拥有的任何特许经营权的报告。
特许经营级别的访问控制应该在Data - Services - Web
层之间的什么位置?
如果它属于我的控制器,我应该如何最好地实现它?
部分模式
Roles
班级
int ID { get; set; } // primary key for Role
string Name { get; set; }
部分Franchises
类
short ID { get; set; } // primary key for Franchise
string Slug { get; set; } // unique key for URL access, eg /{franchise}/{job}
string Name { get; set; }
UserRoles
映射
short FranchiseID; // related to franchises table
Guid UserID; // related to Users table
int RoleID; // related to Roles table
DateTime ValidFrom;
DateTime ValidUntil;
控制器实现
[Authorize]
带属性的访问控制
如果只涉及一个特许经营权,我可以简单地限制对控制器操作的访问,如下所示:
[Authorize(Roles="Receptionist, Technician, Manager, Owner")]
public ActionResult CreateJob(Job job)
{
...
}
而且由于特许经营权不会在一夜之间突然出现,也许这是使用ASP.NET MVC 2 中的新区域功能的一个强有力的案例?或者这会导致重复的视图?
控制器、URL 路由和区域
假设不使用区域,确定正在访问哪个特许经营权数据的最佳方法是什么?我想到了这个:
{franchise}/{controller}/{action}/{id}
还是在 Details(...) 操作中确定工作的特许经营权并使用 [Authorize] 限制用户的操作是否更好:
{job}/{id}/{action}/{subaction}
{invoice}/{id}/{action}/{subaction}
如果任何用户都可以访问多个特许经营权而不会使用 {franchise} 参数混淆 URL,那么这更有意义。
任何输入表示赞赏。
编辑:
背景
我用经典的 ASP 构建了以前的 CRM,它运行良好,但现在是时候进行升级以加快工作流程并减少出错空间。为了正确测试和更好地分离数据和表示,我决定实现存储库模式,如 Rob Conery 的 MVC Storefront 系列中所示。
如何安排服务和存储库?
JobService
有一个基于可用过滤器检索任何服务作业的a 是有意义的,例如。IQueryable<Job> GetJobs();
. 但是由于一项工作只能属于一个特许经营权,因此类似的功能IQueryable<Job> GetJobs(int franchiseID);
可能属于其中之一FranchiseService
或JobService
. 应该FranchiseService
充当CatalogService
(就像在 MVC Storefront 中一样)?