ASP.NET MVC 基于角色的权限控制系统的示例教程
上一次在 .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 基于角色的权限控制系统的示例教程的更多相关文章
- ASP.net MVC 基于角色的权限控制系统的实现
一.引言 我们都知道ASP.net mvc权限控制都是实现AuthorizeAttribute类的OnAuthorization方法. 下面是最常见的实现方式: public class Custom ...
- 基于角色的权限控制系统(role-based access control)
role-based access control(rbac),指对于不同角色的用户,拥有不同的权限 .用户对应一个角色,一个角色拥有若干权限,形成用户-角色-权限的关系,如下图所示.当一个用户进行访 ...
- ASP.NET MVC 基于页面的权限管理
菜单表 namespace AspNetMvcAuthDemo1.Models { public class PermissionItem { public int ID { set; get; } ...
- MVC基于角色权限控制--数据库设计
在网站后台设计过程中都会遇上权限控制这一问题 当前较为流行的解决方案是基于角色的权限管理 基本思路如下 分别建立 用户信息表.角色信息表.权限信息表 让用户和角色关联,角色和权限关联,当用户访问时,通 ...
- Asp.net core IdentityServer4与传统基于角色的权限系统的集成
写在前面 因为最近在忙别的,好久没水文了 今天来水一篇: 在学习或者做权限系统技术选型的过程中,经常有朋友有这样的疑问 : "IdentityServer4的能不能做到与传统基于角色的权限系 ...
- FineAdmin.Mvc 使用ok-admin+ASP.NET MVC搭建的通用权限后台管理系统
FineAdmin.Mvc 介绍 使用ok-admin+ASP.NET MVC搭建的通用权限后台管理系统RightControl后台layui模板不太好看,换成ok-admin v2.0重写一遍.项目 ...
- ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...
- ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则
原文:ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则 对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象, ...
- C 实现基于角色的权限系统
本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1068 实例使用C# 实现基于角色的权限 ...
随机推荐
- mysql 选择性高
选择性高是指能够过滤掉更多不需要的记录.举例来说,在一个公司里,使用性别只能过滤掉一半的人,而使用姓名一般可以过滤掉99%以上的人,因为会有重名情况,而使用员工号,选出一个,其他的全部过滤掉.也就是说 ...
- Data truncated for column xxx
对于字段XXX,数据发生截断.原因是:字段的取值,不满足约束条件.比如下面的情况: 原来的字段取值为null,现在约束字段not null,就会报错Data truncated for column ...
- 【Todo】【读书笔记】大数据Spark企业级实战版 & Scala学习
下了这本<大数据Spark企业级实战版>, 另外还有一本<Spark大数据处理:技术.应用与性能优化(全)> 先看前一篇. 根据书里的前言里面,对于阅读顺序的建议.先看最后的S ...
- django在pyhton2.7 和 python3.* 之间代码和睦相处的方法
“祥”龙第一掌: from __future__ import unicode_literals from django.utils.encoding import python_2_unicode_ ...
- POJ水题 1298
#include "stdafx.h" #include <iostream> #include <string> using namespace std; ...
- phalcon: 表单
以实例为说明: controller <?php use \Phalcon\Forms\Form; use \Phalcon\Forms\Element\Text; use \Phalcon\F ...
- Android Toolbar样式定制详解
前言 Marterial Design出来也有一段时间了,为了紧跟Google的设计规范,决定在项目中使用Toolbar.使用了一段时间之后,发现很多时候原始的Toolbar并不能满足项目的要求.为了 ...
- ASP.NET Core文档中Work with Data章节的翻译目录
作为初学者看了相关的教程,遇到的问题有: 1. 教程不是针对初学者,往往在某一方面教的较深,但并不系统,不适合初学者: 2. 虽然翻译的很顺畅,但是谈了自己较多的开发体会,初学者看着困难,尤其是TOM ...
- 谈谈HttpUrlConnection与DefaultHttpClient一些区别
HttpClient封装的很庞大,很复杂,你必须按照,他封装的思想去使用它,导致它很不灵活. 相比之下,HttpUrlConnection很轻巧,很方便,很灵活. HttpClient对于数据上面的封 ...
- PHP 启动 cURL模块以及启动失败的解决方案
配置方法: php_curl.dll libeay32.dll ssleay32.dll php5ts.dll 复制到 %windir%/system32 以及php 目录的ext目录 下 并且找到p ...