gpt4 book ai didi

database - 图层设计 : where to check permissions for database reads/updates?

转载 作者:太空狗 更新时间:2023-10-30 01:42:37 24 4
gpt4 key购买 nike

在大多数情况下,您希望用户只能访问用户自己创建的数据库中的实体。例如,如果有一个由 User1 创建的日历,则只有 User1 应该能够读取、更新或删除该特定日历及其在数据库中的内容。这与一般授权无关——在我的项目中,已经有一个基于角色的授权组件,它检查用户是否属于“日历编辑器”角色,但它不检查特定用户是否被允许访问具体日历。

因此,最终必须在当前请求的用户 ID 和代表所请求日历所有者的用户 ID 之间进行比较。但我想知道在哪里做这个。我的想法:

  • 我可以在 DAO 级别上完成。但是每个 DAO 方法都需要一个额外的参数来表示用户 ID,这使得这些方法更加冗长并降低了可重用性。

    例如

    def findCalById(id: Int): future [选项[日历]]

    成为

    def findCalById(id: Int, ownerId: Int ): Future[选项[日历]]

    一个优点是权限检查基本上是在查询级别完成的,这意味着如果用户无权访问日历,则不会从数据库返回任何日历。但话又说回来:如果在某些情况下没有返回日历,你如何区分不存在的日历和当前用户无法访问的现有日历?两种不同的场景,产生相同的结果。

  • 另一种选择是将 DAO 排除在外,并在服务层或类似的东西中进行检查。这意味着检查是在 DAO 返回请求的日历之后执行的。这种方法听起来比另一种方法更灵活,但这也意味着如果用户无法访问所请求的日历,所请求的日历仍然会消耗带宽和内存,因为在任何一种情况下它都是从数据库中获取的。

也许还有其他我什至没有考虑过的选项。有什么最佳做法吗?

顺便说一句:我的 Web 应用程序中没有日历,这只是一个说明问题的示例。

最佳答案

我认为,当您说 DAO 方法“降低了可重用性”时,关键是要思考您的确切意思。如果您强制执行用户访问权限的要求对于您的 DAO 的所有应用程序都是通用的,那么在 DAO 级别执行此操作实际上增加可重用性而不是降低它:使用 DAO 的每个人都可以从这些中受益检查而不是必须自己实现它们。

您可以将用户 ID 设为隐式参数,以使这些方法对上游用户更加友好。您还可以让它返回一个 Try(或者,也许,一个 Either)来解决您对区分丢失和无法访问的对象情况的担忧:

case class UserId(id: Int)
def findCalById(id: Int)(implicit user: UserId): Future[Try[Option[Calendar]]] = ???

然后,调用者可以做这样的事情:

implicit val currentUser = UserId(request.getUserId)
dao.findCalById(request.getCalendarId).map {
case Failure(IllegalAccessException()) => "You are not allowed to use this calendar"
case Return(None) => "Calendar not found"
case Return(Some(cal)) => calendarToString(cal)
}

另一方面,如果有可能在没有用户上下文(可能是“管理”应用程序)的情况下使用 DAO 的情况,那么您可以考虑将其子类化以提供对“常规应用程序”的访问控制,或者,也许只是创建一个额外的角色,允许用户访问与所有权相关的所有日历,然后在您的管理应用程序中使用该“ super 用户”。

我不会担心在检查访问之前必须加载对象的成本(即使加载对象真的很昂贵,也应该很少有人试图访问他不拥有的对象) .我认为,反对服务层方法的一个更有力的论点恰恰是代码的可重用性和模块化:具有公共(public)接口(interface)的 DAO 类的存在表明它至少有可能被多个组件重用。要求所有这些组件实现它们自己的访问检查似乎很愚蠢,尤其是考虑到这样的契约(Contract)将无法执行:没有办法确保几年后决定使用您的 DAO 类的人,会记住这个要求(或注意阅读评论)。无论如何,如果您正在生成一个用于访问数据库的层,您不妨让它对某些东西有用。

关于database - 图层设计 : where to check permissions for database reads/updates?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33985737/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com