Sto provando a caricare un file con Amazon Java SDK, tramite caricamento multipart. L'idea è di passare un id di caricamento a un'applet, che mette le parti del file in un bucket di sola lettura. Andando in questo modo, evito di memorizzare le credenziali AWS nell'applet.Metti il file su Amazon S3 usando il caricamento multipart
Nei miei test, genera un id di caricamento con boto (python) e memorizza un file nel bucket. Funziona bene
L'applet riceve un "403 accesso negato" dall'S3 e non ho idea del perché.
Ecco il mio codice (che è parzialmente tratto da http://docs.amazonwebservices.com/AmazonS3/latest/dev/llJavaUploadFile.html):
AmazonS3 s3Client = new AmazonS3Client();
List<PartETag> partETags = new ArrayList<PartETag>();
long contentLength = file.length();
long partSize = Config.getInstance().getInt("part_size");
String bucketName = Config.getInstance().getString("bucket");
String keyName = "mykey";
String uploadId = getParameter("upload_id");
try {
long filePosition = 0;
for (int i = 1; filePosition < contentLength; i++) {
partSize = Math.min(partSize, (contentLength - filePosition));
// Create request to upload a part.
UploadPartRequest uploadRequest = new UploadPartRequest()
.withBucketName(bucket).withKey(keyName)
.withUploadId(uploadId).withPartNumber(i)
.withFileOffset(filePosition)
.withFile(file)
.withPartSize(partSize);
// Upload part and add response to our list.
partETags.add(s3Client.uploadPart(uploadRequest).getPartETag());
filePosition += partSize;
}
System.out.println("Completing upload");
CompleteMultipartUploadRequest compRequest = new
CompleteMultipartUploadRequest(bucket,
keyName,
uploadId,
partETags);
s3Client.completeMultipartUpload(compRequest);
} catch (Exception e) {
s3Client.abortMultipartUpload(new AbortMultipartUploadRequest(
bucketName, keyName, uploadId));
}
Nel registro applet di debug, ho trovato questo, quindi:
INFO: Sending Request: PUT https://mybucket.s3.amazonaws.com /mykey Parameters: (uploadId: V4hwobOLQ1rYof54zRW0pfk2EfhN7B0fpMJTOpHOcmaUl8k_ejSo_znPI540.lpO.ZO.bGjh.3cx8a12ZMODfA--, partNumber: 1,) Headers: (Content-Length: 4288546, Content-Type: application/x-www-form-urlencoded; charset=utf-8,)
24.01.2012 16:48:42 com.amazonaws.http.AmazonHttpClient handleErrorResponse
INFO: Received error response: Status Code: 403, AWS Service: null, AWS Request ID: DECF32CCFEE9EBF0, AWS Error Code: AccessDenied, AWS Error Message: Access Denied, S3 Extended Request ID: xtL1ixsGM2/vsxJ+cZRHpkPZ23SMfP8hZZjQCQnp8oWGwdS2/aGfYgomihyqaDCQ
si fa a trovare eventuali errori evidenti nella codice?
Grazie, Stefan
Grazie mille per i vostri pensieri. Anche se è possibile eseguire richieste anonime a S3 se il bucket è pubblicamente disponibile, la tua ipotesi sembra vera, che i caricamenti multipart non sono fatti per il mio caso. E quegli URL pre-firmati non sono disponibili per i caricamenti multipart è troppo male. Tuttavia, ho deciso di utilizzare il meccanismo AWS IAM per impostare un criterio writeonly per il bucket e per memorizzare le credenziali per un nuovo utente di conseguenza configurato nell'applet. Dal punto di vista della sicurezza, dovrebbe andare bene. – schneck
@schneck: Facilitare una politica di sola scrittura IAM è un'eccellente alternativa, anzi, mi sono concentrato troppo su * come * stai cercando di raggiungere il tuo obiettivo piuttosto che sul caso di utilizzo effettivo - potresti farlo ancora di più [Making Richieste utilizzando le credenziali temporanee dell'utente IAM] (http://docs.amazonwebservices.com/AmazonS3/latest/dev/AuthUsingTempSessionTokenJava.html) per evitare completamente la memorizzazione di credenziali permanenti all'interno dell'applet. –
Il pericolo con un bucket pubblico di sola scrittura non è che qualcuno potrebbe spammare il tuo secchio usando nient'altro che curl? O mi sta sfuggendo qualcosa? – sethcall