简体   繁体   English

解释MVC授权属性如何执行类似AOP的操作

[英]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.

相关问题 AspectF(流畅的Aspect框架)是一种类似AOP的设计,可以毫不费力地使用吗? - Is AspectF (a Fluent Aspect Framework) an AOP-like design that can be used without much concern? 如何使用Authorize属性为控制器操作编写失败的单元测试用例 - How to write failed unit test case for controller actions with Authorize attribute MVC RoleProvider和Authorize属性 - MVC RoleProvider and Authorize attribute 在C#中编写自定义属性,如ASP.Net MVC Authorize属性 - Writing Custom Attribute in C# like ASP.Net MVC Authorize attribute 用Authorize属性修饰的单元测试操作 - unit test actions decorated with Authorize attribute ASP.Net MVC:如何在授权或受限制的控制器和操作名称中进行迭代 - ASP.Net MVC: How to iterate in authorize or restricted controllers and actions name 如何在没有Authorize属性的情况下调用连接/授权 - How to call connect/authorize without Authorize attribute 如何返回false,如何创建将重定向到Login的自定义属性,类似于Authorize属性 - ASP.NET MVC - How to create a custom attribute that will redirect to Login if it returns false, similar to the Authorize attribute - ASP.NET MVC 自定义角色提供程序的授权属性在MVC 5中不起作用 - Authorize attribute of custom Role provider not working in MVC 5 从MVC4中的Authorize属性捕获异常 - Capture exceptions from Authorize attribute in MVC4
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM