深入了解 Authorize 和 AllowAnonymous

Chapter 0 - Intro

最近做的一个项目的时候,自定义授权 Attribute 来区分用户权限,我的项目不太大,权限控制也不是很复杂,只涉及到匿名、普通用户、超级管理员。 权限验证方式使用的是默认的 MemberShip 认证结合自己自定义的 权限验证 Filter。

Chapter 1 - 自定义 Filter V1.0

Filter代码 V1.0

 /// <summary>
/// 不需要登录即可访问
/// </summary>
public class NoPermissionRequiredAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
} /// <summary>
/// 需要登录才能进行操作
/// </summary>
public class PermissionRequiredAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Session["User"]==null)
{
filterContext.Result = new RedirectResult("~/Admin/Account/Login");
}
base.OnActionExecuting(filterContext);
}
} /// <summary>
/// 需要有超级管理员权限
/// </summary>
public class AdminPermissionRequiredAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if ((filterContext.HttpContext.Session["User"] == null) || !((filterContext.HttpContext.Session["User"] as Models.User).IsSuper))
{
filterContext.Result = new RedirectResult("~/Admin/Account/Login");
}
base.OnActionExecuting(filterContext);
}
}

Chapter 2 - 控制器引用 Filter

控制器代码中引用Filter 代码:

 [Authorize]
[Filters.PermissionRequired]
public class AccountController : BaseAdminController
{
/// <summary>
/// 登录页面
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[Filters.NoPermissionRequired]
[HttpGet]
public ActionResult Login(string ReturnUrl)
{
if (!Url.IsLocalUrl(ReturnUrl))
{
ReturnUrl = "/Admin/Home/Index";
}
if (Helpers.AuthFormService.TryAutoLogin())
{
return Redirect(ReturnUrl);
}
return View();
} /// <summary>
/// 账户首页
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
Models.User u = Session["User"] as Models.User;
return View(u);
}
}

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 代码吧,修改之后的代码如下所示:

 /// <summary>
/// 需要登录才能进行操作
/// </summary>
public class PermissionRequiredAttribute : ActionFilterAttribute
{ public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.ActionDescriptor.IsDefined(typeof(NoPermissionRequiredAttribute),true))
{
if (filterContext.HttpContext.Session["User"] == null)
{
filterContext.Result = new RedirectResult("~/Admin/Account/Login");
}
}
base.OnActionExecuting(filterContext);
}
}

修改之后再次进行调试,导航到登录页面就不会再出现重定向的问题,就实现了按 就近原则 来决定 Filter 的优先级的自定义的 Filter 了。

深入了解 Authorize 和 AllowAnonymous的更多相关文章

  1. mvc4 实现自己的权限验证 仿Authorize与AllowAnonymous原理

    参考文章 :http://www.cosdiv.com/page/M0/S878/878978.html 实现的效果:在控制器上(Controller)验证权限,在动作(Action)上不验证. 用M ...

  2. ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 配置 上一章节我们简单介绍了下 Id ...

  3. ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 验证特性 上一章节我们简单介绍了 ...

  4. 开始你的api:NetApiStarter

    在此之前,写过一篇 给新手的WebAPI实践 ,获得了很多新人的认可,那时还是基于.net mvc,文档生成还是自己闹洞大开写出来的,经过这两年的时间,netcore的发展已经势不可挡,自己也在不断的 ...

  5. AspNetCore3.1_Secutiry源码解析_8_Authorization_授权框架

    目录 AspNetCore3.1_Secutiry源码解析_1_目录 AspNetCore3.1_Secutiry源码解析_2_Authentication_核心流程 AspNetCore3.1_Se ...

  6. 这难道不是.NET5 的bug? 在线求锤?

    hello,最近在对一个使用.NET5项目的认证授权系统进行重构,对.NET 5的授权中间件的源码有些看法. 也希望同学们能帮我理解. 一个朴素的需求 这是一个api项目,默认所有的api都需要授权, ...

  7. .NET CORE 授权

    .NET CORE 授权 一.三种方式授权 不论使用NET CORE框架的何种授权都必须引入中间件,因为它实现了在管道中对当前请求的鉴权和授权的验证,在Startup中的Configure中首先加入鉴 ...

  8. ASP.NET Core 6.0 添加 JWT 认证和授权

    序言 本文将分别介绍 Authentication(认证) 和 Authorization(授权). 并以简单的例子在 ASP.NET Core 6.0 的 WebAPI 中分别实现这两个功能. 相关 ...

  9. 解决ASP.NET MVC AllowAnonymous属性无效导致无法匿名访问控制器的问题

    在ASP.NET MVC项目中,一般都要使用身份验证和权限控制,但总有部分网页是可以匿名访问的.使用AllowAnonymous属性就可以指定需要匿名访问的控制器,从而跳过身份验证. 但是今天却遇到一 ...

随机推荐

  1. 学用MVC4做网站六后台管理:6.1管理员(续)

    接6.1 首先在~/Areas/Admin/Models文件夹添加管理员模型Administrator.cs using System.ComponentModel.DataAnnotations; ...

  2. javascript运动系列第七篇——鼠标跟随运动

    × 目录 [1]眼球转动 [2]苹果菜单[3]方向跟随 前面的话 运动除了直线运动和曲线运动两种运动形式外,还有一种运动形式是鼠标跟随运动,而这种跟随运动需要用到三角函数的相关内容或者需要进行比例运算 ...

  3. java泛型上下限

    前言: java的泛型上下限不是很好理解,尤其像我这种菜鸡.反反复复看了好几遍了...,真是... 一.简单的继承体系 class Person{} class Student extends Per ...

  4. 配置 DHCP 服务 - 每天5分钟玩转 OpenStack(89)

    前面章节我们看到 instance 在启动过程中能够从 Neutron 的 DHCP 服务获得 IP,本节将详细讨论其内部实现机制. Neutron 提供 DHCP 服务的组件是 DHCP agent ...

  5. EntityFramework 7 smallint short 奇怪问题(已解决)

    在使用 EF7 进行条件查询的时候,遇到一个很奇怪的问题,不知道 EF 其他版本有没有这种情况,怎么说呢?一句话描述不清楚,具体请看下面内容. 问题场景 BloggingContext 配置代码: u ...

  6. C#缓存操作

    1.缓存辅助方法类的接口代码: public interface IThrottleStore { /// <summary> /// 试图获取值 /// </summary> ...

  7. 用纯JS做俄罗斯方块 - 简要思路介绍(1)

    大家都知道俄罗斯方块是一款大众化的游戏了,我很小的时候就玩过,今年已经25岁了,可以说俄罗斯方块确实是历史悠久,做俄罗斯方块是我上个星期开始的想法.也许是由于自己从来没有写过这种东西吧,所以有生疏.代 ...

  8. SFC中的问题描述

    本文主要描述了在大规模的网络环境中部署服务功能存在的一些问题,还提出了几个关键领域,即SFC工作组将要探讨的关于SFC结构.工作协议.相关文档. 1.问题描述 SFC工作组致力于解决的几个服务部署中存 ...

  9. js数组去重的4种方法

    js数组去重,老生长谈,今天对其进行一番归纳,总结出来4种方法 贴入代码前 ,先对浏览器Array对象进行支持indexOf和forEach的polyfill Array.prototype.inde ...

  10. java基础面试题

    参考:http://blog.csdn.net/jackfrued/article/details/44921941 说未经允许不转载,我只好参考了. 1.面向对象的特征有哪些方面? 抽象:抽象是将一 ...