上一次在 .NET MVC 用户权限管理示例教程中讲解了ASP.NET MVC 通过AuthorizeAttribute类的OnAuthorization方法讲解了粗粒度控制权限的方法,接下来讲解基于角色的权限控制方法。

基于角色的权限控制方法概述

基于角色的权限控制系统RBAC(Role Based Access Control)是目前最流行,也是最通用的权限控制系统。所谓基于角色的权限控制,就是将各个操作权限分组,每一个组就是一个角色,举个例子:管理员拥有所有的权限,编辑就只拥有写文章和发布文章的权限,这里的“管理员”和“编辑”就是一个角色——一系列操作权限的集合。我们只需要将某个角色赋予某个用户那么这个用户就拥有这个角色下的权限集合。

现在我们要做的就是通过把Controller下的每一个Action可以看作是一个权限,然后可以通过方法将每一个权限进行自定义的分组,从而创建一个角色,然后将角色与用户对应起来。

基于角色的权限控制方法步骤

步骤一、新建一个RoleAuthorizeAttribute类

这个类可以拿到ControllerName和ActionName,这样可以根据ControllerName和ActionName判断是什么样的操作,如下面的代码

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Mvc;
using System.Web.Routing; namespace SampleMVCWebsite
{
public class RoleAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var isAuth = false;
if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
{
isAuth = false;
}
else
{
if (filterContext.RequestContext.HttpContext.User.Identity != null)
{
var roleApi = new RoleApi();
var actionDescriptor = filterContext.ActionDescriptor;
var controllerDescriptor = actionDescriptor.ControllerDescriptor;
var controller = controllerDescriptor.ControllerName;
var action = actionDescriptor.ActionName;
var ticket = (filterContext.RequestContext.HttpContext.User.Identity as FormsIdentity).Ticket;
var role = roleApi.GetById(ticket.Version);
if (role != null)
{
isAuth = role.Permissions.Any(x => x.Permission.Controller.ToLower() == controller.ToLower() && x.Permission.Action.ToLower() == action.ToLower());
}
}
}
if (!isAuth)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "account", action = "login", returnUrl = filterContext.HttpContext.Request.Url, returnMessage = "您无权查看." }));
return;
}
else
{
base.OnAuthorization(filterContext);
}
}
}
}

其中RoleApi是角色对象管理的API,这里需要自己设置角色管理。上面的代码中通过FilterContext的ActionDescriptor对象的ControllerDescriptor就可以获取到ControllerName和ActionName。获取到当前用户的角色后,通过查看用户的权限中是否包含了当前访问的Controller中的方法,就能实现权限验证。这里主要使用了ActionDescriptor和ControllerDescriptor,关于这两个类的介绍可以参考MSDN官网。

PS:这里用Ticket的Version存储RoleId。你也可以用其他方式。关于Ticket的知识可以参考微软MSDN官方文档,这里不再敖述。

步骤二、创建DescriptionAttribute类

这个类是继承Attribute,为的是给Action方法打上描述标签,如下面的代码

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace SampleMVCWebsite
{
/// <summary>
/// Description Attribute
/// </summary>
public class DescriptionAttribute:Attribute
{
public string Name
{
set;
get;
}
public int No
{
set;
get;
}
}
}

Name和NO和Permission类中是ControllerName、ActionName和ControllerNo、ActionNO是对应的。

步骤三、给Controllers打上DescriptionAttribute标签

使用步骤二创建的DescriptionAttribute标签给Controller标上,以便存储Permission的时候获取信息。如下面的代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace SampleMVCWebsite.Controllers
{
[Description(No = , Name = "用户")]
public class UserController : Controller
{
[RoleAuthorize]
[Description(No = , Name = "用户首页")]
public ActionResult Index()
{
return View();
}
[RoleAuthorize]
[Description(No = , Name = "用户管理员")]
public ActionResult Manage()
{
return View();
}
[RoleAuthorize]
[Description(No = , Name = "用户详情")]
public ActionResult Detail()
{
return View();
}
}
}

步骤四、生成权限控制列表

步骤一种有一个role.Permissions,这个Permissions就是当前用户所拥有的权限集合,在实际的项目开发中是把它存储在数据库关系表中的,我们可以将Permissions类如下面的代码这样定义

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace SampleMVCWebsite
{
public class Permission
{
/// <summary>
/// Permission Id
/// </summary>
public virtual int Id
{
set;
get;
}
/// <summary>
/// Permission Action No
/// </summary>
public virtual int ActionNo
{
set;
get;
} /// <summary>
/// Controller No
/// </summary>
public virtual int ControllerNo
{
set;
get;
} /// <summary>
/// Controller Name
/// </summary>
public virtual string ControllerName
{
set;
get;
} /// <summary>
/// Permission Action Name
/// </summary>
public virtual string ActionName
{
set;
get;
} /// <summary>
/// Controller
/// </summary>
public virtual string Controller
{
set;
get;
} /// <summary>
/// Action
/// </summary>
public virtual string Action
{
set;
get;
}
}
}

属性Controller和Action记录的是权限,ControllerName和ActionName用于显示UI,ControllerNo和ActionNo用于显示顺序控制。其余根据上面的代码注释应该很好理解,这里就不一一陈述了。

因此你需要将Action输入数据库中来实现RoleApi。手动输入如果方法少还好,但是多了就比较麻烦,这样我们可以使用.NET的反射机制来进行权限的创建。先看下面的代码:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SampleMVCWebsite.Controllers; namespace SampleMVCWebsite
{
public class InstallController
{
public class InstallController : Controller
{
public ActionResult Index()
{
return View();
} [HttpPost]
public ActionResult Index()
{
try
{
var roleService = new RoleApi();
#region init permission
CreatePermission(new UserController());
#endregion var allDefinedPermissions = roleService.GetDefinedPermissions(); #region 管理员角色初始化
var adminPermissions = new List<RolePermissionInfo>();
foreach (var d in allDefinedPermissions)
{
adminPermissions.Add(new RolePermissionInfo {Permission = d, });
}
int adminRoleId = roleService.AddRole(new RoleInfo
{
Name = "管理员",
Description = "",
Permissions = adminPermissions,
AddDate = DateTime.Now,
});
#endregion
return RedirectToAction("Admin", "Index");
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.Message);
return View();
}
}
private void CreatePermission(Controller customController)
{
var roleApi = new RoleApi(); var controllerName = "";
var controller = ""; var controllerNo = ;
var actionName = ""; var action = ""; var actionNo = ;
var controllerDesc = new KeyValuePair<string, int>(); var controllerType = customController.GetType(); //remove controller posfix
controller = controllerType.Name.Replace("Controller", "");
controllerDesc = Getdesc(controllerType);
if (!string.IsNullOrEmpty(controllerDesc.Key))
{
controllerName = controllerDesc.Key;
controllerNo = controllerDesc.Value;
foreach (var m in controllerType.GetMethods())
{
var mDesc = GetPropertyDesc(m);
if (string.IsNullOrEmpty(mDesc.Key)) continue;
action = m.Name;
actionName = mDesc.Key;
actionNo = mDesc.Value;
roleApi.CreatePermissions(actionNo, controllerNo, actionName, controllerName, controller, action);
}
}
}
private KeyValuePair<string, int> Getdesc(Type type)
{
var descriptionAttribute = (DescriptionAttribute)(type.GetCustomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute));
if (descriptionAttribute == null) return new KeyValuePair<string, int>();
return new KeyValuePair<string, int>(descriptionAttribute.Name, descriptionAttribute.No);
}
private KeyValuePair<string, int> GetPropertyDesc(System.Reflection.MethodInfo type)
{
var descriptionAttribute = (DescriptionAttribute)(type.GetCustomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute));
if (descriptionAttribute == null) return new KeyValuePair<string, int>();
return new KeyValuePair<string, int>(descriptionAttribute.Name, descriptionAttribute.No);
}
}
}
}
上面的代码首先通过Getdesc来获取Controller的描述,GetPropertyDesc
方法获取方法的描述,这里的方法就是一个独立的权限,然后通过roleApi的CreatePermissions方法将权限的数据写入到数据库中,将数据写入数据库的代码就需要根据自己的数据库读写方法去实现了,强烈建议使用Linq对数据库进行读写。然后再通过roleApi获取到所有的权限并且将所有的权限绑定到Admin角色,保存对应关系。这样我们就完成了权限控制列表生成并且初始化了管理员用户。

通过上面的示例就可以完成ASP.NET MVC 基于角色的权限控制系统,上面的代码中的roleApi需要自己写代码实现对数据库的操作,数据模型就是权限、角色、用户的数据表以及权限月角色以及角色与用户的关系表。

ASP.NET MVC 基于角色的权限控制系统的示例教程的更多相关文章

  1. ASP.net MVC 基于角色的权限控制系统的实现

    一.引言 我们都知道ASP.net mvc权限控制都是实现AuthorizeAttribute类的OnAuthorization方法. 下面是最常见的实现方式: public class Custom ...

  2. 基于角色的权限控制系统(role-based access control)

    role-based access control(rbac),指对于不同角色的用户,拥有不同的权限 .用户对应一个角色,一个角色拥有若干权限,形成用户-角色-权限的关系,如下图所示.当一个用户进行访 ...

  3. ASP.NET MVC 基于页面的权限管理

    菜单表 namespace AspNetMvcAuthDemo1.Models { public class PermissionItem { public int ID { set; get; } ...

  4. MVC基于角色权限控制--数据库设计

    在网站后台设计过程中都会遇上权限控制这一问题 当前较为流行的解决方案是基于角色的权限管理 基本思路如下 分别建立 用户信息表.角色信息表.权限信息表 让用户和角色关联,角色和权限关联,当用户访问时,通 ...

  5. Asp.net core IdentityServer4与传统基于角色的权限系统的集成

    写在前面 因为最近在忙别的,好久没水文了 今天来水一篇: 在学习或者做权限系统技术选型的过程中,经常有朋友有这样的疑问 : "IdentityServer4的能不能做到与传统基于角色的权限系 ...

  6. FineAdmin.Mvc 使用ok-admin+ASP.NET MVC搭建的通用权限后台管理系统

    FineAdmin.Mvc 介绍 使用ok-admin+ASP.NET MVC搭建的通用权限后台管理系统RightControl后台layui模板不太好看,换成ok-admin v2.0重写一遍.项目 ...

  7. ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上

    原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...

  8. ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则

    原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...

  9. C 实现基于角色的权限系统

    本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1068 实例使用C# 实现基于角色的权限 ...

随机推荐

  1. MVC中Html.Listbox的用法实例

    要绑定listbox或dropdownlist前提是:必须是SelectItem类,例如: 因为Html.ListBox第二个绑定数据的参数要得类型为SelectList第一种:因为listbox可以 ...

  2. thinkphp分页效果的制作,按查询条件分页正确做法

    PHP代码: <?php namespace Home\Controller; use Think\Controller; use Home\Clas\Cate; class IndexCont ...

  3. 算法_栈的Java的通用数组实现

    栈是一个常用的最简单的数据结构,这里提供了其实现.内部维护了一个数组,并且可以动态的调整数组的大小.而且,提供了迭代器支持后进先出的迭代功能.Stack的实现是所有集合类抽象数据类型实现的模板,它将所 ...

  4. Hadoop与Spark比较

    先看这篇文章:http://www.huochai.mobi/p/d/3967708/?share_tid=86bc0ba46c64&fmid=0 直接比较Hadoop和Spark有难度,因为 ...

  5. ViewPager 基本方式加载view

    1.新建view_pager.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayo ...

  6. a链接onclick="window.location.href=在ie6上面无法执行解决

    <a href="javascript:void(0)" onclick="window.location.href=document.getElementById ...

  7. 【linux命令】:查看系统运行状态,命令top 【转载】

    原文:http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316399.html 简介 top命令是Linux下常用的性能分析工具,能够实时显示系 ...

  8. hiho_1138_island_travel

    题目 二维平面上有n个点,每个点的横纵坐标均为非负整数.两个点之间的距离记为 min(abs(x1 - x2), abs(y1 - y2)),求从点1到达点n的最短路径长度. 比较容易想到使用最短路径 ...

  9. java 集合(Collection 和 Array)

    Collection(是一个单列集合的根接口) Collections(操作集合对象的一个工具类)只要了解部分常用的方法就好

  10. VirtualBox相关问题总结

    欢迎关注我的社交账号: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://gith ...