JWPlayer and S3: calculated signature does not match the provided one

我怕爱的太早我们不能终老 提交于 2019-12-11 17:15:34

问题


I'm trying to upload videos to JWPlayer using AWS S3.

My backend is coded in Spring so I'm using Java. I manage to request the upload URL but every time I try to submit a POST request with it I get back a "SignatureDoesNotMatch" error from AWS.

Without s3 it works just fine... The documentation is not that clear in this sense... There isn't a well done example from the beginning to the end, I mean, an example with the whole process: authentication, url request and upload of the video. So I'm struggling trying to understand what's the problem here.

With this method I get the update url.

public String createVideo(String title, String description, String username) throws UnsupportedEncodingException {
        Map<String, String> params = new HashMap<>();
        String nonce = generateNonce(8);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000L);
        params.put("api_format", "json");
        params.put("author", username);
        params.put("title", title);
        params.put("description", description);
        params.put("upload_method", "s3");
        params.put("api_key", jwPlayerConfig.getKey());
        params.put("api_nonce", nonce);
        params.put("api_timestamp", timestamp);
        params.put("api_signature", generateAPISignature(params, jwPlayerConfig.getSecret()));
        String urlParameters = getParamsString(params);
        String response = requestAuthenticationToken(jwPlayerConfig.getUrl() + jwPlayerConfig.getCreateVideoUrl(), urlParameters);
        JSONObject myObject = new JSONObject(response.toString());
        System.out.println(myObject);
        JSONObject link = myObject.getJSONObject("link");
        return "https://" + link.getString("address") + link.getString("path") +
                "?api_format=json" +
                "&redirect_address=" + jwPlayerConfig.getCreateVideoRedirectAddress() +
                "&key_in_path=True" +
                "&AWSAccessKeyId=" + link.getJSONObject("query").getString("AWSAccessKeyId") +
                "&Expires=" + link.getJSONObject("query").get("Expires").toString() +
                "&Signature=" + link.getJSONObject("query").getString("Signature");
    }

This method is called by a controller method of Spring and it uses these other methods in order to generate the upload url:

public String generateAPISignature(Map<String, String> params, String api_secret){
        final Map<String, String> sorted = params.entrySet()
                .stream()
                .sorted(Comparator.comparing(Map.Entry::getKey))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
        StringBuilder concat = new StringBuilder();
        for(String key: sorted.keySet()){
            concat.append(key);
            concat.append("=");
            concat.append(sorted.get(key));
            concat.append("&");
        }
        concat.delete(concat.length() - 1, concat.length());
        concat.append(api_secret);
        return DigestUtils.sha1Hex(concat.toString());
    }

This method generates a nonce:

public static String generateNonce(int length){
        Random rnd = new Random();
        StringBuilder nonce = new StringBuilder();
        do{
            nonce.append(rnd.nextInt(10));
        }while(nonce.length() < length);
        return nonce.toString();
    }

And this other one builds the parameters string from the parameters Map:

public String getParamsString(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();

        for (Map.Entry<String, String> entry : params.entrySet()) {
            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
            result.append("&");
        }

        String resultString = result.toString();

        return resultString.length() > 0
                ? resultString.substring(0, resultString.length() - 1)
                : resultString;
    }

The html form looks like this:

<form method="POST" action="url">
    <input type="file" name="file" id="file"/>
    <button type="submit">Upload video</button>
</form>

The error message I get is the following:

SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your key and signing method. AKKSAJBCJBSbXC3NQ POST application/x-www-form-urlencoded 1567098922 /jwplatform-upload/Qsafas6vB WWbjcskWBKlc/BLxbm6/RJg57u7M= 50 4f 53 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 31 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 64 6f 64 65 64 0a 31 35 36 37 30 39 38 39 32 32 0a 2f 6a 77 70 6c 23 74 66 6f 72 6d 2d 75 70 6c 6f 61 64 2f 51 72 4e 53 33 36 76 42 8D9AA0A3719CE53F 3x6mnassasaQ2PEFVmc9GZwp0Y7yFS1FtasakDgY39EktjlwX2UsoViikqiE8bDcG6pKB4YPXvsH1Q=


回答1:


Try with a PUT, not a POST. We have documentation for this at https://developer.jwplayer.com/jw-platform/reference/v1/s3_uploads.html#uploading-file



来源:https://stackoverflow.com/questions/57697391/jwplayer-and-s3-calculated-signature-does-not-match-the-provided-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!