2013-09-04 1 views
3

내가하려는 것은 Azure Storage Rest API List Blob에 연결하는 것입니다. 참조 : http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspxAzure - 콜 목록 BLOB에 대한 스토리지 나머지 API

승인 헤더를 지정하기 위해 http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx을 따르려고했지만 403 오류가 발생합니다.

코드 :

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; 

사람이 어떤 실수를 볼 수 있을까요? 키를 생성 할 수있는 도구가 있습니까? 한가지 확실하지 않은 것은 문자열을 올바르게 인코딩/해싱한다는 것입니다.

감사합니다, 최신 코드 앤드류

업데이트. 이 코드는 나에게 금지 된 오류를줍니다.

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()) 
{ 
} 
+0

"키를 생성 할 수있는 도구가 있습니까?"라고 말하면 의심 스럽습니다. 푸른 관리 포털 오른쪽의 푸른 색 저장 페이지에서 키를 가져 오는 중입니까? – paqogomez

+0

예. Azure가 처음입니다. 포털에 액세스 할 수 있습니까? 포털에 나열된 키를 사용하겠습니까? 위의 코드를 통해 키를 생성 하시겠습니까? – andrewb

+0

"StringToSign"으로 무엇을하고 있는지 보았습니다. 그것은 그 예가 당신에게 말하려고하는 것이 아닙니다. 당신은 보낼 가치가 아닌 결과를주고 있습니다. 내가 뭔가를하려고 노력하자. 내가이 모든 코드를 사용하고 있다는 사실을 알기가 어렵습니다. – paqogomez

답변

4

위의 코드에는 몇 가지 문제가 있습니다. 하지만 그 전에 필요한 것은 스토리지 계정의 핵심입니다. Windows Azure 포털에서 가져올 수 있습니다. 포털에 저장 계정 이름을 클릭 한 다음 아래의 스크린 샷과 같이 "ACCESS 키를 관리"를 클릭 :

방법 당신이를 만드는 : 문제에 대한 지금

enter image description here

승인 헤더가 잘못되었습니다. 인증 헤더를 만들려면 위 코드에서 계정 이름, 계정 키 및 StringToSign이 필요합니다. 이 코드를보십시오 : 위의

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; 
     } 

이 기능은 당신이 승인으로 통과해야 인증 헤더를 제공합니다.

두 번째로 주목해야 할 점은 StringToSign의 코드에서 컨테이너 이름을 전달하지 않는다는 것입니다. 그래서 StringToSign가 있어야한다 : 당신은 윈도우 Azure에 아주 익숙 언급

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 

. 제가 제안 할 수 있다면 - REST API를 구현하는 것은 이전에 많은 사람들에 의해 수행되었습니다. 그들이 똑같은 일을 다시 시도하는 대신에 한 일을 살펴보십시오. 당신은 유용한 이러한 링크를 찾을 수 있습니다 :

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

http://azurestoragesamples.codeplex.com/ -이 프로젝트의 REST API를 구현 봐.

UPDATE가

여기에 작업 코드의

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()) 
    { 
    } 
} 

희망 (단지 키 계정 이름 및 컨테이너 이름을 변경)이 도움이됩니다.

+0

답장을 보내 주셔서 감사합니다. 몇 가지 : SignThis에서 canonicalizedString이라는 변수를 참조하면 StringToSign이어야합니다. 둘째로 canonicalizedString은 무엇입니까? 셋째,이 코드를 실행할 때 나는 여전히 금지되어 있으며 생성 된 키는 각 실행마다 다릅니다. 맞습니까? – andrewb

+0

죄송합니다 ... 내 잘못 ... 잘라 내기/붙여 넣기 오류 : P. 네, 이것은'StringToSign'이어야합니다. 그래서 기본적으로'StringToSign'은 인증 헤더를 만드는 데 사용되는 canonicalizedString입니다. 정확한 소식을 알 수 있도록 업데이트 된 코드로 원본 게시물을 업데이트 할 수 있습니까? –

+0

코드가 추가되었습니다. StringToSign 변수에서 해당 필드에 대한 값이없는 경우에도 모든 필드를 포함해야합니까? – andrewb