Search code examples
ruby-on-railsrails-activestorage

Rails 5.2: authorize access to ActiveStorage::BlobsController#show


I would like to authorize access to ActiveStorage attachments and looking at the source code of BlobsController (https://github.com/rails/rails/blob/master/activestorage/app/controllers/active_storage/blobs_controller.rb) is stated the following:

# Take a signed permanent reference for a blob and turn it into an expiring service URL for download.
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
# security-through-obscurity factor of the signed blob references, you'll need to implement your own
# authenticated redirection controller.
class ActiveStorage::BlobsController < ActiveStorage::BaseController
  include ActiveStorage::SetBlob

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

But even the notes above suggest to create a custom controller I would need also to override the routes generated by ActiveStorage, since they are pointing to the original controllers, and redefining them on my routes.rb seems to throw an exception. Also I don't want to expose these routes anymore as they are not being authorized and someone could take the signed_id of the blob and get the attachment using the original endpoint. Looping over the routes on the app initialization and deleting the old ActiveStorage routes and inserting the new ones seems the best solution for now, but I would like to avoid that.

Any suggestions? 🙄


Solution

  • Create a new controller to override the original: app/controllers/active_storage/blobs_controller.rb then add the authorization method accordingly with your needs:

    #app/controllers/active_storage/blobs_controller.rb
    class ActiveStorage::BlobsController < ActiveStorage::BaseController
      include ActiveStorage::SetBlob
    
      def show
        redirect_to @blob.service_url(disposition: params[:disposition])
        authorize! :show, @blob # NOT TESTED!
      end
    
    end
    

    The show action is triggered when you click on a link to the attachment.

    @blob.class #=> ActiveStorage::Blob