2017-01-31 1 views
0

Wir suchen aus Erstellen neuer Ordner in unserem Eimer Root unsere S3 Benutzer zu verhindern. Mit anderen Worten, sie müssen vorhandene Ordner innerhalb des Buckets zum Hochladen oder Ändern von Dateien verwenden. Sie können wählen, Unterordner in diesen vorhandenen Ordnern zu erstellen, wenn sie möchten.Amazon S3-Politik Prevent Erstellung von Stammebene Folders

Hinweis: Die Verwendung S3 Richtlinien. Benutzer wählen einen vorhandenen Ordner. Sie haben keine zugewiesenen Ordner.

Ich weiß S3 beide Dateien und Ordner als Objekte behandelt, damit ich nicht sicher bin, kann dies auch getan werden, aber ich glaube an das Potenzial der Gemeinschaft.

Hier ist, was ich will:

Bucket-Name: Test-bucket

  • Aktion: Ordner erstellen in Test-Eimer Wurzel. Gewünschtes Ergebnis: verweigert

  • Aktion: Hochladen zufällige Datei in root-Test-Eimer. Gewünschtes Ergebnis: verweigert

  • Aktion: Datei hochladen "file1" im Test-Eimer bestehenden "folder1" Ordner (Test-Eimer/folder1/file1). Gewünschtes Ergebnis: Erfolg

  • Aktion: Ordner erstellen "Unter folder1" in bestehenden "folder1" Ordner (Test-Eimer/folder1/sub-folder1 /) Test-Eimer. Gewünschtes Ergebnis: Erfolg

Antwort

3

Es ist ein Fehler in Ihrem konzeptionellen Modell.

I S3 wissen behandelt beide Dateien und Ordner als

Objekte, die nicht korrekt ist.

Hier ist die richtige Version:

  • Die S3-Service und API haben kein Konzept von Ordnern.
  • S3-Objekte sind in keinem wirklichen Sinne hierarchisch.
  • Die S3-Konsole ist das einzige Unternehmen mit einem Konzept von Ordnern.
  • Die S3-Dienst und API-Unterstützung ein Konzept von Präfix, delimiter und gemeinsame Präfixe.

Wenn eine Liste Objekte anfordern an die API durch einen angegebenen Präfix begleitet wird, nur Objekte mit mit dem Präfix beginnen Schlüssel zurückgegeben werden, und zwar unabhängig von irgendeine / in ihrem Objektschlüssel nach dem Präfix.

Wenn eine Liste Objekte Anfrage einen Präfix begleitet wird und auch durch ein Trennzeichen (in der Regel /), gibt die API nur Objekte, deren Schlüssel entsprechen den gegebenen Präfix und, die keine nachfolgenden haben / (nach dem Präfix in der Anforderung angegeben) im Schlüssel. Diese sind analog zu den "Dateien im Ordner".

Die Präfixe der Tasten beliebiger Objekte die gegebene Präfix passende die aber tun, um eine nachfolgende haben (nach der angegebenen prefix) / werden auf eine eindeutige Liste ihrer Präfixe, abgestumpften zu ihrem nächsten / koalesziert unten. Dies sind die allgemeinen Präfixe, analog zu "Ordnern im Ordner".

Aber tatsächlich ist nichts wirklich "in" etwas anderes.

Die Konsole schafft eine Illusion von Ordnern durch die gemeinsamen Präfixe aus einer Liste zu lesen Objekte an die API anfordern, und diese als Ordner zeigt.

Die Konsole fördert die Illusion, indem Sie auf „Ordner erstellen“ - aber es ist nicht in der Tat ein Ordner, und es ist nicht einmal notwendig. Es ist einfach ein leeres Objekt mit einem Schlüssel, dessen letztes Zeichen / ist. Dieses Objekt wird nicht für den normalen Betrieb von S3 benötigt, sondern wird aus praktischen Gründen erstellt, so dass Sie "in" einen "leeren Ordner" navigieren und eine Datei "in" den leeren Ordner hochladen können.

Doch was ist wirklich passiert, ist dies:

Console: "create folder foo in the root of the bucket" 
API: PUT /foo/ 
    Content-Length: 0 

Console: "click folder foo" 
API: GET /?prefix=foo/&delimiter=/ 

Console: "upload file bar.txt inside folder foo" 
API: PUT /foo/bar.txt 

Nun ... wenn Sie einen leeren Eimer nehmen und verwenden Sie die API (nicht die Konsole), können Sie einfach PUT /foo/bar.txt und Sie bekommen genau das gleiche Nettoergebnis in der Konsole - Sie sehen einen Ordner namens "foo" mit "bar.txt." Der Ordner wird angezeigt da gibt es ein Objekt mit dem Präfix foo/. Löschen Sie das Objekt und der Ordner verschwindet. Umgekehrt, wenn Sie es von oben mit der Konsole gemacht haben, wäre nach dem Löschen von "bar.txt" immer noch der Ordner "foo", denn das ist wirklich nur ein leeres Objekt, dessen einziger Zweck darin besteht, dass ein Ordner erscheint in der Konsolennavigation, wenn keine anderen Objekte mit diesem gemeinsamen Präfix vorhanden sind.

Also, nein ... S3 behandelt nicht sowohl Dateien und Ordner als Objekte. Die S3 Konsole erstellt Objekte, die Ordner fälschen, ausschließlich als Navigationshilfe, und die Magie hier ist, dass der Schlüssel des Objekts mit / endet. Wenn diese leeren Objekte jedoch nicht vorhanden sind, zeigt die Konsole weiterhin Objekte an, als wären sie in Ordnern.

Sie sehen dann das Problem, das sich entwickelt. Der S3-Dienst kann nicht dazu aufgefordert werden, etwas zu testen, von dem es nichts weiß und das tatsächlich nicht existieren muss.

Also, es ist technisch nicht möglich genau das zu tun, was Sie gefragt haben; Es scheint jedoch eine begrenzte Problemumgehung zu geben. Die primäre Einschränkung besteht darin, dass Sie nicht angeben können, dass "der Ordner vorhanden sein muss", aber Sie können angeben "das Objektschlüsselpräfix muss mit einem vordefinierten Mustersatz übereinstimmen".

Der relevante Teil der Bucket- oder Benutzerrichtlinie sieht möglicherweise so aus ...

"Action": "s3:PutObject", 
    "Resource": [ 
     "arn:aws:s3:::examplebucket/taxdocuments/*", 
     "arn:aws:s3:::examplebucket/personnel/*", 
     "arn:aws:s3:::examplebucket/unicorns/*" 
     ... 
    ], 

Ein Benutzer von dieser Politik betroffen wäre in der Lage mit taxdocuments/oder Personal/oder Einhörnern/in dem „examplebucket“ bucket beginnt jedes Objekt zu erstellen, und würde ein Objekt nicht in der Lage sein, ohne dass einer von denen zu schaffen Präfixe. Darüber hinaus können Konsolenordner "in" Ordnern "in" Ordnern den ganzen Tag lang erstellt werden, solange eines dieser Präfixe am Anfang jedes Objektschlüssels eines gefälschten Ordners steht.

Die Einschränkung besteht natürlich darin, dass die Änderung der Richtlinie erforderlich ist, um einen anderen für den Zugriff geeigneten Ordner zu erstellen.

Dies könnte auch funktionieren, aber mit Vorsicht vorgehen:

"Resource": "arn:aws:s3:::examplebucket/?*/?*", 

Intuitiv scheint es, wie dies funktionieren könnte, aber der Fehler hier - die ?*/?* unter der Annahme gültig ist (it seems to be) und dass ? nicht 0 überein Zeichen die Art und Weise * tut - ist, dass dies einem Benutzer ermöglicht, einen neuen (Pseudo-) Ordner im Stamm zu erstellen, solange sie gleichzeitig etwas in ihm mit einem Namen mindestens ein Zeichen lang, unter Verwendung der API erstellen - das heißt Erstellen eines Objekts mit Schlüssel pics/cat.jpg "erstellt" den Ordner "Pics", wenn er nicht bereits vorhanden ist, wie oben beschrieben. Von der Konsole aus sollte diese die Erstellung neuer Ordner im Stamm verhindern, aber von der API würde keine solche Einschränkung auferlegt.

0

Vielen Dank für Ihre ausführliche Antwort @Michael. Sie haben absolut richtig gesagt, dass API- und CLI-Aufrufe weiterhin Root-Level-Ordner erstellen können, wenn sie nicht leer sind. Der Zugriff auf die Konsole und den S3-Browser funktioniert wie vorgesehen. Es ist ein Kompromiss, aber es kommt uns am nächsten, was wir erreichen können. Hier ist die Bucket-Richtlinie, die ich verwende:

{ 
    "Version": "2012-10-17", 
    "Id": "Policy1486492608325", 
    "Statement": [ 

    { 
     "Sid": "Stmt1486492495770", 
     "Effect": "Allow", 
     "Principal": { 
     "*" 
     }, 
     "Action": [ 
     "s3:DeleteObject", 
     "s3:Get*", 
     "s3:List*", 
     "s3:PutObject" 
     ], 
     "Resource": [ 
     "arn:aws:s3:::test-storage", 
     "arn:aws:s3:::test-storage/*" 
     ] 
    }, 
    { 
     "Sid": "Stmt1486492534643", 
     "Effect": "Deny", 
     "Principal": { 
     "*" 
     }, 
     "Action": [ 
     "s3:DeleteObject", 
     "s3:PutObject" 
     ], 
     "NotResource": "arn:aws:s3:::test-storage/?*/?*" 
    } 
    ] 
}