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下的自定义程序页面,现在我们需要给自定义页面做一下权限认证.要求 ...
随机推荐
- centos下如何用SMplayer播放WMV格式文件
安装的是centos6.6,想用来做桌面系统使用!! 装完后,其他的办公软件都安装好了.但是,视频播放却出问题了. 配置的yum安装的SMplayer播放器,播放其他的视频文件没问题,就是WMV的视频 ...
- Linux C 程序 数组(EIGHT)
数组 1.一维数组的定义和使用,声明时数组默认值为0 int a[n]; 这样定义不合法,n是变量 ,数组规定[]里只能为常量 ] = {,,,,,,,,,}; a[] = {,} ;//部分赋值 , ...
- 让hyper-v虚拟机中类ubuntu系统可以全屏
很久之前一直都没有方法让linux虚拟机支持hyper-v的全屏,只能以1024x768或者800x600等方形屏幕 如果是windows7以前的电脑,可以用mstsc远程桌面修改分辨率,window ...
- ASP.NET 学习小记 -- “迷你”MVC实现(1)
ASP.NET 由于采用了管道式设计,具有很好的扩展性.整个ASP.NET MVC应用框架就是通过扩展ASP.NET实现的.通过ASP.NET的管道设计,我们知道,ASP.NET的扩展点主要是体现在H ...
- Codeforces Round #345 (Div. 1) B. Image Preview
Vasya's telephone contains n photos. Photo number 1 is currently opened on the phone. It is allowed ...
- poj 2187 Beauty Contest
Beauty Contest 题意:给你一个数据范围在2~5e4范围内的横纵坐标在-1e4~1e4的点,问你任意两点之间的距离的最大值的平方等于多少? 一道卡壳凸包的模板题,也是第一次写计算几何的题, ...
- Hibernate各种主键生成策略2
先来看看主键映射的标签: <id (1)name="propertyName" (2)column="column_name" (3)type=& ...
- 数组有N+M个数字, 数字的范围为1 ... N, 打印重复的元素, 要求O(M + N), 不可以用额外的空间
数组有N+M个数字, 数字的范围为1 ... N, 打印重复的元素, 要求O(M + N), 不可以用额外的空间 1.题目中要求我们不能使用额外的空间,那么我们能采用在原数组上做文章,这里的重点是如何 ...
- CODEVS 1073 家族
题目描述 Description 若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系. 规定:x和y是亲戚,y和z是亲戚,那么x和 ...
- Js template engine
P http://www.jquery4u.com/javascript/10-javascript-jquery-templates-engines/ http://www.creativebloq ...