2010-10-09 8 views

Antwort

51

ich eigentlich nur S3 URLs in meinem Ruby-autorisierten implementiert on Rails 3 Anwendung mit Paperclip. Lass mich erzählen, wie ich das geschafft habe.

Also was ich getan habe, und was Sie wahrscheinlich wollen, ist ziemlich einfach zu implementieren. Lassen Sie mich Ihnen ein Beispiel geben:

Fileobject Modell

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

FileObjectsController Controller

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

Ich glaube, das ganz einfach. Sie fügen den Paperclip-Anhang dem FileObject Modell hinzu und haben dann eine Aktion (download zum Beispiel) in dem FileObjectsController. Auf diese Weise können Sie eine bestimmte Berechtigung auf Anwendungsebene in Ihrem Controller mit einer before_filter oder so etwas tun.

Die expiring_url() Methode (bereitgestellt von Papierklammer) auf dem @file_object.Anhang fordert im Grunde Amazon S3 für einen Schlüssel, der die Datei mit diesem bestimmten Schlüssel zugänglich macht. Das erste Argument der Methode expiring_url() verwendet eine Ganzzahl, die die Anzahl der Sekunden angibt, in denen die angegebene URL ablaufen soll.

In meiner Anwendung ist es derzeit auf (@ file_object.attachment.expiring_url (10)) so, wenn der Benutzer eine Datei anfordert, immer der Benutzer durch meine Anwendung gehen, hat zum Beispiel myapp .com/file_objects/3/download um eine neue gültige URL von Amazon zu erhalten, die der Benutzer dann sofort zum Herunterladen der Datei verwendet, da wir die redirect_to Methode in der download Aktion verwenden. Im Grunde 10 Sekunden nachdem der Benutzer die Aktion herunterlädt, ist die Verbindung bereits abgelaufen und der Benutzer hat die Datei (oder lädt sie noch) glücklich herunter, während sie vor nicht autorisierten Benutzern geschützt bleibt.

Ich habe sogar versucht, expiring_url (1) zu setzen, so dass die URL sofort abläuft, nachdem der Benutzer die Amazon S3-Anforderung für die URL auslöst. Dies funktionierte für mich lokal, aber nie in der Produktion, Sie können das auch versuchen. Allerdings habe ich es auf 10 Sekunden eingestellt, um dem Server eine kurze Zeit zu geben, um zu antworten. Funktioniert soweit großartig und ich bezweifle, dass irgendjemand jemandes URL innerhalb von 10 Sekunden nach seiner Erstellung entführen wird, geschweige denn, was die URL ist.

zusätzliche Sicherheitsmaßnahme I nahm nur auf schaffen so geheimen Schlüssel für jede Datei zu erzeugen, meine URL immer so aussehen ist:

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

Damit jede URL eindeutig hat es secret_key drin ist Pfad, wodurch es schwieriger wird, innerhalb der Zeit, in der die URL zugänglich ist, zu entführen. Wohlgemerkt, dass, während die URL Ihrer Datei gleich bleibt, die Zugänglichkeit von den zusätzlichen Parameter kommt, die Amazon S3 bietet die verfallen:

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

Hinweis Dieser Teil, der der Schlüssel Amazon erzeugt und endet, welche die macht temporär zugängliche Datei:

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

Das ist worum es geht. Und dies ändert sich mit jeder Anfrage für Ihre Datei, wenn dies über die Download Aktion angefordert wird.

Hoffe, das hilft!

+1

Wenn ich diesen Ansatz versuche, ist alles, was ich zurück erhalte, eine XML-Datei, die einen AccessDenied-Code auflistet. Irgendwelche Ideen? – Clay

+0

Wie wäre es mit der Handhabung Stil (Dimention) im Falle von Bild –

+0

habe es 2. Param zu ablaufende_url - https://github.com/thoughtbot/paperclip/blob/e60f00027704298455c039e111d96bcf46e12822/lib/paperclip/attachment.rb#L159 –

1

Der einfachste Weg, dies zu tun, ist wahrscheinlich, die Datei mit einem zufälligen, nicht zu entdeckenden Namen zu speichern. Dann können Sie die URLs den Benutzern in Instanz A anzeigen, aber die Benutzer von Instanz B können sie nicht erraten.

Es ist keine kugelsichere Sicherheit, aber es ist gut genug. Facebook verwendet diesen Ansatz beispielsweise für Benutzerfotos.

+0

Danke, das ist eine interessante Idee .. Bedenken sind es sensativer als Facebook-Fotos. Auch Benutzer möchten Dateien herunterladen, und ein verrückter Name ist für den Benutzer möglicherweise nicht attraktiv. – AnApprentice

+0

Re verrückter Name: könnte ein verrückter Pfad stattdessen –

+0

sein re nicht kugelsicher Sicherheit: Es ist einfach genug, eine verrückte URL zu teilen, die nicht abläuft. –

5

Sie könnten versuchen, was auf dieser Seite gesagt wird:

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

Die specficics sind unter dem Abschnitt „Nicht mehr Streaming, Zeit für eine Umleitung“.

Zusammenfassung: S3 verfügt über vier vordefinierte Zugriffsrichtlinien, indem die authenticated-read-Richtlinie verwendet wird S3 bietet eine Möglichkeit zum Generieren einer authentifizierten URL für private Inhalte, die nur für einen bestimmten Zeitraum ausgeführt werden.

Ich habe das eigentlich nicht gemacht, also lass es mich wissen, wenn es für dich funktioniert. :-)

(aus meiner Antwort reposted hier: AWS S3/Ruby on Rails/ heroku: Security hole in my app)

+0

+ 1 für die in App geschützten Downloads. Die Idee ist, dass Sie sicherstellen, dass Ihr s3-Inhalt privat ist, dann fordert ein Benutzer die Datei von Ihrer App an, die einen zeitbegrenzten Zugriffslink für S3 generiert, die URL wird als Inhaltsheader (xsendfile) in Ihrer Apps-Antwort auf Ihre festgelegt Webserver (Nginx oder Apache empfohlen) und der Webserver streamt den Inhalt an den Benutzer, ohne dass die Benutzer etwas anderes sehen müssen, als die originale, hübsche URL, um die Datei von Ihrer App anzufordern. – Jeremy

Verwandte Themen