2013-01-04 2 views
2

Je vais avoir un sacré moment pour que S3 accepte les envois via la requête CORS POST générée par PhoneGap (Cordova) FileTransfer.upload(). Toute suggestion sur ce que je pourrais manquer serait appréciée. Actuellement, j'obtiens une réponse 403 AccessDenied en utilisant le code ci-dessous. J'ai été à plusieurs reprises comparé à la documentation de S3, et ne peux pas comprendre le problème.Générer une signature CORS Amazon S3 avec Python

Voici le code Python qui génère la signature:

# Create policy document for S3. 
policy_obj = {"expiration": "2014-01-01T00:00:00Z", 
    "conditions": [ 
    {"bucket": "<my.bucket.name>"}, 
    ["starts-with", "$key", "story_"], 
    {"acl": "public-read"}, 
    ["eq", "$Content-Type", "audio/mp4"], 
    ["content-length-range", str(0), str(2097152)] 
    ] 
} 

policy = base64.b64encode(json.dumps(policy_obj)) 

# Create signature for S3 
signature = base64.b64encode(
    hmac.new(
     key=app.config['AWS_SECRET_KEY'], 
     msg=policy, 
     digestmod=hashlib.sha1 
    ).digest() 
) 

La signature générée par ce procédé correspond à la signature produite par S3 Signature Tester (convertissant la politique de base64 dans Hex puis de celle à travers l'appareil d'essai de signature avec le clef secrète).

La signature politique & résultant sont transmis au client, et la demande de S3 est construit avec cet appel PhoneGap FileTransfer:

// Upload file to Amazon S3 
// r is the response object generated by Python 
var options = new FileUploadOptions(); 
options.chunkedMode = false; 
options.mimeType="audio/mp4"; 
options.fileKey='file'; 
options.fileName='story_' + uniqueKey + '.m4a'; 
options.params={ 
    "key": "${filename}", 
    "acl": "public-read", 
    "AWSAccessKeyId": r.aws_access_key, 
    "Policy": r.policy, 
    "Signature": r.signature, 
}; 

var ft = new FileTransfer(); 
ft.upload(path, "http://<my.bucket.name>.s3.amazonaws.com/", uploadSuccess, uploadFail, options); 

Ceci est la configuration CORS (oui, je prévois de le verrouiller une fois Je reçois les ajouts de travail):

<?xml version="1.0" encoding="UTF-8"?> 
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
    <CORSRule> 
     <AllowedOrigin>*</AllowedOrigin> 
     <AllowedMethod>GET</AllowedMethod> 
     <AllowedMethod>POST</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 
</CORSConfiguration> 

Voici la politique du seau:

{ 
    "Version": "2008-10-17", 
    "Id": "Policy1356975063803", 
    "Statement": [ 
     { 
      "Sid": "Stmt1357234455973", 
      "Effect": "Allow", 
      "Principal": { 
       "AWS": "*" 
      }, 
      "Action": "s3:GetObject", 
      "Resource": "arn:aws:s3:::<my.bucket.name>/*" 
     }, 
     { 
      "Sid": "Stmt1356975061658", 
      "Effect": "Allow", 
      "Principal": { 
       "AWS": "arn:aws:iam::293855469575:root" 
      }, 
      "Action": "s3:*", 
      "Resource": "arn:aws:s3:::<my.bucket.name>" 
     } 
    ] 
} 

MISE À JOUR:

C'est ce que la politique elle-même ressemble après Python a converti l'objet en JSON:

{ 
    "conditions": [ 
    { 
     "bucket": "<my.bucket.name>" 
    }, 
    [ 
     "starts-with", 
     "$key", 
     "story_" 
    ], 
    { 
     "acl": "public-read" 
    }, 
    [ 
     "eq", 
     "$Content-Type", 
     "audio/mp4" 
    ], 
    [ 
     "content-length-range", 
     "0", 
     "6291456" 
    ] 
    ], 
    "expiration": "2014-01-01T00:00:00Z" 
} 
+0

Voici un script S3 pour Django, ne peut pas voir de différence significative entre ce qu'ils font et ce que je fais (j'ai essayé le paramètre 'indent = 2' sans chance): http://djangosnippets.org/snippets/2829/ – bjudson

Répondre

0

Avez-vous essayez de supprimer votre politique dans les nouvelles lignes?

Voici le code Ruby pour la politique, avec la permission de s3_file_upload:

Base64.encode64(policy_data.to_json).gsub("\n", "") 

S'il vous plaît laissez-moi savoir si vous avez réussi à obtenir votre téléchargement de travailler, comme je suis en train de faire la même chose.

+0

La fonction 'json.dumps()' que j'utilise ci-dessus génère la règle sans lignes par défaut. Je l'ai également essayé avec newlines (définissant le paramètre 'indent = 2'), j'ai essayé d'effacer les espaces avec' strip() ', et j'ai juste essayé de charger le document de politique à partir d'un fichier texte plutôt que de générer json depuis un objet. Chaque fois que je reçois une réponse 403. Si vous avez eu de la chance, faites le moi savoir ... – bjudson