【发布时间】:2010-12-16 12:22:48
【问题描述】:
我有一个 ASP.NET MVC 应用程序,其控制器如下所示:
[Authorize]
public class MyController : Controller
{
IMyRepository myRepository;
public MyController(IMyRepository myRepository)
{
this.myRepository = myRepository;
}
...
}
我注意到这个构造函数在验证用户之前被调用,所以如果你是第一次访问这个页面,构造函数会在你重定向到登录屏幕之前被调用。这有很多问题,登录页面加载速度较慢,该站点更容易受到 DOS 攻击,而且我对未经身份验证的、未经授权的用户能够调用“墙后”之类的代码有点紧张。
除非用户被授权,否则我可以在构造函数中检查传入请求并保释,但我使用的是 IOC (Windsor),这有点棘手,无论我是否存储,我的存储库都将被初始化实例,所以我将在每个存储库的构造函数中检查身份验证。有没有一种简单的方法可以让 .NET MVC 在调用构造函数之前对用户进行身份验证?我正在考虑将[PrincipalPermission(SecurityAction.Demand, Authenticated = true)] 添加到控制器中,但可能还有更好的方法。
编辑:
好的,不太高兴,但节目现在必须继续。我不能延迟初始化存储库,直到控制器内的某个稍后时间点。当您的控制器像我的示例中那样使用 IOC 时,您会在实例化控制器时获得存储库接口的已实例化实现。如果我可以控制正在创建的存储库,我可以轻松地调用 IsAuthenticated,而无需使用新方法。为了控制存储库初始化,您必须在每个实现中的存储库本身中实现某种延迟/延迟初始化。我不喜欢这个解决方案,因为它增加了不必要的复杂性,更重要的是控制器和存储库之间的耦合。存储库实现可以在延迟初始化没有意义的其他上下文中使用恕我直言。
【问题讨论】:
-
假设您的 IMyRepository 实现的构造函数是轻量级的,那么我在这里看不到主要问题(即,如果设置与后备存储的实际连接是一个昂贵的过程,那么就懒惰地进行,即在第一次读/写时)。您无需再在登录页面中公开这一点,因为它也正在实例化控制器并可能访问后备存储以验证凭据。
-
@Lazarus 但是如果对我的控制器的依赖需要访问非空用户名(即用户需要在该点进行身份验证)怎么办。目前我正在为此使用
Lazy<T>实例,但我讨厌它。我认为在用户到达控制器之前对其进行身份验证太有意义了。
标签: asp.net-mvc authentication