因此,在为我的 MVC3 应用程序寻找强大的安全解决方案后,我遇到了这篇博文 http://blogs.msdn.com/b/rickandy/archive/2011/05/02/securing-your-asp-net-mvc-3-application.aspx作者:里克·安德森。它详细介绍了一种白名单方法,其中将 AuthorizeAttribute 的自定义实现用作全局过滤器,并且您使用虚拟属性AllowAnonymousAttribute 装饰您希望允许匿名访问的操作/控制器(我说虚拟属性是因为AllowAnonymousAttribute 内部没有逻辑,它是只是一个空属性类)
bool allowAnnonymous = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);
if (allowAnnonymous) return;
这(以及他的博客上提到的其他安全建议,如 HTTPS)为我提供了一个安全的默认模型,这样我就不必对每个操作应用安全检查,并且记住将其添加到未来的功能添加中。
问题的第一部分
现在,我没有在 AuthorizeAttribute 上使用用户/角色属性,我需要从数据库中获取这些内容。对我来说,这就是 AuthorizeCore 中的内容,因为它的唯一责任是返回 true false,用户是否有权访问。但是我有一个问题,根据我对 AuthorizeAttribute 类源代码的阅读,AuthorizeCore 必须是线程安全的,并且我不确定访问数据库以确定用户权限并遵守该权限的最佳方法。我的应用程序正在使用 IoC,并且当前让我的 IoC 容器将处理所有这些内容的存储库注入到 AuthorizeAttribute 的构造函数中,但是通过执行此操作然后在 AuthorizeCore 中访问它,我是否不会造成线程安全问题?或者,IoC 实现和我用来向自定义 AuthorizeAttribute 构造函数提供参数的 MVC3 DependencyResolver 是否能够充分处理线程安全?请注意,我的存储库使用 UnitOfWork 模式,其中包括我的 nHibernate SessionFactory 作为存储库的构造函数,并且工作单元类是从我的 IoC 容器提供的,由 StructureMap 使用下面的行实现,我对此处使用的范围的看法是否正确会处理线程问题吗?
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<UnitOfWork>();
问题的第二部分
我的数据模型(以及安全模型)是这样设置的,以便我的主要业务对象全部定义为一个大型层次结构模型,当我检查权限时,我会在该层次结构模型中查找用户帐户所在的位置定义并默认授予对其下所有内容的访问权限。
辅助权限检查是使用管理定义的业务逻辑权限的检查,例如角色 X 中的用户是否可以访问“删除小部件”功能。为此,我使用路由数据并提取控制器和操作名称,并将它们与当前用户主体详细信息中的详细信息结合使用,以访问我的数据库来解析此请求的权限。然而,对于页面上使用的每个 ChildAction 也会重复此逻辑,但因为我使用的是 Route 数据中的 Controller 和 Action 名称,所以我实际上并未获取 Child Action 信息。它保留为父操作名称,而不是子操作名称,因为子操作不是通过 URL 请求执行的。这会导致对我的数据库进行冗余安全检查,以获取父操作的详细信息和不必要的资源命中。在研究这个问题时,我决定简单地绕过子操作的安全检查,并依赖父操作来实现这一点。
bool bypassChildAction = filterContext.ActionDescriptor.IsDefined(typeof (ChildActionOnlyAttribute), true) || filterContext.IsChildAction;
if (bypassChildAction) return;
这样做有意义吗?如果有/没有,为什么?在我看来,如果 Action 用 ChildActionOnlyAttribute 修饰,则无论如何都无法通过 URL 公开访问它。如果它作为子操作执行但不完全是子操作,我可以绕过此执行的安全检查,因为父操作将处理权限。您是否曾经遇到过需要限制对子操作的访问的情况?知道子操作通常是非常小的部分视图,我预计这不会成为问题,但我也看到 OnAuthorization 的默认实现中引用了一行,概述了有关缓存的一些问题。有谁知道这是否会影响我提出的解决方案?
总结关注点:
- 多线程问题
访问用户权限
AuthorizeCore 内的数据库
- 绕过的安全问题
子操作的授权检查
- 缓存子操作的问题
与上一点相结合
任何有关这些方面的意见或帮助将不胜感激!