Nic*_*cht 12 security asp.net-mvc caching thread-safety asp.net-mvc-3
因此,在为我的MVC3应用程序寻找强大的安全解决方案后,我发现了Rick Anderson的这篇博客文章.它详细介绍了一个WhiteList方法,其中AuthorizeAttribute的自定义实现被应用为全局过滤器,并且您要使用虚拟属性AllowAnonymousAttribute来装饰您希望允许匿名访问的操作/控制器(我说虚拟因为AllowAnonymousAttribute中没有逻辑,所以它是只是一个空的属性类)
bool allowAnnonymous = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);
if (allowAnnonymous) return;
Run Code Online (Sandbox Code Playgroud)
这(以及他的博客上提到的其他安全建议,如HTTPS)为我提供了一个默认的安全模型,我不需要对每个操作都应用安全检查,并且还要记住将其添加到将来的功能添加中.
问题的第一部分
现在,我没有使用AuthorizeAttribute上的Users/Roles属性,我需要从数据库中获取这些东西.对我而言,这是AuthorizeCore中的内容,因为它唯一的责任是返回一个真假,用户是否有权访问.但是我有一个问题,根据我对AuthorizeAttribute类的源代码的读取,AuthorizeCore必须是线程安全的,我不确定访问我的数据库以确定用户权限并坚持这一点的最佳方法.我的应用程序正在使用IoC,目前让我的IoC容器注入我的存储库处理AuthorizeAttribute的构造函数,但是通过这样做然后在AuthorizeCore中访问它,我不会导致线程安全问题吗?或者我正在使用IoC实现和MVC3 DependencyResolver为我的自定义AuthorizeAttribute构造函数提供参数是否足以处理线程安全?注意,我的存储库使用的是UnitOfWork模式,其中包含我的nHibernate SessionFactory作为存储库的构造函数,而工作单元类是从我的IoC容器中提供的,由StructureMap使用下面的行实现,我在考虑这里使用的范围时是正确的会处理线程问题吗?
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<UnitOfWork>();
Run Code Online (Sandbox Code Playgroud)
问题的第二部分
我的数据模型(以及安全模型)的设置使得我的主要业务对象都被定义为一种大型层次结构模型,当我检查权限时,我会在该层次结构模型中查找用户帐户所在的位置默认情况下,定义并授予对其下所有内容的访问权限.辅助权限检查是使用管理定义的业务逻辑权限的权限,例如角色X中的用户可以访问"删除窗口小部件"功能.为此,我使用Route数据并提取Controller和Action名称,并将它们与当前用户的详细信息结合使用,以便访问我的数据库以解析此请求的权限.但是,对于页面上使用的每个ChildAction,也会重复这个逻辑,但是因为我使用了Route数据中的Controller和Action名称,所以我实际上并没有获得Child Action信息.它保留为父操作名称,而不是子操作,因为子操作未通过URL请求执行.这会导致对我的数据库进行冗余安全检查,以获取父操作和不必要的资源命中的详细信息.在研究这个时,我决定简单地绕过Child动作的安全性检查,并依赖于父动作.
bool bypassChildAction = filterContext.ActionDescriptor.IsDefined(typeof (ChildActionOnlyAttribute), true) || filterContext.IsChildAction;
if (bypassChildAction) return;
Run Code Online (Sandbox Code Playgroud)
这样做是否有意义,如果是这样,为什么?在我看来,如果Action使用ChildActionOnlyAttribute进行修饰,那么无论如何都无法通过URL公开访问它.如果它作为子操作执行但不仅仅是子操作,我可以绕过安全检查只是为了执行此操作,因为父操作将处理权限.您是否会遇到需要限制访问子操作的情况?知道子操作通常是非常小的部分视图我不认为这是一个问题,但我也看到OnAuthorization的默认实现中的一行引用了一些关于缓存的问题.有谁知道这是否会影响我提出的解决方案?
总结问题:
任何有关这些方面的意见或帮助将不胜感激!
Heya Yarx - 第 1 部分 - 缓存用户登录时的所有权限。那么多线程访问就不是问题了,因为您的 AuthorizeCore 只是从缓存中获取角色,此时可以将其视为只读。
第 2 部分:再次回到上面的第 1 点:) - 如果您的安全检查如此严格,为什么不在登录时加载用户的所有权限并缓存它们。点击子操作后,您可以请求权限,然后检查它们的缓存。
肯定有一种更好的方法来处理这个问题,而且不会那么重。如果您在一次请求中多次访问数据库只是为了获取权限,则需要通过某种机制(自定义或实现另一个基于声明的系统等)缓存您的权限集
不过,我并没有 100% 遵循您的基于路线的授权机制。您提到您正在从路线中提取信息 - 您能在这里举个例子吗?
保护您孩子的行为绝对有意义。如果两个视图调用 Html.Action - 一个专门作为管理员,另一个被错误地复制并粘贴到另一个视图中,该怎么办?您的子操作应该始终受到保护,不要认为它们没问题,因为它们只是从另一个视图调用的。
此外,如果您无法缓存用户的整个树,您当然可以在第一次调用 AuthorizeCore 时缓存安全检查。后续调用将简单地检查 ex。缓存角色 - 如果存在则使用它们,否则查看数据库。
归档时间: |
|
查看次数: |
2662 次 |
最近记录: |