【问题标题】:how to protect a send_file action with cancan如何使用 cancan 保护 send_file 操作
【发布时间】:2012-10-30 08:20:03
【问题描述】:

我似乎无法批准 web_videos_display 操作的授权。我可以使用skip_authorize_resource 使其工作,但是任何用户都可以通过知道:id 来访问文件的URL。我需要访问 asset 才能“查看”该文件。

感谢您对此进行调查。

assets_controller.rb

...
class AssetsController < ApplicationController

  load_and_authorize_resource :team
  load_and_authorize_resource :through => :team

  # skip_authorize_resource :only => [:web_videos_display, ...]
  # skip_authorize_resource :team, :only => [:web_videos_display, ...]
  ...
  def web_videos_display
    # @asset = Asset.find(params[:id]) #loaded by cancan
    @file = "#{Rails.root}#{@asset.webVideos.last.file}"
    send_file @file, :disposition => 'inline', :x_sendfile=>true
  end
  ...

routes.rb

  resources :teams, :path => '', :except => [:index] do
  ...
    resources :assets, :path => '' do
      ...
      get 'web_videos_display'
      ...
    end
  end

show.html.erb

...
<%= team_asset_web_videos_display_path(@team, @asset, :id => @asset.id, :team_id => @team.id) %>
...

ability.rb

...
can :read, Team, :memberships => {:id => user.membership_ids}
can :manage, Asset, :team => { :id => user.team_ids }
can :web_videos_display, Asset, :team => { :id => user.team_ids }
...

更新以响应@ryanb 评论

返回

1.9.2p318 :006 > ability.can?(:web_videos_display, asset)
  Team Load (0.2ms)  SELECT "teams".* FROM "teams" WHERE "teams"."id" = 1 LIMIT 1
 => true

但是

在开发模式下它仍然返回

Started GET "/video-pros/test-1/web_videos_display?id=10" for 127.0.0.1 at 2012-11-09 16:40:19 -0800
  Processing by AssetsController#web_videos_display as */*
  Parameters: {"id"=>"10", "team_id"=>"video-pros", "asset_id"=>"test-1"}
  Team Load (0.1ms)  SELECT "teams".* FROM "teams" WHERE "teams"."slug" = 'video-pros' LIMIT 1
  Team Load (0.2ms)  SELECT "teams".* FROM "teams" WHERE "teams"."admin_user_id" = 1 LIMIT 1
  CACHE (0.0ms)  SELECT "teams".* FROM "teams" WHERE "teams"."slug" = 'video-pros' LIMIT 1
Access denied on show #<Team id: 1, name: "Video Pros", email: nil, phone: nil, website: nil, slug: "video-pros", admin_user_id: 1, created_at: "2012-11-06 22:43:11", updated_at: "2012-11-06 22:43:11", payment_received: nil>
Redirected to http://0.0.0.0:3000/
Completed 302 Found in 73ms>

谢谢瑞恩

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 cancan sendfile x-sendfile


    【解决方案1】:

    send_file 不应该有所作为,因为授权发生在触发操作之前的 before_filter 中。据我所知,它看起来是正确的,所以可能还有其他事情发生。你试过浏览这个debugging 页面吗?如果您在控制台中模仿控制器授权所做的事情会发生什么?

    user = User.first # fetch any user you want to test abilities on
    team = Team.first # any model you want to test against
    asset = team.assets.first
    ability = Ability.new(user)
    ability.can?(:show, team) # see if it allows access
    ability.can?(:web_videos_display, asset) # see if it allows access
    

    :read 更新为:show 团队操作

    【讨论】:

    • 我用控制台和终端的输出更新了原来的
    • 它似乎拒绝访问父团队记录。确保它也可以在控制台中使用:ability.can?(:show, team)
    • 为了澄清,load_and_authorize_resource :team 行将添加一个前置过滤器来授权父记录。如果你不想这样,你可以改用load_resource :team
    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多