0
Fine UploaderとS3を使っている人は誰ですか?ファインアップローダ - Java Enpoint
ファインアップローダを使用してAWS S3に直接ファイルを送信しようとしています。エンドポイントサーブレットに問題があるか、クライアント側でサーブレットを設定していると思います。
[Fine Uploader 5.6.0]サーバーから空または無効な応答を受信しました。 [Fine Uploader 5.6.0]ポリシーに署名できませんでした。サーバーから空または無効な応答を受信しました。
Tksです。
マイエンドポイント:サーブレットUploadfiles - http://www.example.com/uploadfiles
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.util.BinaryUtils;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings("serial")
public class S3UploadsServlet extends HttpServlet
{
final static String AWS_SECRET_KEY = "MY_SECRET_KEY";
final static String AWS_PUBLIC_KEY = "MY_PUBLIC_KEY";
// Main entry point for POST requests from Fine Uploader. This currently assumes delete file requests use the
// default method of DELETE, but that can be adjusted.
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
if (req.getServletPath().endsWith("s3/signature"))
{
handleSignatureRequest(req, resp);
}
else if (req.getServletPath().endsWith("s3/success"))
{
handleUploadSuccessRequest(req, resp);
}
}
// Main entry point for DELETE requests sent by Fine Uploader.
@Override
public void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
String key = req.getParameter("key");
String bucket = req.getParameter("bucket");
resp.setStatus(200);
AWSCredentials myCredentials = new BasicAWSCredentials(AWS_PUBLIC_KEY, AWS_SECRET_KEY);
AmazonS3 s3Client = new AmazonS3Client(myCredentials);
s3Client.deleteObject(bucket, key);
}
// Called by the main POST request handler if Fine Uploader has asked for an item to be signed. The item may be a
// policy document or a string that represents multipart upload request headers.
private void handleSignatureRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
resp.setStatus(200);
JsonParser jsonParser = new JsonParser();
JsonElement contentJson = jsonParser.parse(req.getReader());
JsonObject jsonObject = contentJson.getAsJsonObject();
if (req.getQueryString() != null && req.getQueryString().contains("v4=true")) {
handleV4SignatureRequest(jsonObject, contentJson, req, resp);
}
else {
handleV2SignatureRequest(jsonObject, contentJson, req, resp);
}
resp.setStatus(200);
}
private void handleV2SignatureRequest(JsonObject payload, JsonElement contentJson, HttpServletRequest req, HttpServletResponse resp) throws IOException{
String signature;
JsonElement headers = payload.get("headers");
JsonObject response = new JsonObject();
try
{
// If this is not a multipart upload-related request, Fine Uploader will send a policy document
// as the value of a "policy" property in the request. In that case, we must base-64 encode
// the policy document and then sign it. The will include the base-64 encoded policy and the signed policy document.
if (headers == null)
{
String base64Policy = base64EncodePolicy(contentJson);
signature = sign(base64Policy);
// Validate the policy document to ensure the client hasn't tampered with it.
// If it has been tampered with, set this property on the response and set the status to a non-200 value.
//response.addProperty("invalid", true);
response.addProperty("policy", base64Policy);
}
// If this is a request to sign a multipart upload-related request, we only need to sign the headers,
// which are passed as the value of a "headers" property from Fine Uploader. In this case,
// we only need to return the signed value.
else
{
signature = sign(headers.getAsString());
}
response.addProperty("signature", signature);
resp.getWriter().write(response.toString());
}
catch (Exception e)
{
resp.setStatus(500);
}
}
private void handleV4SignatureRequest(JsonObject payload, JsonElement contentJson, HttpServletRequest req, HttpServletResponse resp) throws IOException{
String signature = null;
JsonElement headers = payload.get("headers");
JsonObject response = new JsonObject();
try
{
// If this is not a multipart upload-related request, Fine Uploader will send a policy document
// as the value of a "policy" property in the request. In that case, we must base-64 encode
// the policy document and then sign it. The will include the base-64 encoded policy and the signed policy document.
if (headers == null)
{
String base64Policy = base64EncodePolicy(contentJson);
JsonArray conditions = payload.getAsJsonArray("conditions");
String credentialCondition = null;
for (int i = 0; i < conditions.size(); i++) {
JsonObject condition = conditions.get(i).getAsJsonObject();
JsonElement value = condition.get("x-amz-credential");
if (value != null) {
credentialCondition = value.getAsString();
break;
}
}
// Validate the policy document to ensure the client hasn't tampered with it.
// If it has been tampered with, set this property on the response and set the status to a non-200 value.
// response.addProperty("invalid", true);
Pattern pattern = Pattern.compile(".+\\/(.+)\\/(.+)\\/s3\\/aws4_request");
Matcher matcher = pattern.matcher(credentialCondition);
matcher.matches();
signature = getV4Signature(matcher.group(1), matcher.group(2), base64Policy);
response.addProperty("policy", base64Policy);
}
// If this is a request to sign a multipart upload-related request, we only need to sign the headers,
// which are passed as the value of a "headers" property from Fine Uploader. In this case,
// we only need to return the signed value.
else
{
Pattern pattern = Pattern.compile(".+\\n.+\\n(\\d+)\\/(.+)\\/s3\\/aws4_request\\n(.+)", Pattern.DOTALL);
Matcher matcher = pattern.matcher(headers.getAsString());
matcher.matches();
String canonicalRequest = matcher.group(3);
String hashedCanonicalRequest = hash256(canonicalRequest);
String stringToSign = headers.getAsString().replaceAll("(?s)(.+s3\\/aws4_request\\n).+", "$1" + hashedCanonicalRequest);
// Validate the policy document to ensure the client hasn't tampered with it.
// If it has been tampered with, set this property on the response and set the status to a non-200 value.
// response.addProperty("invalid", true);
signature = getV4Signature(matcher.group(1), matcher.group(2), stringToSign);
}
response.addProperty("signature", signature);
resp.getWriter().write(response.toString());
}
catch (Exception e)
{
resp.setStatus(500);
}
}
// Called by the main POST request handler if Fine Uploader has indicated that the file has been
// successfully sent to S3. You have the opportunity here to examine the file in S3 and "fail" the upload
// if something in not correct.
private void handleUploadSuccessRequest(HttpServletRequest req, HttpServletResponse resp) {
String key = req.getParameter("key");
String uuid = req.getParameter("uuid");
String bucket = req.getParameter("bucket");
String name = req.getParameter("name");
resp.setStatus(200);
System.out.println(String.format("Upload successfully sent to S3! Bucket: %s, Key: %s, UUID: %s, Filename: %s",
bucket, key, uuid, name));
}
private String getV4Signature(String date, String region, String stringToSign) throws Exception {
byte[] kSecret = ("AWS4" + AWS_SECRET_KEY).getBytes("UTF8");
byte[] kDate = sha256Encode(date, kSecret);
byte[] kRegion = sha256Encode(region, kDate);
byte[] kService = sha256Encode("s3", kRegion);
byte[] kSigning = sha256Encode("aws4_request", kService);
byte[] kSignature = sha256Encode(stringToSign, kSigning);
return Hex.encodeHexString(kSignature);
}
private byte[] sha256Encode(String data, byte[] key) throws Exception {
String algorithm="HmacSHA256";
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(key, algorithm));
return mac.doFinal(data.getBytes("UTF8"));
}
private String hash256(String data) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(data.getBytes());
return bytesToHex(md.digest());
}
private String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte byt : bytes) result.append(Integer.toString((byt & 0xff) + 0x100, 16).substring(1));
return result.toString();
}
private String base64EncodePolicy(JsonElement jsonElement) throws UnsupportedEncodingException{
String policyJsonStr = jsonElement.toString();
String base64Encoded = BinaryUtils.toBase64 (policyJsonStr.getBytes("UTF-8"));
return base64Encoded;
}
private String sign(String toSign) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException{
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(AWS_SECRET_KEY.getBytes("UTF-8"), "HmacSHA1"));
String signature = BinaryUtils.toBase64 (hmac.doFinal(toSign.getBytes("UTF-8")));
return signature;
}
}
私のJSPページ:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link href="/mysite/uploader/fine-uploader-gallery.css" rel="stylesheet">
<script src="/mysite/uploader/s3.jquery.fine-uploader.js"></script>
<script type="text/template" id="qq-template-s3">
<div class="qq-uploader-selector qq-uploader qq-gallery" qq-drop-area-text="Drop files here">
<div class="qq-total-progress-bar-container-selector qq-total-progress-bar-container">
<div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-total-progress-bar-selector qq-progress-bar qq-total-progress-bar"></div>
</div>
<div class="qq-upload-drop-area-selector qq-upload-drop-area" qq-hide-dropzone>
<span class="qq-upload-drop-area-text-selector"></span>
</div>
<div class="qq-upload-button-selector qq-upload-button">
<div>Upload a file</div>
</div>
<span class="qq-drop-processing-selector qq-drop-processing">
<span>Processing dropped files...</span>
<span class="qq-drop-processing-spinner-selector qq-drop-processing-spinner"></span>
</span>
<ul class="qq-upload-list-selector qq-upload-list" role="region" aria-live="polite" aria-relevant="additions removals">
<li>
<span role="status" class="qq-upload-status-text-selector qq-upload-status-text"></span>
<div class="qq-progress-bar-container-selector qq-progress-bar-container">
<div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" class="qq-progress-bar-selector qq-progress-bar"></div>
</div>
<span class="qq-upload-spinner-selector qq-upload-spinner"></span>
<div class="qq-thumbnail-wrapper">
<a class="preview-link" target="_blank">
<img class="qq-thumbnail-selector" qq-max-size="120" qq-server-scale>
</a>
</div>
<button type="button" class="qq-upload-cancel-selector qq-upload-cancel">X</button>
<button type="button" class="qq-upload-retry-selector qq-upload-retry">
<span class="qq-btn qq-retry-icon" aria-label="Retry"></span>
Retry
</button>
<div class="qq-file-info">
<div class="qq-file-name">
<span class="qq-upload-file-selector qq-upload-file"></span>
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon" aria-label="Edit filename"></span>
</div>
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
<span class="qq-upload-size-selector qq-upload-size"></span>
<button type="button" class="qq-btn qq-upload-delete-selector qq-upload-delete">
<span class="qq-btn qq-delete-icon" aria-label="Delete"></span>
</button>
<button type="button" class="qq-btn qq-upload-pause-selector qq-upload-pause">
<span class="qq-btn qq-pause-icon" aria-label="Pause"></span>
</button>
<button type="button" class="qq-btn qq-upload-continue-selector qq-upload-continue">
<span class="qq-btn qq-continue-icon" aria-label="Continue"></span>
</button>
</div>
</li>
</ul>
<dialog class="qq-alert-dialog-selector">
<div class="qq-dialog-message-selector"></div>
<div class="qq-dialog-buttons">
<button type="button" class="qq-cancel-button-selector">Close</button>
</div>
</dialog>
<dialog class="qq-confirm-dialog-selector">
<div class="qq-dialog-message-selector"></div>
<div class="qq-dialog-buttons">
<button type="button" class="qq-cancel-button-selector">No</button>
<button type="button" class="qq-ok-button-selector">Yes</button>
</div>
</dialog>
<dialog class="qq-prompt-dialog-selector">
<div class="qq-dialog-message-selector"></div>
<input type="text">
<div class="qq-dialog-buttons">
<button type="button" class="qq-cancel-button-selector">Cancel</button>
<button type="button" class="qq-ok-button-selector">Ok</button>
</div>
</dialog>
</div>
</script>
<style>
#fine-uploader-s3 .preview-link {
display: block;
height: 100%;
width: 100%;
}
</style>
<title>Fine Uploader S3 Demo</title>
</head>
<body>
<div id="fine-uploader-s3"></div>
<script>
$('#fine-uploader-s3').fineUploaderS3({
debug: true,
template: 'qq-template-s3',
request: {
endpoint: "my_bucket.s3.amazonaws.com",
accessKey: "my_access_key"
},
signature: {
endpoint: "http://www.example.com/uploadfiles"
},
uploadSuccess: {
endpoint: "http://www.example.com/uploadfiles?success",
params: {
isBrowserPreviewCapable: qq.supportedFeatures.imagePreviews
}
},
iframeSupport: {
localBlankPagePath: "/server/success.html"
},
cors: {
expected: false
},
chunking: {
enabled: true
},
resume: {
enabled: true
},
deleteFile: {
enabled: true,
method: "POST",
endpoint: "http://www.example.com/uploadfiles"
},
validation: {
itemLimit: 5,
sizeLimit: 15000000
},
thumbnails: {
placeholders: {
notAvailablePath: "/uploader/placeholders/not_available-generic.png",
waitingPath: "/uploader/placeholders/waiting-generic.png"
}
},
callbacks: {
onComplete: function(id, name, response) {
var previewLink = qq(this.getItemByFileId(id)).getByClass('preview-link')[0];
if (response.success) {
previewLink.setAttribute("href", response.tempLink)
}
}
}
});
</script>
</body>
</html>
実例はhttps://github.com/FineUploader/server-examplesにあります。コードに何が含まれているかを判断したら、回答を提供してください。あなたのコードを提供していないので誰も助けることはできません。 –
こんにちは、あなたの返事のためのtks。 申し訳ありません。元の投稿で使用しているコードをご覧ください。 Tks。 –
おそらく、サーバー構成の問題です。 _exact_レスポンスはブラウザによってどのように見えますか?すべてのヘッダーとレスポンスペイロードを含めてください。 –