asp.net MVC 权限设计
几点说明:
1、该权限系统是个网站用的,用户简单,因此不涉及到部门这些信息
2、基于将角色与controller、action相关联来判断用户是否有权
3、通过重载AuthorizeAttribute实现
数据库设计:
表说明
ControllerAction
- Name是controller的名称
- IsController是指是否是controller,如果为false,表示存的是action,那么controllerName字段就派上用场了
- IsAllowedNoneRoles是指是否允许没有权限的人访问
- IsAllowedAllRoles是指是否允许有角色的人访问
IsAllowedNoneRoles,IsAllowedAllRoles实现了允许所有人访问以及允许所有注册用户访问:),并且我们约定,IsAllowedNoneRoles具有最高的优先级,其次是IsAllowedAllRoles,然后才是ControllerActionRole中定义的规则
ControllerActionRole
IsAllowed表示该action或者controller是否允许访问,加入表中有两条记录
角色 Name ControllName IsAllowed IsController A Admin Home false false A Home Null true true 这里约定分两个层次来判断权限:
第一条记录:表示A角色不能访问 Home/admin
第二条记录:表示A角色可以访问Controller下的所有方法
到底能不能访问呢?其实,我们以action为准,如果定义了action,我们直接从action的约定来判断,因此这里判断A不能访问Home/admin
其他几张表一看就明白,不再多说
判断是否有权限的设定
1、获取controller,action,以及存放在session中的用户信息
2 {
3
4 publicoverridevoid OnAuthorization(AuthorizationContext filterContext)
5 {
6 var user = filterContext.HttpContext.Session["CurrentUser"] as User;
7 var controller = filterContext.RouteData.Values["controller"].ToString();
8 var action = filterContext.RouteData.Values["action"].ToString();
9 var isAllowed =this.IsAllowed(user, controller, action);
10
11 if (!isAllowed)
12 {
13 filterContext.RequestContext.HttpContext.Response.Write("无权访问");
14 filterContext.RequestContext.HttpContext.Response.End();
15 }
16
17 }
18
19 ……
20
21 }
22
2、检索数据库ControllerAction表中有没有Name为第一步中controller 的记录,如果没有,我们约定这个controller是不需要进行权限控制的,如果有的话,进入第三步
3、前面提到了,我们约定对权限的控制分为两个层次,controller和action层次,如果同时定义了,以action为准。因此,我们需要判断是否在数据库中有action的记录,如果有,进入4,无,进入5
2 {
3 var service = ServiceLoader.LoadService<ToySpirit.IToySpiritService.IControllerActionService>();
4
5 // 获取对应的controller
6 var controller = service.GetSingleByExpression(c => c.Name == controllerName && c.IsController);
7 if (controller !=null)
8 {
9 // 获取对应的action
10 var controllerAction = service.GetSingleByFunc(c => c.Name == actionName && c.IsController ==false&& c.ControllerName == controllerName);
11
12 return controllerAction ==null?this.isAllowed(user, controller) : this.isAllowed(user, controllerAction);
13 }
14
15 // 没有定义controller的权限,表示无需权限控制
16 returntrue;
17 }
18
19
4、如果有action的记录,那么我们首先判断controllerAction 拒绝哪些角色访问,如果用户有角色在这里面,很遗憾,就不能访问了;然后判断controllerAction 允许哪些角色访问,如果用户的角色在这里面,就可以访问了
注:这里很有可能用户有多个角色,比如A,B,C,如果A不能访问controllerAction,那么很遗憾,用户不能访问,尽管角色B,C可能可以访问该controllerAction
5、没有action的记录,自然就检查controller对应的controllerAction 了
privatebool isAllowed(User user, ControllerAction controllerAction)
{
// 允许没有角色的:也就是说允许所有人,包括没有登录的用户
if (controllerAction.IsAllowedNoneRoles)
{
returntrue;
}
// 允许所有角色:只要有角色,就可以访问
if (controllerAction.IsAllowedAllRoles)
{
return user.Roles.Count >0;
}
if (user ==null|| user.Roles.Count ==0)
{
returnfalse;
}
// 选出action对应的角色
var roles = controllerAction.ControllerActionRoles.Select(ca => ca.Role).ToList();
if (roles.Count ==0)
{
// 角色数量为0,也就是说没有定义访问规则,默认允许访问
returntrue;
}
var userHavedRolesids = user.Roles.Select(r => r.ID).ToList();
// 查找禁止的角色
var notAllowedRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed ==false).Select(ca => ca.Role).ToList();
if (notAllowedRoles.Count >0)
{
foreach (Role role in notAllowedRoles)
{
// 用户的角色在禁止访问列表中,不允许访问
if (userHavedRolesids.Contains(role.ID))
{
returnfalse;
}
}
}
// 查找允许访问的角色列表
var allowRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed).Select(ca => ca.Role).ToList();
if (allowRoles.Count >0)
{
foreach (Role role in allowRoles)
{
// 用户的角色在访问的角色列表
if (userHavedRolesids.Contains(role.ID))
{
returntrue;
}
}
}
returnfalse;
}
使用方法:
建立一个basecontroller,使用我们定义好的UserAuthorize,然后所有的controller继承basecontroller就可以了
2 /// 控制基类
3 ///</summary>
4 [UserAuthorize]
5 publicabstractclass BaseController : Controller
6 {}
7
8 publicclass HomeController : BaseController{}
9
演示:
在controlleraction中添加几条数据:
根据我们的规则,我们可以知道,未登录的用户可以访问Home/Public,其他几个页面则不能访问
我们看对应的Action:
2 {
3 Response.Write("View");
4 }
5 publicvoid Public()
6 {
7 Response.Write("Public");
8 }
9 publicvoid Delete()
10 {
11 Response.Write("Delete");
12 }
访问Home/Public,如果有权限,那么显示“Public“,否则显示”无权访问”
未登录用户访问Home/Public,结果符合我们的约定;-)
未登录用户访问Home/ViewPage,按约定应该显示错误信息
查看 asp.net MVC 权限设计(续)
asp.net MVC 权限设计相关推荐
- asp.net MVC 权限设计(续)
asp.net MVC 权限设计一文中没有demo放出来,应大家的要求,这里补充上文并放出demo. 几点说明: 1.基于将角色与controller.action相关联来判断用户是否有权 2.通过自 ...
- Asp.net MVC权限设计思考 (一)数据库建库部分
目前各类的权限设计已经困扰了我们好久,对于MVC,下面我将通过ActionFilter来扩展我们的权限认证,以下示例是从我的一个课程中心项目中提取出来,希望对各位初学者起到抛砖引玉的作用. 下面首先来 ...
- 自定义AuthorizeAttribute实现MVC权限设计
文本为您介绍:自定义AuthorizeAttribute实现MVC权限设计,主要是通过将角色与controller.action等参数关联进行用户权限判断,然后通过自定义AuthorizeAttrib ...
- 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】
关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 [持续更新] 参考文章: (1)关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 [持续更新] (2)https://www. ...
- asp.net mvc 权限过滤和单点登录(禁止重复登录)
1.权限控制使用controller和 action来实现,权限方式有很多种,最近开发项目使用控制控制器方式实现代码如下 /// <summary>/// 用户权限控制/// </s ...
- 【转】ASP.NET MVC实现权限控制
这篇分享一下 ASP.NET MVC权限控制.也就是说某一用户登录之后,某一个用户是否有权限访问Controller,Action(操作),视图等 想实现这些功能,需要在数据库创建好几个表:[User ...
- Asp.net MVC 多语言问题的解决方案
上篇文章我们就Asp.net MVC权限问题做了一个较为全面的解决方案,这篇我们就多语言问题进行探讨. 全球化 在IT行业,具有全球化和本地化特性的计算机软件,可以适应不同的语言,地区差异和目标市场的 ...
- 使用asp.net mvc开发应用程序,页面中的page.IsPostback还有用处吗?
本来我对asp.net mvc也研究了一段时间了,我也使用了asp.net mvc开发了两套应用程序,虽然都不是什么大的系统. 今天也想特别提出一个疑问,不知道是我不知道呢,还是本身很难实现在asp. ...
- Pro ASP.NET MVC 3 Framework 译文(一)
ASP.NET MVC3简介 2011年10月22日 12:49 对于使用微软平台的开发人员来说,ASP.NET MVC框架有了一个根本的转变.它强调"干净的"体系.设计模式.可测 ...
最新文章
- IO流(文本文件读取练习)
- 用ajax控件作的高级搜索
- 互联网亿级日志实时分析平台,一个码农半小时就可以搞定,只因ELK
- R语言XML格式数据导入与处理
- 机器学习理论与实战(十五)概率图模型03
- 这不是商业互吹,是学习的宝藏
- 子类怎么继承父类方法中的变量_关于继承的那些事!
- 集结六大行业领袖,「数据科学家」新课全球首发!
- Axure动态面板设置 2020-11-06
- java pdf tiff_关于java:使用iText将tiff文件转换为pdf文件时出现异常
- 移动硬盘打开文件突然变得很卡
- 超简洁又强大的幻灯片JS、CSS代码,兼容性强
- 【Tableau server 8.0】Tableau server 考试真题回顾总结
- 迪文屏CRC16校验
- Linux的开源操作系统
- C/C++编程学习:百行代码实现小游戏(剪刀石头布)
- JRebel LS client not configured解决方案
- druid安装与案例
- APK获取包名的办法
- 重磅!中国商业联合会专家委员会商贸物流与供应链智库成立在即