CanCan不应该阻止访问

时间:2012-10-12 13:28:49

标签: ruby-on-rails ruby authorization cancan

当我以不同用户身份登录时访问users/1/edit不会引发AccessDenied错误,我不明白为什么:

  authorize_resource only: [:edit, :update]
  def edit
    @user = User.find(params[:id])
  end
  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to @user
    else
      render 'edit'
    end
  end

能力等级:

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new

    can :read, :all
    can :create, User
    can :create, Group

    can :update, User, id: user.id
  end
end

如果我将authorize_resource更改为load_and_authorize_resource,那么它会按预期工作。但这当然不应该是相关的吗?

4 个答案:

答案 0 :(得分:1)

您的代码仅授权用户访问编辑和更新操作,而不是@user对象

你必须像这样手动授权对象

试试这个,

def edit
  @user = User.find(params[:id])
  authorize! :update, @user
end

def update
  @user = User.find(params[:id])
  authorize! :update, @user
  if @user.update_attributes(params[:user])
   redirect_to @user
  else
   render 'edit'
  end
end

答案 1 :(得分:1)

我面临着和你一样的问题,但对我而言,我正在使用cancan设计。因此,在我的控制器中,我会把

 before_filter :authenticate_user!, :except=>[:create]

除了创建之外,它将对用户进行身份验证。

def index
    @user = User.all
    authorize! :index, @user
    respond_to do |format|
       format.html # index.html.erb
       format.xml  { render :xml => @user }
    end
end

您想要授权用户访问的每个控制器功能,您可以这样做,似乎您必须通过将每个单独放在您需要授权的函数中而不是仅使用load_and_authorize_resource来执行大量工作,但希望可以帮助你完成我所做的一切。这是资源:https://github.com/ryanb/cancan/wiki/authorizing-controller-actions。如果您得到答案以及load_and_authorize_resource无法正常工作的原因,请发布到此处:)

答案 2 :(得分:1)

我(还)没有给出答案为什么会发生这种情况,但我遇到了同样的问题。我的情况不同之处在于手动授权每个操作(而不是依赖于“授权资源”或“load_and_authorize”)是关键。

答案 3 :(得分:1)

我也遇到了这个问题,这就是我找到的。

If I'm reading the source code right,在:update操作期间,load_and_authorize执行find_by加载资源,然后在其上调用authorize!。但是,在应用传入参数后,我看不到它授权的位置。 (如果我读错了,请有人纠正我。)

我看到的用例是当有人编辑资源时,在编辑中更新资源中的值,使其不再有资格在保存时传递授权。 (当然,我正在设置UI以帮助避免这种情况,但显然我仍然希望保护资源。)运行功能测试,我能够设置我希望不在控制器上传递授权的属性{{1动作,大概是因为检查发生在解析属性之前。

到目前为止,我处理它的方法是在设置属性后再次调用:update,这意味着我无法使用authorize!,因为我想在保存前进行授权:< / p>

update_attributes

另一种方法是创建一个before_filter,自己加载class FooController < ApplicationControlller load_and_authorize_resource def update # slurp the mass assignable params @foo.attributes = params[:foo] # set some other params @foo.some_other_attr = 'bar' # authorize again, now that we have updated the params authorize! :update, @foo if @foo.save! flash[:notice] = I18n.t(...) respond_with(@foo) # ... end end end 实例,然后按上面的方式调用authorize,但这并没有让事情变得更清晰,恕我直言。它只会保存一个授权!调用

我很好奇其他人如何处理这件事。我对CanCan很新,所以我假设我做错了什么。 :)