技术开发 频道

Asp.Net大型项目实践:如何进行权限判断

  【IT168 技术文档】权限管理是个老生常谈的功能,我看博客园也有不少“高手”写了相关的文章,但大多不是空谈理论,就是做的十分傻瓜和玩具差不多没有真正项目实用性。少数基于RBAC的看设计还可以,但犹抱琵琶半遮面的,谈到关键实现就阳痿,生怕别人学到似的。

  第一篇:如何实践Asp.Net大型项目的开发
  第二篇:Asp.Net大型项目实践:基于MVC权限管理

  在线Demo:

  地址:http://218.60.8.35:1234/

  服务器:网通

  端口:不要禁用1234端口应该就可以访问

  注意:连了数据库的,时间仓促肯定有漏洞,不要捣乱哈:)

  登录用户: 1.用户名:牛头人战士 密码:000000 权限:有全部菜单页面,不能进行数据库的更改操作(不影响录入体验)

  2.用户名:老虎MM 密码:000000 权限:少两个菜单页面,不能进行数据库的更改操作(不影响录入体验)

  3.用户名:admin 密码不公开 权限:所有权限

  注:以上的实现都是通过权限管理s配置出的哈,没有任何硬编码

  1.权限判断的边界

  由于项目是基于MVC的,除去数据权限不说,功能权限的判断边界做在MVC 的Action上无疑是最好的选择,因为无论是一个页面,还是一个按钮,还是一次查询,都是通过Action请求实现的。这样我们只需要在每个Action请求执行之前进行权限判断就可以了,也不用折腾RBAC里的资源+操作=权限 这么麻烦。

  2.菜单权限和功能权限

  其实在MIS项目中,大多数的权限判断粒度还是页面级的,再加上我们还需要根据权限动态生成用户的菜单,所以我们把权限分成“菜单权限”和“功能权限”

  菜单权限:在用户登录验证后,每个页面的请求都必须通过权限验证。

  功能权限:默认客户进入页面后,页面的相关操作默认都不判断,只对显示维护出的功能权限进行权限判断。

  这样有几个好处:一般情况下权限的配置简单了,因为只需要配置粗粒度的页面权限即可使用;增加了效率,不必每个Action执行之前都判断权限(虽然都做了缓存,但能少判断一次还是好的);完全不影响细粒度的权限判断,随时都可以增加对任何一个Action的权限判定

  3.如何取Action功能权限

  我们通过反射把所有的Action权限全部取出来,这样在维护选取的时候就比较方便了,也不会产生录入错误,如下图:

  大家用Demo可以体验到我们模糊输入Action名称就可以找到我们想要的Action的,因为是配置选取用也不用担心什么反射的效率问题,其实大家从demo可以看到速度还是挺快的,在我真实的项目中Action中有上万个,拉出来一样是瞬时的,所以我觉得有时候吧,也别过于“谈反射色变”,呵呵

  通过反射获取所有Action的代码如下:

public IList<ActionPermission> GetAllActionByAssembly()        
{            
var result
= new List<ActionPermission>();            
var types
= Assembly.Load("Demo.HIS.MVC").GetTypes();            
foreach (var type in types)            
{                
if (type.BaseType.Name == "BaseController")//如果是Controller                
{                    
var members
= type.GetMethods();                    
foreach (var member in members)                    
{                        
if (member.ReturnType.Name == "ActionResult")//如果是Action                        
{                            
var ap
= new ActionPermission();                            
ap.ActionName
= member.Name;                            
ap.ControllerName
= member.DeclaringType.Name.Substring(0, member.DeclaringType.Name.Length - 10); // 去掉“Controller”后缀                            
object[] attrs = member.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true);                            
if (attrs.Length > 0)                                
ap.Description
= (attrs[0] as System.ComponentModel.DescriptionAttribute).Description;
result.Add(ap);                        
}                    
}                
}            
}            
return result;        
}
0
相关文章