MVC源码分析 - Authorize授权过滤器
从 上一篇 其实能看到, 程序执行的过滤器, 有四种 :
|
过滤器类型 |
接口 |
描述 |
|
Authorization |
IAuthorizationFilter |
此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法 |
|
Exception |
IExceptionFilter |
用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常 |
|
Action |
IActionFilter |
用于进入行为之前或之后的处理 |
|
Result |
IResultFilter |
用于返回结果的之前或之后的处理 |
但是默认实现它们的过滤器只有三种,分别是Authorize(授权),ActionFilter,HandleError(错误处理);各种信息如下表所示
|
过滤器 |
类名 |
实现接口 |
描述 |
|
ActionFilter |
AuthorizeAttribute |
IAuthorizationFilter |
此类型(或过滤器)用于限制进入控制器或控制器的某个行为方法 |
|
HandleError |
HandleErrorAttribute |
IExceptionFilter |
用于指定一个行为,这个被指定的行为处理某个行为方法或某个控制器里面抛出的异常 |
|
自定义 |
ActionFilterAttribute |
IActionFilter和IResultFilter |
用于进入行为之前或之后的处理或返回结果的之前或之后的处理 |
下面就来介绍一下这几种过滤器.
一、授权过滤器 Authorize
1. 方式一 : Controller类中的 OnAuthorization 方法
我们新建的控制器类里面, 都会直接或者间接继承自 Controller 类, 那么在Controller里面, 有一个 OnAuthorization 方法, 这个方法也是授权过滤器里面的.
// 摘要:
// 定义授权筛选器所需的方法。
public interface IAuthorizationFilter
{
// 摘要:
// 在需要授权时调用。
//
// 参数:
// filterContext:
// 筛选器上下文。
void OnAuthorization(AuthorizationContext filterContext);
}
这种方式, 是不需要在 FilterConfig 文件中, 配置自己的过滤器的.
我先建一个特性, 只要方法加上此特性, 都是不需要登录验证的.
public class AllowLoginAttribute : Attribute
{
}
里面没有任何的内容, 也不需要什么内容.
然后就是过滤器方法了.
public class HomeController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowLoginAttribute), true);
if (attrs.Count() > )
{
return;
}
var cookie = Request.Cookies["Login"];
if (cookie == null || cookie.Value != "Already Login")
{
//正如前面解析的, 只需要给Result赋值, 就可以影响MVC走的流程
filterContext.Result = RedirectToAction("Login");
}
}
//此方法会给浏览器一个 Cookie, 用来识别是否已登录身份的
//实际使用中, 可以做成登录页面, 要求登录, 然后给Cookie和Session
[AllowLogin]
public ActionResult Login()
{
HttpCookie cookie = new HttpCookie("Login", "Already Login");
cookie.Expires = DateTime.Now.AddMinutes();
Response.Cookies.Add(cookie);
return View();
}
//这里就是我想要访问的页面了
public ActionResult Index()
{
return View();
}
}
接下来, 我先直接访问Index页面看一下:

直接跳转到登陆页面了, 此时, 浏览器已经得到想要的Cookie了, 这时候, 再去访问Index页面看看.

成功访问.
由于这种方式是写在控制器里面的, 所以就只对控制器里面的方法有效, 也就是说, 如果此时我访问一个别的控制器, 这种方法就不起作用了.
那么, 我是不是要在每个控制器里面写一遍? 或者我自己弄一个控制器父类, 让别的类来继承我写的类? 是不是有点太麻烦了了.
肿么办呢? 方法就在下面
2. 方式二 : AuthorizeAttribute 的 OnAuthorization 方法
方法里面的内容和上面其实是一样的, 只不过这个方法存放的位置不一样.
但是有几个不一样的地方.
2.1 需要在FilterConfig中注册自己的过滤器
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyAuthAttribute());
filters.Add(new HandleErrorAttribute());
}
}
2.2 跳转的时候, 稍有不同
public class MyAuthAttribute : AuthorizeAttribute
{public override void OnAuthorization(AuthorizationContext filterContext)
{
var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowLoginAttribute), true);
if (attrs.Count() > )
{
return;
}
var cookie = HttpContext.Current.Request.Cookies["Login"];
if (cookie == null || cookie.Value != "Already Login")
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Login" }));
return;
}
}
}
2.3 最好在Web.config文件中修改下配置.
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Home/Login" timeout="2880" />
</authentication>
</system.web>
我自测过了, 是可以的. 结果就不贴了, 看不出什么别的. 和上面是一样的.
3. 方式三 : AuthorizeAttribute 的 AuthorizeCore 方法
这个方法就简单了, 只要返回false, 就回按照上面配置文件配置的去跳转. 一般都会将这里的 OnAuthorization 和 AuthorizeCore 方法一起用.
来看一下代码:
public class MyAuthAttribute : AuthorizeAttribute
{
//在这个方法中, 我判断了用户是否已经登录
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool isAuth = httpContext.User.Identity.IsAuthenticated;
return isAuth;
}
//在这个方法中, 我判断了 Action 是否需要 登录
public override void OnAuthorization(AuthorizationContext filterContext)
{
var attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowLoginAttribute), true);
if (attrs.Count() > 0)
{
return;
}
base.OnAuthorization(filterContext);
}
}
然后要修改一下HomeController控制器中的Login方法.
[AllowLogin]
public ActionResult Login()
{
//执行这个方法之后, Identity 的那里才能得到 true
FormsAuthentication.SetAuthCookie("Login", false);
return View();
}
如果不想修改配置文件, 想在程序中完成自定义跳转, 可以重写 AuthorizeAttribute的 HandleUnauthorizedRequest方法, 如:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.HttpContext.Response.Redirect("~/Home/Login");
}
这个方法是处理权限验证不通过后的事情.
在使用这个过滤器的时候, 也是有两种方法的.
1). 可以像上面那样, 在FilterConfig文件中注册进去, 这样都会从这个过滤器走一遍.
2). 还有一种方式, 更加的灵活. 并不注册进去, 而是只在想要验证权限的方法上面加上特性, 别的方法并不受影响.
[MyAuth]
public ActionResult Index()
{
return View();
}
这里只会对这一个方法进行权限验证, 因为我在方法上面标注了需要验证. 对于别的方法, 却不会进行权限验证, 非常的灵活.
MVC源码分析 - Authorize授权过滤器的更多相关文章
- MVC源码分析 - Action/Result 过滤器执行时机
前面 的篇章, 解析了Action方法的查找, 以及 Authorize, Action, Result, Error 过滤器的加载时机. 也花了两篇去看授权和错误过滤器的使用. 但是对于 Actio ...
- MVC源码分析 - Action/Result 过滤器(续)
上一篇 看到了Action/Result过滤器的执行顺序: OnActionExecuting -> Action -> OnActionExecuted -> OnResultEx ...
- ASP.NET MVC 源码分析(一)
ASP.NET MVC 源码分析(一) 直接上图: 我们先来看Core的设计: 从项目结构来看,asp.net.mvc.core有以下目录: ActionConstraints:action限制相关 ...
- 精尽Spring MVC源码分析 - 寻找遗失的 web.xml
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- WebForm / MVC 源码分析
ASP.NET WebForm / MVC 源码分析 浏览器 Url:https//localhost:6565/Home/Index ,https//localhost:6565/WebForm ...
- ASP.NET WebForm / MVC 源码分析
浏览器 Url:https//localhost:6565/Home/Index ,https//localhost:6565/WebForm1.aspx,请求服务器(构建请求报文,并且将请求报文发送 ...
- ASP.NET MVC源码分析
MVC4 源码分析(Visual studio 2012/2013) HttpModule中重要的UrlRoutingModule 9:this.OnApplicationPostResolveReq ...
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 在前面的文章中我们曾经涉及到ControllerActionInvoker类GetPara ...
- asp.net mvc源码分析-ModelValidatorProviders 客户端的验证
几年写过asp.net mvc源码分析-ModelValidatorProviders 当时主要是考虑mvc的流程对,客户端的验证也只是简单的提及了一下,现在我们来仔细看一下客户端的验证. 如图所示, ...
随机推荐
- day19(乱码解决方案)
乱码的解决方案: 首先需要理解乱码的产生原因:无非就是编码格式的问题 1.服务器到浏览器 字节流传输时 产生乱码的原因: 1.浏览器打开方式不对(打开时 的方式为默认的方式,各个浏览器的方式都不同) ...
- Linux 下socket通信终极指南(附TCP、UDP完整代码)
linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...
- day04_雷神_函数
#day04 1.函数 1.1函数传参 函数定义的时候是形参:函数执行的时候是实参 实参: 位置参数.关键字参数.混合参数 位置参数:位置一一对应 关键字参数: 可以位置不对应 混合参数:关键字参数要 ...
- 第三天:JavaScript的DOM对象和DOM操作HTML
1. DOM操作HTML 1)注意:绝对不要在文档加载完成之后使用docment.write().这样会覆盖原来的文档 <body> <p>hello</p> &l ...
- [ASE][Daily Scrum]11.05
在昨天的课程之后经过讨论进行了初步的分工,并制定出了我们的一个两周计划. 尚没有和老师讨论,已经询问了时间没有收到回复,等老师那边讨论过后我会在更新这个部分. 第一阶段的目标是用户能够在一个空白的地图 ...
- 利用C#迭代器的一个杨辉三角示例
身边有个朋友在跟着廖雪峰的教程学习python,途中遇到了"在Python中使用迭代器打印杨辉三角"的问题,我在帮忙解决的同时顺手写了个简单的C#版本以供补充. internal ...
- MySQL--当mysqldump --single-transaction遇到alter table(1)
部分生产环境采用mysqldump --single-transaction的方式在夜间进行数据库备份,而同事恰好在备份期间执行了alter table操作,操作部分成功部分失败,为啥呢? ##=== ...
- 新建WebAPI项目时遇到的问题
1 处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler” 以管理员运行下面的命令注册 ...
- 背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter
[源码下载] 背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter 作者:weba ...
- Android Dagger 2 无法自动生成 Dagger Component
给项目升级 gradle(3.0)和 build(27)后发现 Dagger 2 无法自动生成 Dagger Component 类了. 原因竟是我把 : kapt 'com.google.dagge ...