简体   繁体   English

不能阻止访问

[英]CanCan not preventing access when it should

Visiting users/1/edit when I'm signed in as different user does not raise an AccessDenied error, and I have no idea why: 当我以其他用户身份登录时访问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

Ability class: 能力等级:

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

If I change authorize_resource to load_and_authorize_resource then it works as expected. 如果我将authorize_resource更改为load_and_authorize_resource则它将按预期工作。 But this should not be relevant, surely? 但这肯定不相关吗?

Your code only authorize the user to access edit and update action not the @user object 您的代码仅授权用户访问编辑和更新操作,而不授权@user对象

you have to manually authorize the object like this 您必须像这样手动授权对象

Try this, 尝试这个,

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

I'm facing the same issues like you,but for me,I'm using devise with cancan. 我面临着和您一样的问题,但对我来说,我正在使用康康设计。 Therefore ,in my controller, i will put 因此,在我的控制器中,我将

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

it will authenticate user except the 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

each of your controller function that you want to authorize the access of user, you can do like this, it seems you have to do lots of works by putting every single in the function that you need to authorize instead just using load_and_authorize_resource, but hope can help ua little from what i have completed. 您想要授权用户访问权限的每个控制器功能,您都可以这样做,看来您需要做很多工作,只需将每一个控制器放入需要授权的功能中,而不是仅使用load_and_authorize_resource,但是希望可以从我已经完成的工作中得到一点帮助。 here is the resource:https://github.com/ryanb/cancan/wiki/authorizing-controller-actions. 这是资源:https://github.com/ryanb/cancan/wiki/authorizing-controller-actions。 If you get an answer and why the load_and_authorize_resource is not working, post to here too :) 如果您得到答案以及为什么load_and_authorize_resource无法正常工作,也可以在此处发布:)

I don't have an answer for you (yet) on why this happens, but I encountered essentially the same issue. 我还没有答案(到目前为止)为什么会发生这种情况,但是我遇到了基本上相同的问题。 My situation was only different in that manually authorizing each action (instead of relying on either "authorize resource" or "load_and_authorize" was the key. 我的情况与众不同之处仅在于手动授权每个操作(而不是依赖“授权资源”或“ load_and_authorize”是关键)。

I am running into this issue as well, and here is what I have found. 我也遇到了这个问题,这就是我所发现的。

If I'm reading the source code right , during an :update action, load_and_authorize does a find_by to load the resource, then calls authorize! 如果我:update动作中正确读取源代码 ,则load_and_authorize执行find_by加载资源,然后调用authorize! on it. 在上面。 However, I don't see where it authorizes it after the incoming parameters have been applied. 但是,在应用了传入参数之后,我看不到它在哪里对其进行授权。 (Someone please correct me if I'm reading this wrong.) (如果我读错了,请纠正我。)

The use case I am seeing this is when someone edits a resource, and in the edit, updates a value in the resource that makes it no longer eligible to pass authorization on save. 我看到的用例是某人编辑资源,然后在编辑中更新资源中的值,使其不再有资格在保存时通过授权。 (Granted, I am setting up the UI to help avoid this situation, but obviously I still want to protect the resource.) Running a functional test, I was able to set attributes that I expected not to pass authorization on the controller :update action, presumably because the check happens before the attributes are parsed. (当然,我正在设置UI来帮助避免这种情况,但是显然我仍然想保护资源。)运行功能测试,我能够设置我希望不通过控制器授权的属性:update操作,大概是因为检查是在解析属性之前进行的。

So far, the way I have worked around it is to call authorize! 到目前为止,我解决该问题的方法是调用authorize! again after I have set the attributes, which means I can't use update_attributes since I want to authorize before saving: 设置属性后再次出现,这意味着我不能使用update_attributes因为我要在保存之前进行授权:

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

An alternative is to create a before_filter, load the @foo instance yourself, then call authorize as above, but that doesn't really make things much cleaner, IMHO. 一种替代方法是创建一个before_filter,自己加载@foo实例,然后按上述方式调用authorize,但这实际上并不能使事情变得更加整洁,恕我直言。 It would just save on one authorize! 这将节省一个授权! call. 呼叫。

I'm curious as to how others are handling this. 我对其他人如何处理此事感到好奇。 I am fairly new to CanCan, so I am presuming I am doing something wrong. 我是CanCan的新手,所以我想我做错了什么。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM