【问题标题】:Rails, Rackspace Cloud Files, Referrer ACLRails、Rackspace 云文件、引用者 ACL
【发布时间】:2010-10-26 03:05:37
【问题描述】:

我正在使用 Rackspace Cloud Files 作为我的应用程序的文件存储服务器。用户上传的文件必须从我的应用程序中获得授权,然后从控制器重定向到正确的 Rackspace 云文件 CDN URL。我正在尝试使用 Rackspace Cloud Files 的 Referrer ACL 进行授权。

所以让我添加一个非常简单的 sn-p 来阐明我想要完成的任务。

class FilesController < ApplicationController
  def download
    redirect_to(some_url_to_a_file_on_cloud_files_url)
  end
end

用户访问该下载操作的 URL 如下:

http://a-subdomain.domain.com/projects/:project_id/files/:file_id/download

因此,我使用 CloudFiles gem 设置了一个应该可以工作的 ACL Referrer 正则表达式。

http\:\/\/.+\.domain\.com\/projects\/\d+\/files\/\d+\/download

当用户单击 Web UI 中的链接时,它会将它们路由到上述 URL,并且根据参数,它会从下载操作将用户重定向到正确的 Rackspace Cloud Files 文件 URL。

好吧,我得到的是一个错误,说我未经授权(错误的 http 引用者)。我有一种预感,因为我正在执行从下载操作直接到云文件的重定向,它不会“算作”作为 HTTP 引荐来源网址,而不是使用此 URL 作为引荐来源网址,我认为它可能正在使用这个网址:

http\:\/\/.+\.domain\.com\/projects\/\d+\/files

由于这是您想要单击“下载”链接时所在的页面,它会将用户引导至 FilesController 中的下载操作。

当我将 Rackspace ACL 的 HTTP Referrer 设置为以下内容时:

http\:\/\/.+\.domain\.com\/projects\/\d+\/files

然后点击一个链接,我就被授权下载了。但是,这还不够安全,因为那时任何人都可以将例如 firebug 放入 html 并注入文件的原始链接并获得访问权限。

所以我想我的问题是,有没有人知道如何或为什么,我想要完成的工作不起作用,并且有任何建议/想法?正如我所说,我认为可能是当用户单击链接时,引用者被设置为单击文件的位置,而不是用户被重定向到云文件上的实际文件的 URL。

这样的事情可能吗?

class FilesController < ApplicationController
  def download
    # Dynamically set a HTTP Referrer here before
    # redirecting the user to the actual file on cloud files
    # so the user is authorized to download the file?
    redirect_to(some_url_to_a_file_on_cloud_files_url)
  end
end

非常感谢任何帮助和建议!

谢谢!

【问题讨论】:

  • 我实际上选择了 Amazon S3 而不是 Rackspace Cloud Files 有几个原因。但与上述主题相关的是,使用 Paperclip gem 在 Ruby on Rails 中向 Amazon S3 添加授权非常简单。基本上,您拥有的是一个私有存储桶,您使用 Paperclips expiring_url 方法为每次下载生成一个唯一密钥,并在几秒钟内将其过期。对上述问题的一个非常简单、快速和安全的解决方案。授权可以通过这种方式在应用层完成。

标签: ruby-on-rails acl cloudfiles rackspace-cloud


【解决方案1】:

一般来说,Micahel 的评论足以解释为什么 S3 在这个问题上排在机架空间之上,但如果您真的想在 Rackspace 请求中添加一些特殊的 HTTP 标头 - 执行您自己的 HTTP 请求并手动获取文件:

class DownloadsController < ApplicationController
   def download
     send_data HTTParty.get(some_url_to_a_file_on_cloud_files_url, :headers => {"x-special-headers" => "AWESOME" }), :file_name => "myfile.something"
   end
end

是的,您可以更好地编写此示例,但这是一般的想法。

【讨论】:

    【解决方案2】:

    虽然仍然没有“Referer”检查,但您可以使用当前版本的 Rackspace CloudFiles 创建temp urls(签名网址)。

    以下代码取自Rackspace documentation site

    require "openssl"
     unless ARGV.length == 4
     puts "Syntax: <method> <url> <seconds> <key>"
     puts ("Example: GET https://storage101.dfw1.clouddrive.com/v1/" +
     "MossoCloudFS_12345678-9abc-def0-1234-56789abcdef0/" +
     "container/path/to/object.file 60 my_shared_secret_key")
     else
     method, url, seconds, key = ARGV
     method = method.upcase
     base_url, object_path = url.split(/\/v1\//)
     object_path = '/v1/' + object_path
     seconds = seconds.to_i
     expires = (Time.now + seconds).to_i
     hmac_body = "#{method}\n#{expires}\n#{object_path}"
     sig = OpenSSL::HMAC.hexdigest("sha1", key, hmac_body)
     puts ("#{base_url}#{object_path}?" +
     "temp_url_sig=#{sig}&temp_url_expires=#{expires}")
     end
    

    【讨论】:

      猜你喜欢
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      相关资源
      最近更新 更多