我的安全逻辑应该放在哪里?

时间:2010-12-09 21:33:25

标签: security oop single-responsibility-principle repository-design

假设我有一个ASP.NET MVC webapp,它调用了一个基于nHibernate构建的存储库层。控制器传递存储库ISecurityToken,封装当前用户的身份和权限,存储库在查询时使用它,只返回用户应该能够看到的行。

我希望实体(票证)只能由特定的一组用户以及分配票证的用户关闭。换句话说,假设的CanCloseTicket()方法需要两个输入:

  1. 票证本身(或其当前所有者ID)
  2. 当前用户的ISecurityToken
  3. 这种假设方法应该在哪里生活?我可以看到几种可能性,但每种都有它们的缺点。

    • 在控制器中:控制器可以访问所有必要的内容,但这样可以绕过安全性。 (“糟糕,在将ticket.IsOpen设置为false之前,我忘记在此操作中调用CanCloseTicket()!”这闻起来很糟糕。
    • 在存储库中:存储库也可以访问这两个部分,但我还必须将Ticket.IsClosed的setter设为私有,以阻止上述相同的事情发生。存储库与模型完全不同,因此使用内部setter不起作用。我可以将setter公开并将属性的当前值与其原始值进行比较,如果非特权用户关闭它则返回错误,但这对我来说也有些异味。 (“哎呀,我忘了在这个动作方法中检查repo.CloseTicket()的返回值!”)
    • 在故障单中:添加Ticket.Close(ISecurityToken token)并使实体对其自身的安全逻辑负责,这感觉违反了SRP

    我认为存储库是最好的选择,但它感觉更像是最差的选项。还有别的吗?

1 个答案:

答案 0 :(得分:1)

您的最终选项对我来说听起来完全正确:当有人想要关闭机票时,他们必须以安全令牌的形式提供证据。 (话虽如此,当您访问一个我不能说我完全有信心的类源代码时,判断SRP违规是很困难的。)

相关问题