[英]Explain HOW the MVC Authorize Attribute performs AOP-like actions
I've been trying to figure out how this works on a low-level: 我一直试图弄清楚它是如何在低级别上运行的:
[Authorize]
public ActionResult Index()
{
return View();
}
Basically, the above code snippet seems to intercept calls to the Index method, perform an authorization check, and throw and exception if not authorized. 基本上,上面的代码片段似乎拦截了对Index方法的调用,执行授权检查,以及如果未经授权则抛出和异常。 The exception prevents the code within the Index method from ever being invoked. 该异常可防止调用Index方法中的代码。
This seems very AOP-like, and is not something easily done in C#. 这看起来很像AOP,并不是C#中容易做到的。 If I were to implement my own class that extended System.Attribute, I would not have any interface to hook into pre or post invocation of the method my attribute decorates. 如果我要实现我自己的扩展System.Attribute的类,我将没有任何接口可以挂接到我的属性修饰的方法的前或后调用。 So how does the MVC Authorize attribute do it, and how could I do it on my own? 那么MVC Authorize属性如何做到这一点,我怎么能自己做呢?
PostSharp is a library that accomplishes the same thing using IL Weaving. PostSharp是一个使用IL Weaving完成同样事情的库。 Basically, at compile time, PostSharp scans the assembly for methods decorated with certain attributes, and then re-writes your code to wrap your method calls with other method calls. 基本上,在编译时,PostSharp会扫描程序集以查找使用某些属性修饰的方法,然后重新编写代码以使用其他方法调用包装方法调用。
Does the MVC framework also perform some kind of IL Weaving at compile time? MVC框架是否也在编译时执行某种IL编织? Is it possible for me to perform my own IL Weaving? 我有可能进行自己的IL编织吗? Or are there other techniques for applying the same AOP principles without complex IL Weaving? 或者是否有其他技术可以应用相同的AOP原则而无需复杂的IL编织?
I've tried to find information on IL Weaving but all I find are articles about PostSharp. 我试图找到关于IL Weaving的信息,但我找到的只是关于PostSharp的文章。 I would prefer to stay away from PostSharp because of the Licensing hassles, but moreover, I just want to know how the heck they did it for my own growth as a developer. 由于许可麻烦,我宁愿远离PostSharp,而且,我只是想知道他们为我自己作为开发人员的成长做了多少。 It's quite fascinating. 这真是令人着迷。
the easiest way to understand it is by looking at the source code. 理解它的最简单方法是查看源代码。
a basic explanation is that the mvc controller is not simply called like instance.method (in which case you would need postsharp to make the attributes work the same way) 一个基本的解释是mvc控制器不是简单地调用像instance.method(在这种情况下你需要postharp来使属性以相同的方式工作)
there is a ControllerActionInvoker
which has the method 有一个ControllerActionInvoker
有这个方法
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
...
// get all the filters (all that inherit FilterAttribute), inlcuding the authorize attribute
FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
first all the filters that inherit IAuthorizationFilter
are executed (Authorize, ValidateAntiForgeryToken)
, after if auth succeeded the rest 首先执行继承IAuthorizationFilter
所有过滤器(Authorize, ValidateAntiForgeryToken)
,如果auth成功完成其余的
AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
//authContext.Result has value if authorization didn't succeed
if (authContext.Result != null)
{
// the auth filter signaled that we should let it short-circuit the request
InvokeActionResult(controllerContext, authContext.Result);
}
else
{
if (controllerContext.Controller.ValidateRequest)
{
ValidateRequest(controllerContext);
}
IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
//invoke the action with filters here
ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.