本文我们将讨论的是ASPNET MVC Membership权限的设置以及其他的一些问题希望能帮助大家更好的应用ASPNET MVC令开发更快乐
以前一位同事习惯于使用Membership来进行权限管理现在随着ASPNET MVC的引入采用以前的方法提出了以下方案
ASPNET MVC+Membership结合通过在nfig中进行配置来管理系统中的权限
于是我对这个方案的可行性进行了分析提出了以下疑点
在ASPNET 的Membership中 在nfig中是通过物理文件和目录那么在ASPNET MVC中如果在URL中直接输入物理文件和目录是找不到这个文件的不知道这种方式还能不能奏效如果说不管在mvc中通过URL Routing怎么绕最终都会定位到物理文件和目录上这种方式是行得通的如果不是文件目录结构的话nfig这种配置是否还能用?关于我提出的这个疑点当时我觉得非常的有趣为了验证我的疑点于是我做了一个测试
经过一个简单的Demo测试结果出来了测试结果如下
在ASPNET MVC的Membership中并不是基于文件和目录的而是易于URLRouting的当进行文件目录配置的话是不起作用的只有在nfig中进行URLRouting的权限配置才会起作用最终经过测试如果按照默认路由走的话最终也是可以通过配置进行权限的控制只不过是配置起来的话要把文件路径改为controller/action而不是原来的Controller/Actionaspx
接下来再想一想这样会不会有什么问题?
以往的Webform开发url是稳定因素(URL重写除外)所以通过Membership进行权限设定是没有问题的但是在MVC中URL是不稳定因素如果更改了routing设置权限系统就会被绕过去从模块职责上来说不应该因为其它模块的更改导致权限管理模块失效这从设计上就是一个糟糕的设计所以从个人情感上来说我认为这种设计糟糕透了既然URL是不稳定因素不应该通过这个来进行权限控制也就是说不应该通过不稳定因素来参杂权限管理 URL是不稳定的那么较稳定的因素应该就是Controller跟Action也就是说无论URL怎么变最终都可以把Controller跟Action确定下来因此在ASPNET MVC中应该通过Controller跟Action结合来进行权限控制了解URLRouting的朋友们一定知道MVC中的路由是按照顺序执行的如果满足了前面的匹配规则将不会执行后面的匹配规则稍稍对于URLRouting掌握不好就会给系统的安全带来隐患
权限系统一般分为稳定不变的部分较稳定的部分不稳定部分因此在进行权限系统的时候就应当综合考虑这些因素
关于权限系统的设计一般都会按照如下来设计
抽象出系统中的实体部分(系统中稳定不变的部分或系统中较稳定的部分) 将抽象的实体部分进行抽象设计(实体类)设计实体类之间的存储
分析实体类之间的关系这些是系统中不稳定的部分因此要将这些关系进行存储(存储在数据库中或配置文件中方便以后进行修改)经过如上的设计一般来说当权限管理系统达到如下要求就算是合格了
能完成基本的权限管理当需要进行权限管理的时候整个权限系统的架构不变变的仅仅是数据一个合格的权限系统的设计通常不够完美所以需要结合实际情况综合考虑进行改进至于如何改进没有统一的方法可言
关于Membership很多人都喜欢重用Membership的一些东西可是究竟能够重用的部分有多少?
ASPNET 中提供的控件如 LoginLoginViewPasswordRecoveryCreateUserWizardChangePassword等当然这些并不是Membership的部分但是这些通常都会跟Membership配合使用这些控件提供了方便的开发可是通常这些控件并不能满足要求扩展性并不好而且这些控件会生成很多垃圾代码如jscss等在带来开发方便的同时也给扩展跟维护带来不便最重要的一点凡是涉及Postback的控件在ASPNET MVC中全部不能使用
数据库及数据库访问通过执行aspnet_regsql命令可以自动在数据库中创建出张表并且提供了若干个API方法来对这张表进行操作可是这张表中的设计往往也是不符合要求的如果进行扩展的话就会比较麻烦一般扩展的方法有两种不改变原来的表但是要建一张表跟以前的表对应表中的Id跟原来表中一模一样改变原来表的设计无论是哪种方法数据库访问部分就必须得重写因此数据库及数据库访问的重用也变的非常低基于配置文件的权限控制似乎从目前上来看能重用的部分只有这个了可是在ASPNET MVC中URL是个不稳定因素基于配置文件的权限控制这个功能的重用并不适合ASPNET MVC的开发综合对比一下至少在ASPNET MVC开发中Membership所带来的重用微乎其微
在不同的权限管理系统中对控制级别的要求是不一样的如页面访问级别数据访问级别控件访问级别函数级别可是不论是要控制到那个级别权限管理系统所要完成的功能都是一样的 我们不妨给权限管理系统下一个定义权限管理系统就是告诉其它模块用户/角色对特定的资源/功能是否具有访问的权限
在Webform中用户跟角色相比角色是不稳定因素用户是相对较稳定的因素因此权限系统的输入参数中我们通常会传入用户而不输入角色因为角色是不稳定的至于说用户属于哪个角色权限系统是可以查出来的
而在ASPNET MVC中用户跟角色都可以是较稳定因素因为用户的权限控制跟角色的权限控制都是通过扩展标记属性来实现的这是跟webform相比权限系统设计上不一样的地方
ASPNET MVC中权限控制是通过对Action的拦截实现的实现的方式如下
定义一个扩展属性标记类继承自接口IActionFilter的抽象类ActionFilterAttribute重写ActionFilterAttribute中的虚方法将扩展标记作用于Controller跟Action关于ASPNET MVC中的权限管理方案网上已经有了这里就不过多的赘述了