1

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

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

  1. 票证本身(或其当前所有者 ID)
  2. 当前用户的ISecurityToken

这种假设的方法应该在哪里?我可以看到几种可能性,但每种都有其缺点。

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

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

4

1 回答 1

1

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

于 2010-12-09T22:03:23.433 回答