bool allowAnnonymous = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true) || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute),true); if (allowAnnonymous) return;
这一点(以及HTTPS等博客提到的其他安全建议)给了我一个安全的默认模式,因此我不必对每一个动作应用安全检查,并且还要将其添加到未来的功能添加中.
问题的第一部分
现在,我没有在AuthorizeAttribute上使用Users / Roles属性,我需要从数据库中获取该东西.对我而言,这是在AuthorizeCore中的东西,因为唯一的责任是返回一个真假,用户是否可以访问.但是我有一个问题,AuthorizeCore必须是线程安全的,因为我读取了AuthorizeAttribute类的源代码,我不知道访问我的数据库以确定用户权限并坚持下去的最佳方式.我的应用程序正在使用IoC,目前让我的IoC容器将我的存储库注入到AuthorizeAttribute的构造函数中,但是通过这样做然后在AuthorizeCore中访问它,我没有引起线程安全问题?或者我将使用IoC实现和MVC3 DependencyResolver来为我的自定义AuthorizeAttribute构造函数提供参数,以充分处理线程安全性?请注意,我的存储库正在使用一个UnitOfWork模式,其中包括我的nHibernate SessionFactory作为存储库的构造,并且Unit of Work类是从我的IoC容器提供的,由StructureMap使用下面的行实现,我正在考虑这里使用的范围会处理线程问题吗?
For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use<UnitOfWork>();
问题的第二部分
我的数据模型(因此安全模型)被设置,使得我的主业务对象都被定义为这样一种方式,它是一个大的层次结构模型,当我检查权限时,我会看到该层次结构模型中用户帐户的位置默认情况下定义并授予对其下的所有内容的访问权限.
次要权限检查是使用管理定义的业务逻辑权限,例如角色X中的用户可以访问删除小部件功能.为此,我使用Route数据并拉出Controller和Action名称,并将它们与当前用户的详细信息一起使用,以查看我的数据库以解决此请求的权限.但是,对于页面上使用的每个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内的数据库
>安全关切绕过
授权检查儿童行为
>儿童行为的缓存问题
结合以前的观点
任何意见或帮助这些方面将不胜感激!
解决方法
然后,多线程访问不是问题,因为您的AuthorizeCore只是从缓存中获取角色,该缓存当时可以被视为只读.
第2部分:
再次去上面的第1点:) – 如果您的安全检查太重了,为什么不登录时加载用户的所有权限并将其缓存.在击中您的小孩的动作后,您可以要求权限,并在那时检查缓存.
肯定有一个更好的方法来处理这个不那么重的.如果您在单个请求中多次使用数据库,以获取权限,则需要通过某种机制来缓存您的权限集(自定义或实现另一个基于声明的系统等)
我不是100%跟随你的机制,而是基于路由的授权.你提到你正在从路线拉出信息 – 你能在这里举个例子吗?
保护孩子的行为绝对有意义.如果两个视图调用Html.Action – 一个专门作为一个管理员,另一个是错误地复制并粘贴到另一个视图中怎么办?你的孩子的行为应该总是受到保护,不要以为他们没有确定,因为他们只是从另一个角度来调用.
另外如果您无法为用户缓存整个树,那么您可以在第一次调用AuthorizeCore时缓存安全检查.随后的电话会简单地检查ex.缓存的角色 – 如果那么它使用它们,否则查看数据库.