2010-10-09 15 views

Respuesta

51

que en realidad sólo implementado autorizado S3 url en mi Ruby on Rails 3 aplicación con Paperclip. Déjame compartir cómo lo logré.

Así que lo que hice, y lo que probablemente desee es bastante fácil de implementar. Déjeme darle un ejemplo:

FileObject modelo

has_attached_file :attachment, 
    :path   => "files/:id/:basename.:extension", 
    :storage  => :s3, 
    :s3_permissions => :private, 
    :s3_credentials => File.join(Rails.root, 'config', 's3.yml') 

FileObjectsController controlador

def download 
    @file_object = FileObject.find(params[:id]) 
    redirect_to(@file_object.attachment.expiring_url(10)) 
    end 

Creo que esto es bastante sencillo. Agregue el archivo adjunto Paperclip al modelo FileObject y luego realice una acción (descarga por ejemplo) en el FileObjectsController. De esta forma puede hacer alguna autorización de nivel de aplicación desde su controlador con un before_filter o algo así.

El expiring_url() método (proporcionado por Paperclip) en el @file_object.El archivo adjunto básicamente solicita a Amazon S3 una clave que hace que el archivo sea accesible con esa clave en particular. El primer argumento del métodoexpiring_url() toma un entero que representa la cantidad de segundos en el que desea que la URL proporcionada a punto de expirar.

En mi aplicación que está configurado para (@ file_object.attachment.expiring_url (10)) de modo que cuando el usuario solicita un archivo, el usuario siempre tiene que ir a través de mi aplicación en, por ejemplo, miaplicacion .com/file_objects/3/descarga para obtener una nueva dirección URL válida desde Amazon, que el usuario luego al instante va a utilizar para descargar el archivo ya que estamos utilizando el método deredirect_to en el descarga acción. Así que, básicamente, 10 segundos después de que el usuario pulsa el descarga acción, el enlace ya expirado y el usuario tiene (o sigue siendo) la descarga del archivo felizmente, mientras permanece protegido de cualquier usuario no autorizado.

Incluso he intentado fijar expiring_url (1) por lo que la URL caduca inmediatamente después de que el usuario activa la solicitud de Amazon S3 para la dirección URL. Esto funcionó para mí localmente, pero nunca lo usé en producción, puedes probarlo también. Sin embargo, lo configuré en 10 segundos para darle al servidor un corto período de tiempo para responder. Funciona muy bien hasta el momento y dudo que alguien pueda secuestrar la URL de alguien dentro de los 10 segundos posteriores a su creación, y mucho menos saber cuál es la URL.

medida de seguridad adicional Tomé es sólo para generar un clave secreta para cada archivo en crear lo que mi URL es siempre el siguiente aspecto:

has_attached_file :attachment, 
    :path => "files/:id/:secret_key/:basename.:extension" 

Para que cada URL tiene su única secret_key en Es ruta, por lo que es más difícil de secuestrar en el momento en que se puede acceder a la URL. Ten en cuenta que, mientras que la dirección URL de su archivo sigue siendo el mismo, la accesibilidad proviene de los parámetros adicionales que Amazon S3 proporciona que expiran:

http://s3.amazonaws.com/mybucket/files/f5039a57acc187b36c2d/my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D 

Aviso esta parte, que es la clave del Amazonas genera y caduca que hace que la archivo temporalmente accesible:

my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D 

De eso se trata. Y esto cambia con cada solicitud para su archivo si se solicita a través de la descarga acción.

Espero que esto ayude!

+1

Cuando intento este enfoque, todo lo que recibo es un archivo XML que incluye un código AccessDenied. ¿Algunas ideas? – Clay

+0

cómo sobre el estilo de manipulación (dimention) en el caso de la imagen –

+0

lo consiguió segundo param a expiring_url - https://github.com/thoughtbot/paperclip/blob/e60f00027704298455c039e111d96bcf46e12822/lib/paperclip/attachment.rb#L159 –

1

La manera más fácil de hacer esto es probablemente almacenar el archivo con un nombre aleatorio e indescifrable. Luego puede mostrar las URL a los usuarios en la Instancia A, pero los usuarios de la Instancia B no podrán adivinarlas.

No es seguridad a prueba de balas, pero es lo suficientemente bueno. Facebook, por ejemplo, usa este enfoque para las fotos de los usuarios.

+0

Gracias, eso es una idea interesante .. Las preocupaciones son que es más sensative que Facebook fotos. Además, los usuarios querrán descargar archivos, y tener un nombre loco podría no ser atractivo para el usuario. – AnApprentice

+0

re loca nombre: podría ser un camino loca lugar –

+0

no re seguridad a prueba de balas: Es bastante fácil de compartir una URL loca que no caduca. –

5

Usted podría intentar lo que se dice en esta página:

http://thewebfellas.com/blog/2009/8/29/protecting-your-paperclip-downloads

Los specficics están bajo la sección de "No más de streaming, tiempo para un cambio de dirección".

Resumen: S3 tiene cuatro políticas de acceso enlatados, mediante el uso de la política de lectura autenticado S3 proporciona una manera de generar una URL autenticado para contenidos privados que sólo funciona durante un período determinado de tiempo.

No he hecho esto, por favor avíseme si funciona para usted. :-)

(publicado en de mi respuesta aquí: AWS S3/Ruby on Rails/ heroku: Security hole in my app)

+0

+ 1 para las descargas protegidas en la aplicación integrada. La idea es que se asegure de que su contenido s3 es privado, entonces un usuario solicita el archivo de su aplicación, que genera un enlace de acceso limitado en el tiempo para S3, la URL se establece como un encabezado de contenido (xsendfile) en su respuesta de aplicaciones a su servidor web (nginx o apache recomendado) y el servidor web transmite el contenido al usuario, sin que los usuarios tengan que ver nada más que la url linda original haya definido para solicitar el archivo desde su aplicación. – Jeremy

Cuestiones relacionadas