常见的Controller定义方式:

public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}

如果对Action的操作需要权限管理的话,需要在Controller或者Action上面添加AuthorizeAttribute属性或者AllowAnonymousAttribute属性。

AllowAnonymousAttribute的意思很明确,允许匿名访问。

AuthorizeAttribute类型有几个属性:Roles,Users,TypeId。

当用户请求一个Action时,会调用OnAuthorization方法。那么,我们来看看这个方法里面的代码是什么:

public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
} if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
{
throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache);
} bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true); if (skipAuthorization)
{
return;
} if (AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan());
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else
{
HandleUnauthorizedRequest(filterContext);
}
}

中间有一段是判断Action或者Controller是否被属性AllowAnonymousAttribute描述,如果有,则返回。也就是说,无论Action或者是Controller哪一个上面被定义了[AllowAnonymous]属性,那么,这个Action就会跳过验证。

如果没有的话,会判断函数AuthorizeCore(filterContext.HttpContext)执行的结果是否为true,这样,我们进一步看函数AuthorizeCore里面的代码:

protected virtual bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
} IPrincipal user = httpContext.User;
if (!user.Identity.IsAuthenticated)
{
return false;
} if (_usersSplit.Length > && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
} if (_rolesSplit.Length > && !_rolesSplit.Any(user.IsInRole))
{
return false;
} return true;
}

逻辑比较清晰,如果用户没有登录,返回false;如果授权用户组长度大于0,但同时不包含当前用户,返回false;如果授权角色组长度大于0,但同时不包含当前用户所在的任何角色,返回false;符合前面所有的条件,则返回true。

到此,授权验证的上下逻辑算是比较明了。

问题

实际操作中出现了疑惑:

如果在Controller那里定义了角色为"Users,Admin"的授权,而在Action处定义其他角色的Authorize,会怎么样呢?

测试思路,自定义一个CustomAuthorize,override上述两个函数(这两个函数都是virtual的),代码复制微软的源码,加断点调试。(重写的代码就不展示了。大部分复制,小部分微调下。),控制器代码如下:

[CustomAuthorize(Roles="Users,Admin")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
} [CustomAuthorize(Roles = "AAAAA")]
public ActionResult About()
{
ViewBag.Message = "Your application description page."; return View();
}
}

调试模式启动Home下面的About页面,在OnAuthorization里面加断点,可以看到如下数据:
1. 在filterContext.ActionDescriptor和filterContext.ActionDescriptor.ControllerDescriptor里面可以看到各自的Roles内容
2. base.Roles的值为"Users,Admin"。

由此,我们可以得出:

当Controller和Action都出现了角色授权时,多个授权不是合并,也不是取Action上面的,而是直接取Controller上面定义的角色,继而判断当前用户是否有授权。

Users是不是也是这样的,有兴趣的童鞋可以自己调试看看o(∩_∩)o ~

MVC源码学习之AuthorizeAttribute的更多相关文章

  1. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  2. MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

    前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...

  3. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  4. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...

  5. [转]MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    本文转自:http://www.cnblogs.com/landeanfen/p/5989092.html 阅读目录 一.MVC原理解析 1.MVC原理 二.HttpHandler 1.HttpHan ...

  6. ASP.NET Core MVC 源码学习:MVC 启动流程详解

    前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...

  7. ASP.NET Core MVC 源码学习:Routing 路由

    前言 最近打算抽时间看一下 ASP.NET Core MVC 的源码,特此把自己学习到的内容记录下来,也算是做个笔记吧. 路由作为 MVC 的基本部分,所以在学习 MVC 的其他源码之前还是先学习一下 ...

  8. ASP.NET Core MVC 源码学习:详解 Action 的激活

    前言 在 上一篇 文章中,我们已经学习了 ASP.NET Core MVC 的启动流程,那么 MVC 在启动了之后,当请求到达过来的时候,它是怎么样处理的呢? 又是怎么样把我们的请求准确的传达到我们的 ...

  9. ASP.NET Core MVC 源码学习:详解 Action 的匹配

    前言 在 上一篇 文章中,我们已经学习了 ASP.NET Core MVC 的启动流程,那么 MVC 在启动了之后,当请求到达过来的时候,它是怎么样处理的呢? 又是怎么样把我们的请求准确的传达到我们的 ...

随机推荐

  1. Java Date and Calendar examples

    Java Date and Calendar examples This tutorial shows you how to work with java.util.Date and java.uti ...

  2. Python 爬虫 大量数据清洗 ---- sql语句优化

    . 问题描述 在做爬虫的时候,数据量很大,大约有五百百万条数据,假设有个字段是conmany_name(拍卖公司名称),我们现在需要从五百万条数据里面查找出来五十家拍卖公司, 并且要求字段 time( ...

  3. git 放弃本地修改(转)

    如果在修改时发现修改错误,而要放弃本地修改时, 一, 未使用 git add 缓存代码时. 可以使用 git checkout -- filepathname (比如: git checkout -- ...

  4. JS两日期相减

    JS两日期相减,主要用到下面两个方法 dateObject.setFullYear(year,month,day) 方法 stringObject.split(separator) 方法 functi ...

  5. Install OpenCV3.0 on Eclipse

     Neste artigo veremos como usar o OpenCV com Eclipse. Usaremos as versões mais recentes:OpenCV 3.0 ...

  6. 使用MySQL Proxy和MySQL Replication实现读写分离

    MySQL Replication可以将master的数据复制分布到多个slave上,然后可以利用slave来分担master的读压力.那么对于前台应用来说,就要考虑如何将读的压力分布到多个slave ...

  7. tomcat启动窗口中的时间与系统时间不一致

    比我的系统时间慢8个小时,应该如何设置? 产生原因是因为Tomcat中的时区设置与操作系统的时区设置不一致,通过修改Tomcat根目录下的bin文件夹中的catalina.bat文件,增加以下配置解决 ...

  8. Atitit 快速开发的推荐技术标准化 规范 大原则

    Atitit 快速开发的推荐技术标准化 规范 大原则 1. 如何评估什么样的技术适合快速开发??1 1.1. (重要)判断语言层次..层次越高开发效率越高  4gl  dsl> 3.5gl &g ...

  9. flexb布局图解

  10. 浅谈hibernate的sessionFactory和session

    一.hibernate是什么? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hiber ...