【问题标题】:Implement authorization for ActiveRecord methods对 ActiveRecord 方法实施授权
【发布时间】:2016-04-12 10:52:11
【问题描述】:

我一直在尝试在 ActiveRecord 之上实现一个授权层。让我解释一下它应该如何工作。

数据库

考虑一个包含以下字段的数据库表Invoices

  • 发票编号
  • 客户 ID
  • ...其他字段

会有一个带有字段的辅助表InvoicePrivileges

  • ObjectId(指发票 ID)
  • SubjectId(在这种情况下指的是客户 ID)
  • 主题类型(处理多种用户 - 客户、管理员、操作员等)
  • 读取(布尔值)
  • 写入(布尔值)

授权检查

为了能够读取发票,尝试read 行或行集的实体必须在InvoicePrivileges 表中有一组条目(其中InvoicePrivileges.object_id 指的是InvoiceId)和@ 987654328@.

例如,从数据库中获取一堆发票的查询

SELECT invoice.*
FROM Invoices invoice
LEFT JOIN InvoicePrivileges privilege 
    ON invoice.invoice_id = privilege.object_id
    AND privilege.subject_id = <user_id>
    AND privilege.subject_type = <user_type>
WHERE privilege.read = TRUE;

在尝试 update 发票时适用相同的条件,但最后一个 WHERE 条件变为 WHERE privilege.write = true

实施

我可以使用Arel library 轻松创建这些约束。但是,我应该在哪里实现这些方法,以使所有 ActiveRecord 保存和更新操作都包含这些约束?

我不介意编写一些代码来启用它。我正在寻找有关如何最好地进行此操作的指针。

【问题讨论】:

    标签: mysql ruby-on-rails ruby activerecord authorization


    【解决方案1】:

    创建一个 gem 并在 ActiveRecord gem 之后需要它。在您的 gem 中打开 ActiveRecord 类并覆盖感兴趣的方法。

    module ActiveRecord
      class Base
    
        def save(*)
          if(authorised?)
            super
          else
            raise NotAuthorisedError.new("Your meaningful message!")
          end
        end
    
      end
    end
    

    Rails 源代码的原始代码位于Persistence class。所有持久化方法通常在内部使用create_or_update 方法。因此,您可能会考虑改写该方法。但是,您需要查看代码,看看这是否是个好主意。

    【讨论】:

    • 尽管这很有帮助,但我正在寻找更多 if that's a good idea 部分
    猜你喜欢
    • 1970-01-01
    • 2020-05-05
    • 2018-06-29
    • 1970-01-01
    • 2018-08-12
    • 2019-05-02
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    相关资源
    最近更新 更多