如何使用Node设置Azure Blob存储CORS属性? [英] How to set Azure Blob Storage CORS properties using Node?

查看:75
本文介绍了如何使用Node设置Azure Blob存储CORS属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注(用于在请求上签名)并假设您将存储帐户密钥作为字符串传递,您可以在 buildSharedKeyLite 函数中尝试以下操作:

  return crypto.createHmac('sha256',new Buffer(self.accountKey,'base64')).update(stringToSign).digest('base64'); 

I have been following the blob service and authentication documentation in order to set the CORS properties on my azure blob storage account from my mobile service.

I can't figure out what I am doing wrong.

The server response is:

The MAC signature found in the HTTP request 'JI...Tk=' is not the same as any computed signature. Server used following string to sign: 'PUT

x-ms-date:Wed, 19 Feb 2014 07:24:06 GMT x-ms-version:2013-08-15 /apporotest/?comp=properties'

When I log the string to sign (not passing contentMD5 and content type) on my end, it turns out to be the same string. So I guess my function to build the shared key is wrong.

This should build : Base64(HMAC-SHA256(UTF8(StringToSign))):

function buildSharedKeyLite( verb, contentMD5, contentType, canonicalizedHeaders, canonicalizedResource ) {

        var stringToSign = verb + "\n" +
            contentMD5 + "\n" +
            contentType + "\n" +
            "" + "\n" + // date is to be empty because we use x-ms-date
            canonicalizedHeaders +
            canonicalizedResource;

        return crypto.createHmac('sha256', self.accountKey).update(encodeURIComponent(stringToSign)).digest('base64');
    }

What confuses me though is that the formerly mentioned documentation for the Shared Key Lite requires MD5 of the content as well as the content type to be set. However, the server response with the string to sign does not seem to expect these.

If the creation of the shared key lite is correct, then I assume I am not handling the creation of the MD-5 content correctly or the canonicalized headers:

function setCors( cors ) {

        var url = MY_ACCOUNT_UTL + '/?restype=service&comp=properties';
        var canonicalizedResource = '/' + MY_ACCOUNT_NAME + '/?comp=properties';
        var corsMD5 = crypto.createHash('md5' ).update(MY_CORS_XML).digest('base64');
        var date = (new Date()).toUTCString();
        var headers = {

            'x-ms-version': '2013-08-15',
            'x-ms-date': date,
            'Host': MY_ACCOUNT_HOST
        };

        var canonicalizedHeaders = buildCanonicalizedHeaders( headers );

    // THIS
        var key = buildSharedKeyLite( 'PUT', corsMD5, 'text/plain; charset=UTF-8', canonicalizedHeaders, canonicalizedResource );

    // AND THIS, BOTH YIELD THE SAME SERVER RESPONSE    
    var key = buildSharedKeyLite( 'PUT', "", "", canonicalizedHeaders, canonicalizedResource );

        headers['Authorization'] = 'SharedKeyLite ' + MY_ACCOUNT_NAME + ':' + key;

        var options = {
            url: url,
            headers: headers
        };

        function onPropertiesSet(error, response, body) {
            if (!error && response.statusCode == 202) {
                console.log("CORS: OK");
            }
            else {
                console.log("CORS: "+ response.statusCode);
                console.log(body);
            }
        }
        request.put(options, onPropertiesSet); // require('request')
    }

    function buildCanonicalizedHeaders( headers ) {

        var xmsHeaders = [];
        var canHeaders = "";

        for ( var name in headers ) {
            if ( name.indexOf('x-ms-') == 0 ) )
                xmsHeaders.push( name );
            }
        }

        xmsHeaders.sort();

        for ( var i = 0; i < xmsHeaders.length; i++ ) {
            name = xmsHeaders[i];
            canHeaders = canHeaders + name.toLowerCase().trim() + ':' + headers[name] + '\n';
        }
        return canHeaders;
    }

I am really thankful for any pointers.

解决方案

I'm not 100% sure but I believe encodeURIComponent is creating problem for you. For example, look at the code below:

var a = "PUT\n\n\nFeb 2014 09:08:18 GMT\nx-ms-version:2013-08-15\n/cynapta/?comp=properties";
var b = encodeURIComponent(a);
console.log(a);
console.log("\n");
console.log(b);

and this is how a and b are displayed on my console:

Can you try by removing encodeURIComponent and just pass stringToSign directly for signature calculation?

Update

Looking at the source code here for signing the request and assuming you're passing storage account key as string, can you try the following in your buildSharedKeyLite function:

return crypto.createHmac('sha256', new Buffer(self.accountKey, 'base64')).update(stringToSign).digest('base64');

这篇关于如何使用Node设置Azure Blob存储CORS属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆