深入了解 Authorize 和 AllowAnonymous
Chapter 0 - Intro
最近做的一个项目的时候,自定义授权 Attribute 来区分用户权限,我的项目不太大,权限控制也不是很复杂,只涉及到匿名、普通用户、超级管理员。 权限验证方式使用的是默认的 MemberShip 认证结合自己自定义的 权限验证 Filter。
Chapter 1 - 自定义 Filter V1.0
Filter代码 V1.0
1 /// <summary> 2 /// 不需要登录即可访问 3 </summary> 4 public class nopermissionrequiredAttribute : ActionFilterattribute 5 { 6 override void OnActionExecuting(ActionExecutingContext filterContext) 7 { 8 base.OnActionExecuting(filterContext); 9 } 10 } 11 12 13 需要登录才能进行操作 14 15 PermissionrequiredAttribute : ActionFilterattribute 16 17 18 19 if (filterContext.HttpContext.Session["User"]==null) 20 { 21 filterContext.Result = new RedirectResult(~/Admin/Account/Login"); 22 } 23 24 25 26 27 28 需要有超级管理员权限 29 30 AdminPermissionrequiredAttribute : ActionFilterattribute 31 32 33 34 if ((filterContext.HttpContext.Session["] == null) || !((filterContext.HttpContext.Session["] as Models.User).IsSuper)) 35 36 filterContext.Result = 37 38 39 40 }
Chapter 2 - 控制器引用 Filter
1 [Authorize] 2 [Filters.Permissionrequired] 3 AccountController : BaseAdminController 5 6 登录页面 7 8 <returns></returns> [AllowAnonymous] [Filters.nopermissionrequired] 11 [HttpGet] 12 public ActionResult Login(string ReturnUrl) 13 14 if (!Url.IsLocalUrl(ReturnUrl)) 16 ReturnUrl = /Admin/Home/Index; 17 18 if (Helpers.AuthFormService.TryAutoLogin()) 19 20 return Redirect(ReturnUrl); 21 22 View(); 23 24 25 26 账户首页 27 28 29 public ActionResult Index() 31 Models.User u = Session[ Models.User; 32 View(u); 34 }
Chapter 3 - 运行代码
开始调试代码,访问这个 Login
Action 时就直接崩了,一直在重定向到登录页面。 于是就想为什么会出现这样的情况呢,只使用 [Authorize]
和 [AllowAnonymous]
的时候是不会出现这种问题的,但是为什么自定义 Filter 的时候会出现这样的问题呢,是哪里出现的问题呢。
首先自带的[Authorize]
和 [AllowAnonymous]
是基于 就近原则 的,离的越近的 Filter 的权限越高会覆盖掉父级定义的 Filter。
但是自定义的 Filter 却并没有依照 就近原则 这一原则来控制权限,所以可能内部并不是靠判断哪个 Filter 离得近就用哪个 Filter的,下一步反编译 MVC 代码,看 MVC 是怎么样处理 [Authorize]
和 [AllowAnonymous]
的
Chapter 4 - 反编译分析出现问题的原因
利用 .Net 反编译工具 Reflector 或 JustDecompile反编译 System.Web.Mvc.dll ,在命名空间 System.Web.Mvc 下可以找到 Authorize
和 AllowAnonymous
的定义,如下图所示:
AllowAnonymous定义:
Authorize定义
通过上面的 Authorize.OnAuthorization 方法的定义基本可以知道问题出现在哪里了,Authorize 在进行权限验证的时候会判断当前请求的 Controller 和 Action 上是否有 AllowAnonymous 定义,如果有定义则不进行验证,跳过验证,只有在 当前请求的 Controller 和 Action 上都没有 AllowAnonymous 时才会进行权限验证。
Chapter 5 - 自定义 Filter V2.0
知道问题出现在哪里了,就开始修改自定义的 Filter 代码吧,修改之后的代码如下所示:
6 7 8 9 if (!filterContext.ActionDescriptor.IsDefined(typeof(nopermissionrequiredAttribute),true)) 11 12 { 13 filterContext.Result = 14 } } 16 18 }
修改之后再次进行调试,导航到登录页面就不会再出现重定向的问题,就实现了按 就近原则 来决定 Filter 的优先级的自定义的 Filter 了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。