如何为特许经营企业进行基于角色的访问控制?
我正在 ASP.NET MVC 2 中为特许经营服务业务构建基于 Web 的 CRM+CMS 的第二次迭代。我需要根据为该特许经营的用户分配的角色来控制对每个特许经营的服务的访问。
4 个示例:
接待员
应该能够为她的“Atlantic Seaboard”特许经营权预订服务工作,但不能做任何报告。技术人员
应该能够改变服务工作,但不能修改发票。经理
应该能够对其商店内的工作发票应用折扣。所有者
应该能够提取他拥有的任何特许经营权的报告。
特许经营级访问控制应位于数据 - 服务 - 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
使用 [Authorize]
属性映射
short FranchiseID; // related to franchises table
Guid UserID; // related to Users table
int RoleID; // related to Roles table
DateTime ValidFrom;
DateTime ValidUntil;
控制器实现
访问控制
如果只有涉及一个特许经营权,我可以简单地限制对控制器操作的访问,如下所示:
[Authorize(Roles="Receptionist, Technician, Manager, Owner")]
public ActionResult CreateJob(Job job)
{
...
}
由于特许经营权不会在一夜之间突然出现,也许这是使用 ASP 中新的区域功能的有力案例。 NET MVC 2?或者这会导致重复的视图吗?
控制器、URL 路由和区域
假设未使用区域,那么确定正在访问哪个特许经营权的数据的最佳方法是什么?我想到了这一点:
{franchise}/{controller}/{action}/{id}
或者更好的是在“详细信息(...)”操作中确定一份工作的特许经营权并使用[授权]限制用户的操作:
{job}/{id}/{action}/{subaction}
{invoice}/{id}/{action}/{subaction}
如果任何用户可以在没有授权的情况下访问多个特许经营权,那么这更有意义。使用 {franchise} 参数使 URL 变得混乱。
任何意见都会受到赞赏。
编辑:
背景
我用经典 ASP 构建了以前的 CRM,业务运行良好,但现在是升级的时候了,以加快工作流程并减少出错的空间。为了正确测试以及更好地分离数据和表示,我决定实现存储库模式,如 Rob Conery 的 MVC Storefront 系列中所示。
如何安排服务和存储库?
拥有一个基于可用过滤器检索任何服务作业的 JobService
是有意义的,例如。 IQueryable<作业>; GetJobs();
。但由于一项工作只能属于一个特许经营权,因此像 IQueryableFranchiseService
或 JobService
。 FranchiseService
是否应该充当 CatalogService
(就像在 MVC Storefront 中一样)?
I'm building the 2nd iteration of a web-based CRM+CMS for a franchise service business in ASP.NET MVC 2. I need to control access to each franchise's services based on the roles a user is assigned for that franchise.
4 examples:
Receptionist
should be able to book service jobs in for her "Atlantic Seaboard" franchise, but not do any reporting.Technician
should be able to alter service jobs, but not modify invoices.Managers
should be able to apply discount to invoices for jobs within their stores.Owner
should be able to pull reports for any franchises he owns.
Where should franchise-level access control fit in between the Data - Services - Web
layer?
If it belongs in my Controllers, how should I best implement it?
Partial Schema
Roles
class
int ID { get; set; } // primary key for Role
string Name { get; set; }
Partial Franchises
class
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
mapping
short FranchiseID; // related to franchises table
Guid UserID; // related to Users table
int RoleID; // related to Roles table
DateTime ValidFrom;
DateTime ValidUntil;
Controller Implementation
Access Control with [Authorize]
attribute
If there was just one franchise involved, I could simply limit access to a controller action like so:
[Authorize(Roles="Receptionist, Technician, Manager, Owner")]
public ActionResult CreateJob(Job job)
{
...
}
And since franchises don't just pop up over night, perhaps this is a strong case to use the new Areas feature in ASP.NET MVC 2? Or would this lead to duplicate Views?
Controllers, URL Routing & Areas
Assuming Areas aren't used, what would be the best way to determine which franchise's data is being accessed? I thought of this:
{franchise}/{controller}/{action}/{id}
or is it better to determine a job's franchise in a Details(...) action and limit a user's action with [Authorize]:
{job}/{id}/{action}/{subaction}
{invoice}/{id}/{action}/{subaction}
which makes more sense if any user could potentially have access to more than one franchise without cluttering the URL with a {franchise} parameter.
Any input is appreciated.
Edit:
Background
I built the previous CRM in classic ASP and it runs the business well, but it's time for an upgrade to speed up workflow and leave less room for error. For the sake of proper testing and better separation between data and presentation, I decided to implement the repository pattern as seen in Rob Conery's MVC Storefront series.
How to arrange services and repositories?
It makes sense to have a JobService
that retrieves any service jobs based on available filters, eg. IQueryable<Job> GetJobs();
. But since a job can only belong to one franchise, a function like IQueryable<Job> GetJobs(int franchiseID);
could belong in either FranchiseService
or in JobService
. Should FranchiseService
act as a CatalogService
(like in MVC Storefront)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我尝试回答一下这个问题。我正在使用一个涉及上述某些方面的示例应用程序。这不是权威答案,只是经验。
特许经营级访问控制应位于数据 - 服务 - Web 层之间的哪个位置?
由于特许经营权不会在一夜之间突然出现,也许这是使用 ASP.NET MVC 2 中新的 Areas 功能的一个强有力的案例?或者这会导致重复的视图?
假设未使用区域,确定正在访问哪个特许经营权的数据的最佳方法是什么?
如何安排服务和存储库?
希望这有帮助..
Let me take a stab at answering this. I am in the process of playing with a sample app that touches some of the aspects mentioned. This is not an authoritative answer, merely experience.
Where should franchise-level access control fit in between the Data - Services - Web layer?
Since franchises don't just pop up over night, perhaps this is a strong case to use the new Areas feature in ASP.NET MVC 2? Or would this lead to duplicate Views?
Assuming Areas aren't used, what would be the best way to determine which franchise's data is being accessed?
How to arrange services and repositories?
Hope this helps..