2010-10-26 109 views
3

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

因此,让我只是添加一个非常简单的片段,以澄清我想要完成的事情。

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

用户将访问的网址去下载这个行动是以下几点:

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

所以与CloudFiles宝石,我设置了一个ACL引荐正则表达式应该工作。

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

当用户单击Web UI中的链接,其路由他们到上述网址,并根据这些参数,它将从下载操作将用户重定向到正确的Rackspace的云文件的文件URL。

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

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

因为这是你的页面是当你要点击“下载”链接,引导用户在FilesController下载行动。

当我设置HTTP推荐为Rackspace公司ACL,只是这样的:

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

然后点击一个链接,我被授权下载。然而,这是不够安全的,因为任何人都可以例如只是firebug到HTML并注入原始链接到文件并获得访问权限。

所以我想我的问题是,有没有人有任何线索如何或为什么,我试图完成的是不工作,并有任何建议/想法?正如我所说,我认为可能是当用户点击链接时,引用者被设置为文件被点击的位置,而不是用户被重定向到云文件实际文件的网址。

是这样的可能吗?

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 

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

谢谢!

+1

由于几个原因,我实际上使用Amazon S3而不是Rackspace Cloud Files。但是与上述主题相关的是,使用Paperclip gem在Ruby on Rails中添加对Amazon S3的授权非常简单。基本上你所拥有的是一个私人存储桶,你使用Paperclips__expiring_url__方法为每次下载生成一个唯一的密钥,并在几秒钟内过期。上述问题的一个非常简单,快速和安全的解决方案。授权可以在应用程序层完成。 – 2010-10-31 10:51:42

回答

0

一般来说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 

是的,你可以更好地编写这个例子,但它是一般的想法。

0

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

以下代码摘自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