動機慘慘check_authorization不扔存取遭拒例外非REST風格的控制器
我試圖在其中一個控制器不與資源相關的應用程序使用慘慘 - 非REST風格的控制器。我希望該控制器的操作能夠根據其他資源和會話參數進行有條件授權。
背景
The CanCanCan documentation for Non RESTful controllers指出
因爲 沒有資源來加載你不應該使用load_and_authorize_resource方法。相反,您可以致電授權!分別在每個動作 中。
這不應該是一個問題,反正在理論上我應該鎖定下來,並確保授權加入check_authorization
我ApplicationController
發生在我的應用程序的每一個動作。據the CanCanCan documentation:
如果授權不在 行動執行這將引發異常。
問題
我遇到的問題是,check_authorization似乎並沒有被鎖定非REST風格的控制器的操作。不聲明授權的行爲!正在執行而不會引發任何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:酒吧授權:
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
方法 - 考慮到new
操作不應調用authorize!
方法,您會期望其中一個操作與show
操作具有相同的行爲。
我很欣賞這種努力,但它如何工作?你建議,而不是授權!我調用'before_action:check_authorization',然後會引發'CanCan :: AccessDenied'異常......使我無法授權該操作。 – David
'raise'行末尾有一個'if'。在'ability.rb'裏面用'can'或'cannot'列出你需要的所有權限,然後,當一個具有'check_authorization'作爲前兆的動作被調用時,如果權限確實會引發'AccessDenied'不存在於'ability.rb'中,否則它會進展得很好。我還注意到,在你的所有行爲中,你都會在'authorize!'上面調用同一對'action'和'class'。不同的行爲不應該是不同的嗎?另外'action'是第一部分,'class'是所有'authorize!'的第二部分。 CanCan'文檔清楚地解釋了所有這些。 –
啊我現在完全理解你在做什麼,謝謝你的明確解釋。不幸的是,我不認爲我可以以這種方式使用這些能力,因爲我沒有使用資源。對於RESTful操作,您可以爲有效地使授權有條件的能力提供一些範圍 - 例如, 'can:read,Product,organisation_id:@ user.organisation_id'。這就是爲什麼我在行動本身內有條件地授權 - 我可能已經過分簡化了我的MCVE,並沒有足夠清楚。你的意見雖然有價值,並提供了更多的清晰度,所以我會upvote。 – David