4

我用 Devise 和 CanCan 成功地制作了登录系统,我有 3 种类型的用户。管理员、内部和全球用户。我创建了控制器和索引操作:Admin、Cpanel、Report 和 State,并且我想限制某些用户对该控制器的访问。

管理员用户应具有访问权限:报告(全部)、状态(读取)、管理员(全部)

全局用户应具有访问权限:Reports(只读)、State(读取)、Cpanel(全部)

内部用户应具有访问权限:报告(全部)、状态(读取)

我尝试使用 ability.rs 中的以下代码来做到这一点

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, [Report, Admin]
      can :read, State
    elsif user.role? :global_user
      can :read, [Report, State]
      can :manage, Cpanel
    elsif user.role? :internal_user
      can :manage, Report
      can :read, State     
    end
   end
end

目前我在这个控制器中只有索引操作,当我使用内部用户登录到应用程序时,我可以访问 /admin 例如,这不是我想要的行为。我想限制对所有控制器的访问,而不是ability.rb 类中列出的控制器。

源代码在这里

4

3 回答 3

8

如果我要阻止对整个控制器的访问,我会制作一个 before 过滤器,如果他没有管理员角色,则将用户重定向到拒绝访问页面。可能看起来像:

def check_permissions
 raise CanCan::AccessDenied unless @current_user.role?(:admin)
end

例如,如果我只是想阻止访问更新和创建,我会这样做:

def update
  raise CanCan::AccessDenied unless can?(:update,Thing)
  ...
end

def create
  raise CanCan::AccessDenied unless can?(:create,Thing)
  ...
end

您可以CanCan::AccessDenied在应用程序控制器中处理异常:

rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to no_access_path
  end

我在这里这里有一些关于 CanCan 和 Devise 的不错的帖子

更新 我在我的应用程序控制器中使用这个方法来设置我当前的用户变量:

# Make the current user object available to views
  #----------------------------------------------------------------------------
  def get_user
    @current_user = session[:current_user]
  end
于 2011-03-02T04:29:13.953 回答
2

您需要为您的控制器添加对 cancan 授权的检查。

这可能只是添加一行

authorize! :read, @state

到您的状态控制器索引操作,对于所有其他索引操作也是如此。

编辑: 抱歉,在状态控制器索引操作中,您可能没有@state,因此上述内容不适用。可能像

authorize! :read, State

还有一种load_and_authorize方法可以用来组合控制器中多个操作的授权并减少代码。该load_and_authorize版本可能看起来类似于

load_and_authorize_resource :状态

它应该在你的行动之前。

您可能想查看关于 cancan 授权的这个 railscast 以获得完整的基本设置(在 rails2 中)。

我怀疑要解决其他问题,我们可能需要查看更多代码。尝试发布一些控制器代码。

我没有在 rails3 中使用过它,但我认为它的大部分或多或少是相似的。

于 2011-03-02T00:55:19.827 回答
0

我解决了这个问题

def check_permissions
 raise CanCan::AccessDenied unless current_user.role?(:admin)
end

但是,请注意,我必须更改@current_usercurrent_user(不带@)

谢谢托尼

于 2011-03-02T14:17:10.867 回答