我有一个ASP.NET MVC应用程序,其控制器看起来像这样:
[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository = myRepository;
}
...
}
我注意到在验证用户之前调用了这个构造函数,所以如果你是第一次访问页面,那么在重定向到登录屏幕之前会调用构造函数。这有很多问题,登录页面加载速度较慢,网站有更多暴露于DOS的攻击,我对未经验证的未经授权的用户有点紧张,他们可以在墙后面调用代码。
我可以检查构造函数中的incomming请求并保释,除非用户被授权,但我正在使用IOC(Windsor),这使得它有点棘手,我的存储库将被初始化,无论我是否存储实例,所以我将在每个存储库的构造函数中检查身份验证。是否有一种简单的方法可以让.NET MVC验证用户之前来调用构造函数?我在考虑将[PrincipalPermission(SecurityAction.Demand, Authenticated = true)]
添加到控制器,但可能还有更好的方法。
编辑:
好的,不太高兴,但这个节目现在必须继续。我不能延迟初始化存储库,直到控制器内的某个稍后的时间点。当您的控制器在我的示例中使用IOC时,您将在实例化控制器时获得已实例化的存储库接口实现。如果我可以控制正在创建的存储库,我可以很容易地调用IsAuthenticated,不需要新的方法。为了控制存储库初始化,您必须在每个实现中的存储库本身中实现某种延迟/延迟初始化。我不喜欢这个解决方案,因为它增加了不必要的复杂性,更重要的是增加了控制器和存储库之间的耦合。存储库实现可以在懒惰初始化没有意义的其他上下文中使用恕我直言。
答案 0 :(得分:4)
控制器需要在授权发生之前进行实例化,因为它可以通过OnAuthorization
方法充当自己的授权过滤器。改变这种行为将涉及替换mvc管道的一些核心部分。是否有一个特殊原因让您认为AuthorizedAttribute
可能无法正常工作?
您可以考虑的另一个选项是在控制器方法的OnActionExecuting
中而不是在构造函数中初始化存储库。
答案 1 :(得分:1)
您可以使用HttpModules(或HttpHandler)在管道中更早地验证请求。
修改强>
通过引入OWIN,您可以配置整个请求管道中间件,并将授权放在您想要的任何阶段。与上述相同,但更容易实现。
答案 2 :(得分:0)
保罗,
控制器的实例化是在可调用的控制器上的任何操作之前的许多进程。即使攻击者试图从实例化和登录屏幕之间的这段时间间隔中受益,控制器操作也只能在行动有权这样做的情况下运行,即我假设您的行为或控制器全部它们具有[Authorize]
属性。
我认为你不需要太担心这件事,并且可以轻松休息,因为我明白你明显的好奇心。
答案 3 :(得分:0)
就DOS攻击而言,它确实无关紧要 - 在第一次打击之后,在开发时会看到很多,控制器实例化应该很便宜。好吧,除非您通过让构造函数执行实际工作(例如预缓存数据库查找)来自己进行DDOS。 。