Pere Joan Martorell
Pere Joan Martorell

Reputation: 3152

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? 🙄

Upvotes: 3

Views: 1559

Answers (1)

iGian
iGian

Reputation: 11193

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

Upvotes: 2

Related Questions