【发布时间】:2016-11-10 00:09:02
【问题描述】:
动机
我正在尝试在其中一个控制器未与资源关联的应用程序中使用 CanCan - 非 RESTful 控制器。我希望根据其他资源和会话参数有条件地授权该控制器的操作。
背景
The CanCanCan documentation for Non RESTful controllers 声明
你不应该使用 load_and_authorize_resource 方法,因为那里 没有要加载的资源。相反,您可以致电授权!在每一个动作 分开。
无论如何这不应该是一个问题,因为理论上我应该将其锁定并通过将check_authorization 添加到我的ApplicationController 来确保我的应用程序中的每个操作都发生授权。根据the CanCanCan documentation:
如果授权未在 行动。
问题
我遇到的问题是 check_authorization 似乎没有锁定非 RESTful 控制器的操作。未声明授权的操作!正在执行而不引发任何 AccessDenied 异常。
下面是代表我正在做的事情的 MCVE。我做错了什么还是我发现了一个错误?这样做的“正确”方法是什么?
实施
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
check_authorization
def current_user
Object.new
end
protected
rescue_from CanCan::AccessDenied do |exception|
puts "CanCan::AccessDenied Exception thrown : message=#{exception.message}"
end
end
在我的控制器中,我尝试手动授权,但前提是满足某些条件:
class FooController < ApplicationController
def new
authorize! :foo, :bar, unless: true
puts 'FooController#new'
end
def index
authorize! :foo, :bar, if: true
puts 'FooController#index'
end
def show
puts 'FooController#show'
end
end
以及启用 :foo :bar 授权的 Ability 类:
class Ability
include CanCan::Ability
def initialize(user)
puts 'CanCan::Ability#initialise'
can :foo, :bar
end
end
在 Rails 控制台中生成的输出:
2.3.0 :001 > app.get '/foo/new'
CanCan::Ability#initialise
FooController#new
2.3.0 :002 > app.get '/foo'
CanCan::Ability#initialise
FooController#index
2.3.0 :001 > app.get '/foo/1'
FooController#show
请注意,show 操作甚至没有 authorize! 声明,但仍允许执行而不会引发异常。
另外,我不明白的是,Ability#initialize 根本没有调用 show 操作。让我更加困惑的是——new 和 index 都调用了 Ability#initialize 方法——你会期望其中一个具有与 show 操作相同的行为,因为 new 操作应该不要调用authorize! 方法。
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 cancan cancancan