加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

深入了解 Authorize 和 AllowAnonymous

发布时间:2020-12-16 09:01:09 所属栏目:asp.Net 来源:网络整理
导读:深入了解 Authorize 和 AllowAnonymous Chapter 0 - Intro 最近做的一个项目的时候,自定义授权 Attribute 来区分用户权限,我的项目不太大,权限控制也不是很复杂,只涉及到匿名、普通用户、超级管理员。 权限验证方式使用的是默认的 MemberShip 认证结合自

深入了解 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

控制器代码中引用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 下可以找到 AuthorizeAllowAnonymous的定义,如下图所示:

?

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 了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读