问题 在ASP.NET MVC应用程序中实现粒度安全性(即授权)的最佳机制是什么?


假设高速开发人员的任务是构建一个可由许多不同的人访问的银行应用程序。每个人都希望访问他或她自己的帐户信息,但不希望其他人访问它。我想知道限制MVC应用程序访问的最佳实践,以便只有拥有该信息的用户(或管理员)才能访问它。

Authorize 属性允许我们按角色进行限制。虽然这是一个起点,但似乎任何经过身份验证的用户都可以访问任何其他用户的信息。

ActionFilters似乎提供了更精细控制的选项,可能用于完成任务。但是,我不清楚它们是否是推荐的方法。

欢迎任何指导或想法。


1480
2017-08-22 05:39


起源

什么是“高速开发者”? - Matthew Groves


答案:


ActionFilter可能是一个很好的起点,但根据您的架构,您可能需要考虑外围防御是否足够好。

如果你基本上构建一个单层ASP.NET MVC应用程序(并且可能有完全合理的理由这样做),ActionFilter将提供足够好的防御,同时非常简单地应用。

另一方面,如果您的应用程序是多层应用程序,则深度防御更合适。在这种情况下,您应该考虑在域模型中应用授权逻辑,或者甚至在数据访问层中应用授权逻辑。这将确保如果您开发基于相同域模型的另一个应用程序(例如Web服务),则授权逻辑仍然适用。

无论你做什么,我强烈建议你将实际的授权实现建立在IPrincipal上。

更具体地说,您在这里询问的内容最好使用基于ACL的授权建模:在每个用户配置文件上设置ACL,默认情况下仅授予用户他/她和管理员访问权限。如果/稍后您需要扩展应用程序以允许委派访问其他用户的配置文件(我不知道在您的特定情况下是否甚至是远程实际的),您可以通过向ACL添加新条目来实现。

在这种情况下,评估访问涉及检索所请求资源的ACL并检查当前用户(IPrincipal)是否包含在该ACL中。这样的操作很可能涉及进程外操作(在数据库中查找ACL),因此通过将其隐藏在ActionFilter后面将其作为应用程序的隐式部分听起来有可能隐藏一些性能问题。在这种情况下,我会考虑使授权模型更明确/可见。


10
2017-08-22 08:37



马克,这是一个很好的策略!谢谢!在我之前的大多数项目中,我们编写了自己的安全组件来管理权限,用户,组,角色等。并且专门绕过ASP.NET成员资格架构以适应较低级别的访问控制。我曾希望有一种更简单的方法来实现MVC中的权限而不是滚动我自己的权限。从我最初的帖子开始,无论如何我最终还是写了它,但采取了混合方法。我使用ASP.NET的成员资格和角色提供程序来获得基本权限和角色管理,但是我开发了自己的组和权限管理以实现更好的粒度控制。
当用户尝试执行操作(在控制器上)时,我会检查他的角色以确保他具有“基本”访问权限。如果没有,我会重定向他。如果他确实有基本访问权限,我会调用一个更细粒度的函数来检查他对特定对象类型和/或他试图访问的实例的实际权限。现在,我还没有将其作为动作过滤器实现,但我只是在每个动作中调用它。我很快就会重构它。
很高兴您可以使用答案 - 您可能还想看看这个有些相关的答案: stackoverflow.com/questions/1335315/... - Mark Seemann


根据我的观点,如果你有单层应用程序,那么授权是最好的选择,而actionfilter也更好,更简单易用。但是,如果您的应用程序是多层的,那么您可以使用Mus USE访问控制列表[ACL]。


1
2018-01-12 10:53





我认为你有正确的,ActionFilter方法是合理的。

我将创建一组继承自AuthorizeAttribute的自定义操作过滤器。

除了Authorize属性的功能之外,您还可以干净地实施更严格的所有者策略。

HTH,


0
2017-08-22 06:34



谢谢丹!您对实施“更严格的所有者政策”有何建议?这与Mark上面描述的类似吗?
完全是安东尼,特别是马克回答的最后一段。我会从Authorize过滤器派生您的自定义过滤器,因为您需要一个授权的IPrincipal来检查ACL。 - Daniel Elliott


如果您想要外部授权,可以查看基于XACML的实现。


0
2017-11-15 19:43