3

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

因此,让我添加一个非常简单的片段来阐明我想要完成的工作。

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 云文件文件 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

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

谢谢!

4

2 回答 2

0

一般来说,Micahel 的评论足以解释为什么 S3 在这个问题上超过 rackspace,但是如果你真的想在你的 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

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

于 2012-08-13T16:26:38.667 回答
0

尽管仍然没有“Referer”检查,但您可以使用当前版本的 Rackspace CloudFiles创建临时 url (签名 url)。

以下代码取自Rackspace 文档站点

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
于 2013-05-29T04:49:08.687 回答