【问题标题】:How do I add permissions to ActiveStorage?如何向 ActiveStorage 添加权限?
【发布时间】:2019-12-13 15:11:18
【问题描述】:

我正在迁移到 ActiveStorage 一个权限敏感的应用程序。我需要确保只有具有权限的人才能访问文件,并且这些权限仅持续指定的时间段。

使用 Paperclip,这就像使用专家授权调用定义路由一样简单:

def thumbnail
    authorize @record
    redirect_to @record.thumbnail.expiring_url(300)
end

/record/thumbnail 的任何调用都将由设计人员进行身份验证,由权威人士授权,然后重定向到带有过期网址的 S3。这是一个行之有效的过程。

转移到 ActiveStorage,我最初的想法是我会使用 service_url,但它只在我使用 S3 时才有效——它在测试中不起作用,如果我在本地也不起作用使用磁盘服务进行开发。实际的“正确”方法是使用url_for,或者在上面的示例中使用redirect_to url_for @record.thumbnail

问题是,url_for 似乎发出了一个永久 url——它生成的 url 对任何人都是有效的,无需身份验证或授权。更重要的是,一旦有人有了那个网址,我就不能撤销它,我不能说它只能维持一个星期。一旦有人拥有该网址,他们就可以永远访问该文件。 (或者,可能至少在文件更新之前)。

我不认为这是一个巨大的安全漏洞,但与使用 Paperclip 所能实现的相比,这绝对是一个倒退。我是否遗漏了一个重要的细节,或者这真的是 ActiveStorage 的全部功能吗?

【问题讨论】:

  • 我很困惑,当我使用 image_tag(@record.thumbnail) 或 image_tag(url_for(@record.thumbnail) 时,我得到一个只持续几分钟的 url 重定向。你做了什么获得永久网址?每当我尝试时,我只能得到持续几分钟且无法缓存或与 CDN 一起使用的内容永久网址可能对你来说是个问题,但它是包括我在内的很多人的解决方案。你有不小心找到了解决我们问题的方法?
  • @JohnSmall 不知道。可能是版本问题?也许链接没有我想的那么好(尽管这应该会导致我们的一些应用程序出现问题,这些应用程序需要链接长时间保持有效,以便他们可以重新连接下载)

标签: rails-activestorage


【解决方案1】:

文档说:

如果您需要在已签名 blob 引用的隐匿性安全因素之外实施访问保护,则需要实现自己的经过身份验证的重定向控制器。

这不是特别有用。为此,您需要创建自己的控制器来为 blob 提供服务:

class BlobsController < ApplicationController
  include ActiveStorage::SetBlob
  before_action :authorize_blob

  def show
    expires_in ActiveStorage::Blob.service.url_expires_in
    redirect_to @blob.service_url(disposition: params[:disposition])
  end

  private

  def authorize_blob
    # Your authorization code goes here
  end
end

然后你需要设置你的路由:

  get '/blobs/:signed_id/*filename' => "blobs#show", as: "service_blob"
  direct :blob do |blob, options|
    route_for(:service_blob, blob.signed_id, blob.filename, options)
  end
  resolve("ActiveStorage::Blob") { |blob, options| route_for(:blob, blob, options) }  

最后,您需要禁用不安全的默认控制器,以便知识渊博的用户无法绕过您的授权。

如果您使用的是 Rails 6.1+,您可以通过在 application.rb 中将 config.active_storage.draw_routes 设置为 false 来完成此操作。但是您需要确保其余的 ActiveStorage 路由是手动绘制的,并且其中有很多。你可以view them on Github

否则,您将需要添加扩展控制器以重定向到您的新控制器(或完全关闭它)。您可以将以下内容添加到初始化程序中:

module ActiveStorageRedirect
  def self.included(controller)
    controller.before_action :redirect_to_authenticated
  end

  private

  def redirect_to_authenticated
    redirect_to Rails.application.routes.url_helpers.blob_path(@blob)
  end
end

ActiveStorage::Blobs::RedirectController.include(ActiveStorageRedirect) # For Rails >= 6.1
ActiveStorage::Blobs::ProxyController.include(ActiveStorageRedirect) # For Rails >= 6.1
# ActiveStorage::BlobsController.include(ActiveStorageRedirect) # For Rails < 6.1

【讨论】:

  • 感谢您的回答。我会将其标记为已接受,但我无法对其进行测试——新工作,不再有权访问与此相关的项目。
猜你喜欢
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-18
  • 2020-08-13
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多