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下的自定义程序页面,现在我们需要给自定义页面做一下权限认证.要求 ...
随机推荐
- Java Web开发中的名词解释
1.JVM Java虚拟机,class文件的运行时环境,就好比软件运行在操作系统一样,java要运行在JVM中才行,这也是Java之所以支持扩平台的基础. 2.Servlet/JSP 是满足一定接口需 ...
- 【仿携程JQuery日期价格表】
今天比较闲所以就花点时间又写了点东西. 相信这种价格表大家不会陌生 现在我就模仿它做一个简单版本的.效果如下 首先需要两个时间控件,我这里用的是HTML5里面的时间控件,这个没限制喜欢用什么就用什么 ...
- centos 7.0 mono&Jexus V5.5.3安装
首先我们需要先配置一下yum源中mono的引用说明: 第一步: vi /etc/yum.repos.d/mono.repo 第二步:在刚打开的文件中编辑如下内容 [mono]name=monobase ...
- 如何使用ERStudio 生成comment
在ER使用中,在生成sql过程中,如何批量生成字段描述,如何批量添加Owner,请看下文: 1.ER生成字段描述 2.ER生成描述添加Owner 使用的ER版本是8.0,英文版本,在操作过程中,有些配 ...
- Bios里,把SATA Mode Selection改为AHCI无法启动
新装系统Win7_X64,将SATA Mode Selection改为AHCI后总是重启,baidu参考: SATA的硬盘就选AHCI(全称应该是SATA AHCI),AHCI可以提升硬盘的读写速度原 ...
- 【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线 ...
- Vijos P1062 迎春舞会之交谊舞
题目链接:https://vijos.org/p/1062 题意:输入n(n <= 1500)个女生左边有多少个男生.每个女生都和她左边最近的男生跳舞. 输出每个女生到可以与之跳舞的男生之间有几 ...
- 2016030206 - mysql常用命令
参考地址如下: http://www.cnblogs.com/linjiqin/archive/2013/03/01/2939384.html http://www.cnblogs.com/zhang ...
- We7——很有意思的一个开源CMS
目前做门户.做网站,基本上都需要用到一个系统,那就是CMS内容管理系统:现在开源产品有很多,笔者也是从事这个行业的,国内的各大CMS提供商基本上都试用过,今天向大家推荐一款很有意思的产品——We7CM ...
- java枚举类型enum的使用
2015-10-24 java达人 Java 中 的枚举类型采用关键字enum 来定义,从jdk1.5才有的新类型,所有的枚举类型都是继承自Enum 类型.要了解枚举类型,建议大家先打开jdk 中的E ...