简体   繁体   English

Azure - 为列表blob调用Storage rest api

[英]Azure - call Storage rest api for list blobs

What I am trying to do is connect to the Azure Storage Rest API List Blobs. 我要做的是连接到Azure Storage Rest API列表Blob。 Ref: http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx 参考: http//msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx

I have tried to follow http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx in order to specify the authorization header however I get a 403 error - forbidden. 我曾尝试关注http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx以指定授权标头,但我收到403错误 - 禁止。

Code: 码:

Uri address = new Uri("https://account.blob.core.windows.net/$logs?restype=container&comp=list");
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
req.Headers["x-ms-date"] = "2013-09-04";
req.Headers["x-ms-version"] = "2012-02-12";
req.Method = "GET";

string StringToSign =  "GET\n"
    + "\n" // content encoding
    + "\n" // content language
    + "\n" // content length
    + "\n" // content md5
    + "\n" // content type
    + "\n" // date
    + "\n" // if modified since
    + "\n" // if match
    + "\n" // if none match
    + "\n" // if unmodified since
    + "\n" // range
    + "x-ms-date: 2013-09-04\nx-ms-version:2012-02-12\n" // headers
    + "/account/blob\ncomp:list\nrestype:container"; // resources

string accountName = "account";
string key = Convert.ToBase64String(Encoding.Default.GetBytes(StringToSign));
req.Headers["Authorization"] = string.Format("SharedKey {0}:{1}", accountName, key);

HttpWebResponse resp = req.GetResponse() as HttpWebResponse;

Can anyone see any mistakes? 任何人都可以看到任何错误吗? Is there a tool which can generate the key? 有没有可以生成密钥的工具? One thing I am not sure of is I am encoding/hashing the string correctly. 我不确定的一件事是我正确编码/散列字符串。

Thanks, Andrew 谢谢,安德鲁

Update with latest code. 使用最新代码更新。 This code gives me a Forbidden error. 这段代码给了我一个Forbidden错误。

DateTime dt = DateTime.UtcNow;
string StringToSign = "GET\n"
    + "\n" // content encoding
    + "\n" // content language
    + "\n" // content length
    + "\n" // content md5
    + "\n" // content type
    + "\n" // date
    + "\n" // if modified since
    + "\n" // if match
    + "\n" // if none match
    + "\n" // if unmodified since
    + "\n" // range
    + "x-ms-date: " + dt.ToString("R") + "\nx-ms-version:2012-02-12\n" // headers
    + "/account/$logs\ncomp:list\nrestype:container";

string auth = SignThis(StringToSign, "accountkey", "account");
string method = "GET";
string urlPath = "https://account.blob.core.windows.net/$logs?restype=container&comp=list";
Uri uri = new Uri(urlPath);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = method;
request.Headers.Add("x-ms-date", dt.ToString("R"));
request.Headers.Add("x-ms-version", "2012-02-12");
request.Headers.Add("Authorization", auth);

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
}

There are some issues with the code above. 上面的代码存在一些问题。 But before that, first thing you would need is the key for your storage account. 但在此之前,您首先需要的是存储帐户的密钥。 You can get it from Windows Azure Portal. 您可以从Windows Azure门户获取它。 Click on the storage account name in the portal and then click on "MANAGE ACCESS KEYS" as shown in the screenshot below: 单击门户中的存储帐户名称,然后单击“管理访问密钥”,如下面的屏幕截图所示:

在此输入图像描述

Now for the issues: 现在问题:

The way you're creating the authorization header is incorrect. 您创建授权标头的方式不正确。 For creating the authorization header, you would need account name, account key and StringToSign from your code above. 要创建授权标头,您需要上面代码中的帐户名,帐户密钥和StringToSign Try this code: 试试这段代码:

private static String SignThis(String StringToSign, string Key, string Account)
        {
            String signature = string.Empty;
            byte[] unicodeKey = Convert.FromBase64String(Key);
            using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
            {
                Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(canonicalizedString);
                signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
            }

            String authorizationHeader = String.Format(
                  CultureInfo.InvariantCulture,
                  "{0} {1}:{2}",
                  "SharedKey",
                  Account,
                  signature);

            return authorizationHeader;
        }

The function above will provide authorization header which you would need to pass as authorization. 上面的函数将提供您需要作为授权传递的授权标头。

2nd thing I noticed was that in the code for StringToSign , you're not passing the container name. 我注意到的第二件事是在StringToSign的代码中,你没有传递容器名称。 So your StringToSign should be: 所以你的StringToSign应该是:

string StringToSign =  "GET\n"
    + "\n" // content encoding
    + "\n" // content language
    + "\n" // content length
    + "\n" // content md5
    + "\n" // content type
    + "\n" // date
    + "\n" // if modified since
    + "\n" // if match
    + "\n" // if none match
    + "\n" // if unmodified since
    + "\n" // range
    + "x-ms-date: 2013-09-04\nx-ms-version:2012-02-12\n" // headers
    + "/account/$logs\ncomp:list\nrestype:container"; // resources 

You mentioned that you're quite new to Windows Azure. 你提到你是Windows Azure的新手。 If I may suggest - implementing REST API has been done by a number of folks earlier also. 如果我可以建议 - 早先也已经由许多人实现了REST API。 Please take a look at what they have done instead of trying to do the same thing again. 请看看他们做了什么,而不是再尝试做同样的事情。 You may find these links useful: 您可能会发现这些链接很有用:

http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/ http://convective.wordpress.com/2010/08/18/examples-of-the-windows-azure-storage-services-rest-api/

http://azurestoragesamples.codeplex.com/ - Look at the REST API implementation in this project. http://azurestoragesamples.codeplex.com/ - 查看此项目中的REST API实现。

UPDATE UPDATE

Here's the working code (just change the account name, key and the container name) 这是工作代码(只需更改帐户名,密钥和容器名称)

static void ListContainers()
{
    string Account = "account";
    string Key = "key";
    string Container = "$logs";
    DateTime dt = DateTime.UtcNow;
    string StringToSign = String.Format("GET\n"
        + "\n" // content encoding
        + "\n" // content language
        + "\n" // content length
        + "\n" // content md5
        + "\n" // content type
        + "\n" // date
        + "\n" // if modified since
        + "\n" // if match
        + "\n" // if none match
        + "\n" // if unmodified since
        + "\n" // range
        + "x-ms-date:" + dt.ToString("R") + "\nx-ms-version:2012-02-12\n" // headers
        + "/{0}/{1}\ncomp:list\nrestype:container", Account, Container);

    string auth = SignThis(StringToSign, Key, Account);
    string method = "GET";
    string urlPath = string.Format("https://{0}.blob.core.windows.net/{1}?restype=container&comp=list", Account, Container);
    Uri uri = new Uri(urlPath);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    request.Method = method;
    request.Headers.Add("x-ms-date", dt.ToString("R"));
    request.Headers.Add("x-ms-version", "2012-02-12");
    request.Headers.Add("Authorization", auth);

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
    }
}

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM