MVC 自定义AuthorizeAttribute实现权限管理
在上一节中提到可以使用AuthorizeAttribute进行权限管理:

[Authorize]
public ActionResult TestAuthorize()
{
return View();
} [Authorize(Users="test1,test2")]
public ActionResult TestAuthorize()
{
return View();
} [Authorize(Roles="Admin")]
public ActionResult TestAuthorize()
{
return View();
}

但是通常情况下,网站的权限并不是固定不变的,当新增角色或者角色改变时,只能修改每个Action对应的特性,当项目较大时工作量可想而知。幸运的是我们可以重写AuthorizeAttribute达到自定义的权限管理。新建一个CustomAuthorizeAttribute类,使这个类继承于AuthorizeAttribute。打开AuthorizeAttribute查看下方法说明,我们只需要重写AuthorizeCore和OnAuthorization就能达到我们的目的。

// Summary:
// When overridden, provides an entry point for custom authorization checks.
//
// Parameters:
// httpContext:
// The HTTP context, which encapsulates all HTTP-specific information about
// an individual HTTP request.
//
// Returns:
// true if the user is authorized; otherwise, false.
//
// Exceptions:
// System.ArgumentNullException:
// The httpContext parameter is null.
protected virtual bool AuthorizeCore(HttpContextBase httpContext); //
// Summary:
// Called when a process requests authorization.
//
// Parameters:
// filterContext:
// The filter context, which encapsulates information for using System.Web.Mvc.AuthorizeAttribute.
//
// Exceptions:
// System.ArgumentNullException:
// The filterContext parameter is null.
public virtual void OnAuthorization(AuthorizationContext filterContext);

在CustomAuthorizeAttribute中重载AuthorizeCore方法,它的处理逻辑如下:首先判断当前账户是否被认证,如果没有,则返回false;然后获取当前账户的类型,并跟给定的类型进行比较,如果类型相同,则返回true,否则返回false。一般网站中权限管理都会使用权限树,然后将角色的权限保存至数据库或者文件中,本例中我们使用XML文件保存每个Action的角色,这样在用户请求Action时,由XML文件获取Action对应的权限,然后检测账户是否有相应的权限。CustomAuthorizeAttribute类的代码如下:

public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
public new string[] Roles { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null) {
throw new ArgumentNullException("HttpContext");
}
if (!httpContext.User.Identity.IsAuthenticated) {
return false;
}
if (Roles == null) {
return true;
}
if (Roles.Length == 0)
{
return true;
}
if (Roles.Any(httpContext.User.IsInRole))
{
return true;
}
return false;
} public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
{
string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
string actionName = filterContext.ActionDescriptor.ActionName;
string roles = GetRoles.GetActionRoles(actionName, controllerName);
if (!string.IsNullOrWhiteSpace(roles)) {
this.Roles = roles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
}
base.OnAuthorization(filterContext);
}
}

当用户请求一个Action时,会调用OnAuthorization方法,该方法中GetRoles.GetActionRoles(actionName, controllerName);根据Controller和Action去查找当前Action需要具有的角色类型,获得Action的Roles以后,在AuthorizeCore中与用户的角色进行比对Roles.Any(httpContext.User.IsInRole),如果没有相应权限则返回false,程序就会自动跳转到登录页面。
GetRoles为XML解析类,代码如下:

public class GetRoles
{ public static string GetActionRoles(string action, string controller) {
XElement rootElement = XElement.Load(HttpContext.Current.Server.MapPath("/")+"ActionRoles.xml");
XElement controllerElement = findElementByAttribute(rootElement, "Controller", controller);
if (controllerElement != null)
{
XElement actionElement = findElementByAttribute(controllerElement, "Action", action);
if (actionElement != null)
{
return actionElement.Value;
}
}
return "";
} public static XElement findElementByAttribute(XElement xElement,string tagName, string attribute)
{
return xElement.Elements(tagName).FirstOrDefault(x => x.Attribute("name").Value.Equals(attribute,StringComparison.OrdinalIgnoreCase));
}
}

相应的权限XMl文件:

<?xml version="1.0" encoding="utf-8" ?>
<Roles>
<Controller name="Home">
<Action name="Index"></Action>
<Action name="About">Manager,Admin</Action>
<Action name="Contact">Admin</Action>
</Controller>
</Roles>

当需求发生变化时,只需要修改XML文件即可
使用时,只需要在FilterConfig中注册该filter
filters.Add(new CustomAuthorizeAttribute());
当然这只是一个简单的例子,实际应用中会复杂许多,还可能要实现在即的MemberShipProvider和RoleProvider
MVC 自定义AuthorizeAttribute实现权限管理的更多相关文章
- MVC自定义AuthorizeAttribute实现权限管理
[转]MVC自定义AuthorizeAttribute实现权限管理 原文载自:小飞的DD http://www.cnblogs.com/feiDD/articles/2844447.html 网站的权 ...
- C#_MVC 自定义AuthorizeAttribute实现权限管理
随笔- 28 文章- 31 评论- 16 MVC 自定义AuthorizeAttribute实现权限管理 在上一节中提到可以使用AuthorizeAttribute进行权限管理: [Autho ...
- MVC 自定义AuthorizeAttribute 实现权限验证
MVC内置的AuthorizeFilter先于Action/Result过滤器执行,为网站权限验证提供了很好的一套验证机制. 通过自定义的AuthorizeAttribute可以实现对用户权限的验证. ...
- [转]Asp.Net大型项目实践(11)-基于MVC Action粒度的权限管理【续】【源码在这里】(在线demo,全部源码)
本文转自:http://www.cnblogs.com/legendxian/archive/2010/01/25/1655551.html 接上篇Asp.Net大型项目实践(10)-基于MVC Ac ...
- MVC身份验证及权限管理
MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供了三种方式,其中最常用的就是我们的Form认证,需要配置相应的信息.例如下面的配置信息: < ...
- MVC身份验证及权限管理(转载)
from https://www.cnblogs.com/asks/p/4372783.html MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供 ...
- (转) MVC身份验证及权限管理-2
转自:http://www.cnblogs.com/ldp615/archive/2010/10/27/asp-net-mvc-forms-authentication-roles-authoriza ...
- SQLSERVER 数据库性能的的基本 MVC + EF + Bootstrap 2 权限管理
SQLSERVER 数据库性能的基本 很久没有写文章了,在系统正式上线之前,DBA一般都要测试一下服务器的性能 比如你有很多的服务器,有些做web服务器,有些做缓存服务器,有些做文件服务器,有些做数据 ...
- SharePoint _layouts下自定义程序页面权限管理
在sharepoint中,_layouts下的自定义页面没有特别的权限,只要用户能访问sharepoint站点就可以访问_layouts下的自定义程序页面,现在我们需要给自定义页面做一下权限认证.要求 ...
随机推荐
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点[数据结构]
作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { ...
- php二维数组,按照指定的key,去排序value值
$arr = array( '11'=>array( 'a'=>1, 'b'=>2, ), '22'=>array( 'a'=>3, 'b'=>4, ), '33' ...
- remastersys修改默认选项
1.vim /etc/remastersys/isolinux/isolinux.cfg.vesamenu default vesamenu.c32prompt 0timeout 100 menu t ...
- free -m
free -m total used free shared buffers cached Mem: 7760 1572 6187 0 9 ...
- Linux C 程序 数组(EIGHT)
数组 1.一维数组的定义和使用,声明时数组默认值为0 int a[n]; 这样定义不合法,n是变量 ,数组规定[]里只能为常量 ] = {,,,,,,,,,}; a[] = {,} ;//部分赋值 , ...
- Java security MD5加密算法
利用java.security对字符串进行MD5加密: import java.security.MessageDigest; import java.security.NoSuchAlgorithm ...
- 今日吐槽20151208.net服务器控件
正文 今天有个小任务是给页面添加一个搜索条件,复选框多选.因为页面都是服务器控件,我也只能用服务器控件配合了.然后给页面加了一个 CheckBoxList 控件.后台通过数据表加载数据. fore ...
- 2015版App推广全攻略(完整版)
线上渠道 1.基础上线 各大手机厂商市场.第三方应用商店.大平台.PC下载站.手机WAP站.收录站.移动互联网应用推荐媒体等等基本可以覆盖Android版本发布渠 道:推广的第一步是要上线,这是最基础 ...
- 006.Compile方法
Delphi procedure Compile; 类型:procedure 可见性:public 所在单元:System.RegularExpressionsCore 父类:TPerlRegEx 此 ...
- 【BZOJ】1015: [JSOI2008]星球大战starwar
1015: [JSOI2008]星球大战starwar 题意:一个点数为N(1<= 40w),边数为M(1<=20w)的图,总共删除k个节点,问开始以及每次删除一个节点之后图的连通块数? ...