如何为不同的用户类型创建基于规则的访问控制单元

How to create a rule-based access control unit for different user types

我正在尝试为我的应用实施基于角色的访问控制单元,但由于我的限制不知道如何去做。

我使用 Devise 进行签名 in/up 操作。我只有一个模型用户,但每个用户都有不同的 user_type。我有八种具有不同身份验证级别(整数)的独特用户类型。

这些是对用户与网站交互方式的限制:

  1. 具有较高身份验证级别的用户可以执行具有较低身份验证级别功能的相关用户类型,即访问其相关控制器并执行操作。

  2. 并非每个具有相同身份验证级别的用户类型都可以访问相同的控制器:user1auth_level = 2 可以访问控制器 C1user2auth_level = 2可以访问控制器C2。换句话说,他们在同一级别从事不同的工作。

  3. 有没有gem实现这样的东西?我调查了 CanCan 它不能满足我的需求。

  4. 如果没有gem,你建议如何approach/design实现这样的访问控制单元?

我建议您使用路由约束 (http://guides.rubyonrails.org/routing.html#advanced-constraints) 来实现控制器访问。

使用request.env["warden"].authenticate,您可以在约束class 中的matches? 方法内对当前用户的请求进行身份验证。如果您使用 request.env["warden"].authenticate!,您甚至会将用户重定向到登录页面,或显示适当的错误消息(取决于您的设置)。

自从几天前我问了这个问题以来,有一段时间我想知道并评估可用的 gems,适合我的目的但我找不到任何 simpleeasy-to-uselightweight 足以将其导入我的应用程序;所以我接受了这场斗争并写了我自己的 gem 命名为 ACU (Access Control Unit),它满足了我在问题中的限制 + 它非常轻巧,易于使用并且适用于任何目的。

在这个gem中,每个请求要么通过要么不通过,访问规则可以涵盖rails应用程序的任何方面。以下是规则集的示例,有关更多详细信息,请参阅 here.

提供的文档
# config/initializers/acu_rules.rb
Acu::Rules.define do
  # anyone makes a request could be count as everyone!
  whois :everyone { true }

  whois :admin, args: [:user] { |c| c and c.user_type == :ADMIN.to_s }

  whois :client, args: [:user] { |c| c and c.user_type == :CLIENT.to_s }

  # any request that doesn't match with a rule will be denied by default; 
  # but this can be configured to not to!

  # the default namespace
  namespace do
    controller :home, except: [:some_secret_action] do
      allow :everyone
    end
    controller :home do
      allow [:admin, :client], on: [:some_secret_action]
    end
  end

  # the admin namespace
  namespace :admin do
    allow :admin

    controller :contact, only: [:send_message] do
      allow :everyone
    end

    controller :contact do
      action :support {
        allow :client
      }
    end
  end
end