我的安全逻辑应该放在哪里?[关闭]
-
25-09-2019 - |
题
假设我有一个 ASP.NET MVC Web 应用程序,它调用存储库层,该层构建在 nHibernate 之上。控制器将存储库传递给 ISecurityToken
它封装了当前用户的身份和权限,并且存储库在查询时使用它以仅返回用户应该能够看到的行。
我希望实体(票证)只能由特定用户组以及票证分配给的用户关闭。换句话说,假设的 CanCloseTicket()
方法需要两个输入:
- 门票本身(或其当前所有者 ID)
- 当前用户的
ISecurityToken
这个假设的方法应该放在哪里?我可以看到几种可能性,但每种都有其缺点。
- 在控制器中:控制器可以访问所有必要的内容,但这使得安全性有可能被绕过。(“哎呀,我忘记在设置之前在此操作中调用 CanCloseTicket()
ticket.IsOpen
假的!”这闻起来很糟糕。 - 在存储库中:存储库也可以访问这两个部分,但我还必须
Ticket.IsClosed
的 setter 为私有,以阻止上述相同的事情发生。存储库位于与模型完全不同的组件中,因此使用内部设置器不起作用。相反,我可以将 setter 保留为公开,并将属性的当前值与其原始值进行比较,如果非特权用户关闭它,则返回错误,但这对我来说也有点不对劲。(“哎呀,我忘了检查返回值repo.CloseTicket()
在这个动作方法中!”) - 门票中:添加
Ticket.Close(ISecurityToken token)
让实体负责自己的安全逻辑感觉像是违反了 建议零售价.
我认为存储库是这里最好的选择,但它 感觉 更像是最不坏的选择。还有别的事吗?
解决方案
你的最终选择对我来说听起来完全正确:当有人想要关闭票证时,他们必须提供 证据 以安全令牌的形式。(话虽如此,当您可以访问类的源代码时,判断是否违反 SRP 已经很困难了,我不能说我完全有信心。)
不隶属于 StackOverflow