Wywoływanie operacji interfejsu API REST za pomocą autoryzacji klucza wspólnego

W tym artykule pokazano, jak wywołać operację interfejsu API REST usługi Azure Storage przez utworzenie autoryzowanego żądania REST przy użyciu języka C#. Po dowiesz się, jak wywołać operację interfejsu API REST dla usługi Blob Storage, możesz użyć podobnych kroków dla dowolnej innej operacji REST usługi Azure Storage.

Wymagania wstępne

Przykładowa aplikacja zawiera listę kontenerów obiektów blob dla konta magazynu. Aby wypróbować kod w tym artykule, potrzebne są następujące elementy:

  • Zainstaluj program Visual Studio i uwzględnij obciążenie programowanie na platformie Azure. Ten przykład został utworzony przy użyciu programu Visual Studio 2019. Jeśli używasz innej wersji, wskazówki mogą się nieznacznie różnić.

  • Subskrypcja platformy Azure. Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto.

  • Konto magazynu ogólnego przeznaczenia. Jeśli nie masz jeszcze konta magazynu, zobacz Tworzenie konta magazynu.

  • W przykładzie w tym artykule pokazano, jak wyświetlić listę kontenerów na koncie magazynu. Aby wyświetlić dane wyjściowe, przed rozpoczęciem dodaj do konta magazynu niektóre kontenery obiektów blob.

Pobieranie przykładowej aplikacji

Przykładowa aplikacja to aplikacja konsolowa napisana w języku C#.

Użyj narzędzia git, aby pobrać kopię tej aplikacji do swojego środowiska projektowego.

git clone https://github.com/Azure-Samples/storage-dotnet-rest-api-with-auth.git

To polecenie klonuje repozytorium do lokalnego folderu git. Aby otworzyć rozwiązanie programu Visual Studio, przejdź do folderu storage-dotnet-rest-api-with-auth i otwórz plik StorageRestApiAuth.sln.

Informacje o interfejsie REST

Representational State Transfer (REST) to architektura, która umożliwia interakcję z usługą za pośrednictwem protokołu internetowego, takiego jak HTTP/HTTPS. Interfejs REST jest niezależny od oprogramowania uruchomionego na serwerze lub kliencie. Interfejs API REST może być wywoływany z dowolnej platformy obsługującej protokół HTTP/HTTPS. Możesz napisać aplikację działającą na komputerach Mac, Windows, Linux, telefonie z systemem Android lub tablecie, i Telefon, iPodze lub witrynie internetowej oraz użyć tego samego interfejsu API REST dla wszystkich tych platform.

Wywołanie interfejsu API REST składa się z żądania złożonego przez klienta i odpowiedzi zwróconej przez usługę. W żądaniu wysyłasz adres URL zawierający informacje o operacji, którą chcesz wywołać, zasób do działania, wszystkie parametry zapytania i nagłówki oraz w zależności od wywołanej operacji, ładunku danych. Odpowiedź z usługi zawiera kod stanu, zestaw nagłówków odpowiedzi i w zależności od operacji, która została wywołana, ładunku danych.

Informacje o przykładowej aplikacji

Przykładowa aplikacja wyświetla listę kontenerów na koncie magazynu. Gdy zrozumiesz, jak informacje w dokumentacji interfejsu API REST są skorelowane z rzeczywistym kodem, inne wywołania REST są łatwiejsze do zrozumienia.

Jeśli spojrzysz na interfejs API REST usługi Blob Service, zobaczysz wszystkie operacje, które można wykonać w magazynie obiektów blob. Biblioteki klienta magazynu są otokami interfejsów API REST, co ułatwia dostęp do zasobów magazynu bez bezpośredniego korzystania z interfejsów API REST. Czasami jednak możesz chcieć użyć interfejsu API REST zamiast biblioteki klienta magazynu.

Operacja Wyświetlanie listy kontenerów

Ten artykuł koncentruje się na operacji List Containers . Poniższe informacje pomagają zrozumieć niektóre pola w żądaniu i odpowiedzi.

Metoda żądania: GET. To zlecenie jest metodą HTTP określaną jako właściwość obiektu żądania. Inne wartości tego zlecenia to HEAD, PUT i DELETE, w zależności od wywoływanego interfejsu API.

Identyfikator URI żądania: https://myaccount.blob.core.windows.net/?comp=list. Identyfikator URI żądania jest tworzony na podstawie punktu końcowego https://myaccount.blob.core.windows.net konta magazynu obiektów blob i ciągu /?comp=listzasobu .

Parametry identyfikatora URI: istnieją dodatkowe parametry zapytania, których można użyć podczas wywoływania elementów ListContainers. Kilka z tych parametrów to limit czasu wywołania (w sekundach) i prefiks, który jest używany do filtrowania.

Innym przydatnym parametrem jest maxresults: jeśli więcej kontenerów jest dostępnych niż ta wartość, treść odpowiedzi będzie zawierać element NextMarker wskazujący następny kontener, który ma powrócić do następnego żądania. Aby użyć tej funkcji, należy podać wartość NextMarker jako parametr znacznika w identyfikatorze URI podczas następnego żądania. W przypadku korzystania z tej funkcji jest ona analogiczna do stronicowania wyników.

Aby użyć dodatkowych parametrów, dołącz je do ciągu zasobu z wartością, tak jak w tym przykładzie:

/?comp=list&timeout=60&maxresults=100

Nagłówki żądań: w tej sekcji wymieniono wymagane i opcjonalne nagłówki żądań. Wymagane są trzy nagłówki: nagłówek autoryzacji , x-ms-date (zawiera godzinę UTC żądania) i x-ms-version (określa wersję interfejsu API REST do użycia). Dołączenie elementu x-ms-client-request-id w nagłówkach jest opcjonalne. Możesz ustawić wartość dla tego pola na dowolne elementy i jest zapisywana w dziennikach analizy magazynu po włączeniu rejestrowania.

Treść żądania: nie ma treści żądania dla elementów ListContainers. Treść żądania jest używana we wszystkich operacjach PUT podczas przekazywania obiektów blob, w tym SetContainerAccessPolicy. Treść żądania umożliwia wysyłanie w formacie XML listy przechowywanych zasad dostępu do zastosowania. Zasady dostępu przechowywanego omówiono w artykule Korzystanie z sygnatur dostępu współdzielonego (SAS).

Kod stanu odpowiedzi: informuje o wszelkich kodach stanu, które należy znać. W tym przykładzie kod stanu HTTP 200 jest prawidłowy. Aby uzyskać pełną listę kodów stanu HTTP, zapoznaj się z tematem Definicje kodu stanu. Aby wyświetlić kody błędów specyficzne dla interfejsów API REST usługi Storage, zobacz Typowe kody błędów interfejsu API REST

Nagłówki odpowiedzi: obejmują one typ zawartości; x-ms-request-id, czyli identyfikator żądania, który został przekazany; x-ms-version, która wskazuje wersję używanej usługi Blob, oraz datę, która jest w formacie UTC i informuje, o której godzinie zostało wykonane żądanie.

Treść odpowiedzi: to pole jest strukturą XML dostarczającą żądane dane. W tym przykładzie odpowiedź to lista kontenerów i ich właściwości.

Tworzenie żądania REST

W przypadku zabezpieczeń działających w środowisku produkcyjnym należy zawsze używać protokołu HTTPS, a nie http. Na potrzeby tego ćwiczenia używamy protokołu HTTP, aby wyświetlić dane żądania i odpowiedzi. Aby wyświetlić informacje o żądaniu i odpowiedzi w rzeczywistych wywołaniach REST, możesz pobrać program Fiddler lub podobną aplikację. W rozwiązaniu programu Visual Studio nazwa konta magazynu i klucz są zakodowane w klasie . Metoda ListContainersAsyncREST przekazuje nazwę konta magazynu i klucz konta magazynu do metod używanych do tworzenia różnych składników żądania REST. W rzeczywistej aplikacji nazwa i klucz konta magazynu będą znajdować się w pliku konfiguracji, zmiennych środowiskowych lub pobrać je z usługi Azure Key Vault.

W naszym przykładowym projekcie kod tworzenia nagłówka Authorization znajduje się w oddzielnej klasie. Chodzi o to, że możesz wziąć całą klasę i dodać ją do własnego rozwiązania i użyć jej "tak, jak jest". Kod nagłówka autoryzacji działa w przypadku większości wywołań interfejsu API REST do usługi Azure Storage.

Aby skompilować żądanie, które jest obiektem HttpRequestMessage, przejdź do pozycji ListContainersAsyncREST w pliku Program.cs. Kroki tworzenia żądania to:

  • Utwórz identyfikator URI, który ma być używany do wywoływania usługi.
  • Utwórz obiekt HttpRequestMessage i ustaw ładunek. Ładunek ma wartość null dla elementu ListContainersAsyncREST, ponieważ nie przekazujemy niczego.
  • Dodaj nagłówki żądań dla x-ms-date i x-ms-version.
  • Pobierz nagłówek autoryzacji i dodaj go.

Potrzebne są podstawowe informacje:

  • W przypadku klasy ListContainers metoda to GET. Ta wartość jest ustawiana podczas tworzenia wystąpienia żądania.
  • Zasób jest częścią zapytania identyfikatora URI, która wskazuje, który interfejs API jest wywoływany, więc wartość to /?comp=list. Jak wspomniano wcześniej, zasób znajduje się na stronie dokumentacji referencyjnej, która zawiera informacje o interfejsie API ListContainers.
  • Identyfikator URI jest tworzony przez utworzenie punktu końcowego usługi Blob Service dla tego konta magazynu i połączenie zasobu. Wartość identyfikatora URI żądania kończy się na .http://contosorest.blob.core.windows.net/?comp=list
  • W przypadku obiektów ListContainers element requestBody ma wartość null i nie ma dodatkowych nagłówków.

Różne interfejsy API mogą mieć inne parametry do przekazania, takie jak ifMatch. Przykład, gdzie można użyć funkcji ifMatch podczas wywoływania obiektu PutBlob. W takim przypadku należy ustawić wartość ifMatch na wartość eTag i zaktualizować obiekt blob tylko wtedy, gdy element eTag, który podajesz, pasuje do bieżącego elementu eTag w obiekcie blob. Jeśli ktoś inny zaktualizował obiekt blob od momentu pobrania elementu eTag, ich zmiana nie zostanie zastąpiona.

Najpierw ustaw parametr uri i requestPayload.

// Construct the URI. It will look like this:
//   https://myaccount.blob.core.windows.net/resource
String uri = string.Format("http://{0}.blob.core.windows.net?comp=list", storageAccountName);

// Provide the appropriate payload, in this case null.
//   we're not passing anything in.
Byte[] requestPayload = null;

Następnie utwórz wystąpienie żądania, ustawiając metodę na GET i podając identyfikator URI.

// Instantiate the request message with a null payload.
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{ Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{

Dodaj nagłówki żądań dla x-ms-date elementów i x-ms-version. To miejsce w kodzie jest również miejscem dodawania wszelkich dodatkowych nagłówków żądań wymaganych do wywołania. W tym przykładzie nie ma żadnych dodatkowych nagłówków. Przykładem interfejsu API, który przekazuje dodatkowe nagłówki, jest operacja Set Container ACL (Ustawianie listy ACL kontenerów). To wywołanie interfejsu API dodaje nagłówek o nazwie "x-ms-blob-public-access" i wartość poziomu dostępu.

// Add the request headers for x-ms-date and x-ms-version.
DateTime now = DateTime.UtcNow;
httpRequestMessage.Headers.Add("x-ms-date", now.ToString("R", CultureInfo.InvariantCulture));
httpRequestMessage.Headers.Add("x-ms-version", "2017-07-29");
// If you need any additional headers, add them here before creating
//   the authorization header.

Wywołaj metodę tworzącą nagłówek autoryzacji i dodaj ją do nagłówków żądania. Nagłówek autoryzacji zostanie utworzony w dalszej części artykułu. Nazwa metody to GetAuthorizationHeader, który można zobaczyć w tym fragmencie kodu:

// Get the authorization header and add it.
httpRequestMessage.Headers.Authorization = AzureStorageAuthenticationHelper.GetAuthorizationHeader(
    storageAccountName, storageAccountKey, now, httpRequestMessage);

W tym momencie httpRequestMessage zawiera żądanie REST zakończone nagłówkami autoryzacji.

Wysyłanie żądania

Po utworzeniu żądania możesz wywołać metodę SendAsync, aby wysłać ją do usługi Azure Storage. Sprawdź, czy wartość kodu stanu odpowiedzi to 200, co oznacza, że operacja zakończyła się pomyślnie. Następnie przeanalizuj odpowiedź. W takim przypadku uzyskasz listę kontenerów w formacie XML. Przyjrzyjmy się kodowi wywołującego metodę GetRESTRequest, aby utworzyć żądanie, wykonać żądanie, a następnie zbadać odpowiedź dla listy kontenerów.

    // Send the request.
    using (HttpResponseMessage httpResponseMessage =
      await new HttpClient().SendAsync(httpRequestMessage, cancellationToken))
    {
        // If successful (status code = 200),
        //   parse the XML response for the container names.
        if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
        {
            String xmlString = await httpResponseMessage.Content.ReadAsStringAsync();
            XElement x = XElement.Parse(xmlString);
            foreach (XElement container in x.Element("Containers").Elements("Container"))
            {
                Console.WriteLine("Container name = {0}", container.Element("Name").Value);
            }
        }
    }
}

Jeśli uruchamiasz sniffer sieci, taki jak Fiddler podczas wykonywania wywołania funkcji SendAsync, możesz zobaczyć informacje o żądaniu i odpowiedzi. Zobaczmy. Nazwa konta magazynu to contosorest.

Żądanie:

GET /?comp=list HTTP/1.1

Nagłówki żądań:

x-ms-date: Thu, 16 Nov 2017 23:34:04 GMT
x-ms-version: 2014-02-14
Authorization: SharedKey contosorest:1dVlYJWWJAOSHTCPGiwdX1rOS8B4fenYP/VrU0LfzQk=
Host: contosorest.blob.core.windows.net
Connection: Keep-Alive

Kod stanu i nagłówki odpowiedzi zwrócone po wykonaniu:

HTTP/1.1 200 OK
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 3e889876-001e-0039-6a3a-5f4396000000
x-ms-version: 2017-07-29
Date: Fri, 17 Nov 2017 00:23:42 GMT
Content-Length: 1511

Treść odpowiedzi (XML): w przypadku operacji List Containers jest wyświetlana lista kontenerów i ich właściwości.

<?xml version="1.0" encoding="utf-8"?>
<EnumerationResults
  ServiceEndpoint="http://contosorest.blob.core.windows.net/">
  <Containers>
    <Container>
      <Name>container-1</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:39:48 GMT</Last-Modified>
        <Etag>"0x8D46CBD5A7C301D"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-2</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:40:50 GMT</Last-Modified>
        <Etag>"0x8D46CBD7F49E9BD"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-3</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:41:10 GMT</Last-Modified>
        <Etag>"0x8D46CBD8B243D68"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-4</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:41:25 GMT</Last-Modified>
        <Etag>"0x8D46CBD93FED46F"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
        </Properties>
      </Container>
      <Container>
        <Name>container-5</Name>
        <Properties>
          <Last-Modified>Thu, 16 Mar 2017 22:41:39 GMT</Last-Modified>
          <Etag>"0x8D46CBD9C762815"</Etag>
          <LeaseStatus>unlocked</LeaseStatus>
          <LeaseState>available</LeaseState>
        </Properties>
      </Container>
  </Containers>
  <NextMarker />
</EnumerationResults>

Teraz, gdy już wiesz, jak utworzyć żądanie, wywołać usługę i przeanalizować wyniki, zobaczmy, jak utworzyć nagłówek autoryzacji.

Tworzenie nagłówka autoryzacji

Napiwek

Usługa Azure Storage obsługuje integrację firmy Microsoft z usługą Entra dla obiektów blob i kolejek. Identyfikator Entra firmy Microsoft oferuje znacznie prostsze środowisko autoryzowania żądania do usługi Azure Storage. Aby uzyskać więcej informacji na temat używania identyfikatora Entra firmy Microsoft do autoryzowania operacji REST, zobacz Autoryzowanie przy użyciu identyfikatora Entra firmy Microsoft. Aby zapoznać się z omówieniem integracji usługi Microsoft Entra z usługą Azure Storage, zobacz Uwierzytelnianie dostępu do usługi Azure Storage przy użyciu identyfikatora Entra firmy Microsoft.

Aby dowiedzieć się więcej na temat pojęć dotyczących autoryzacji, zobacz Autoryzowanie żądań do usługi Azure Storage.

Stylujmy ten artykuł w dół do dokładnie potrzebnych i pokażemy kod.

Najpierw użyj autoryzacji klucza współdzielonego. Format nagłówka autoryzacji wygląda następująco:

Authorization="SharedKey <storage account name>:<signature>"  

Pole podpisu to oparty na skrótach kod uwierzytelniania komunikatów (HMAC) utworzony na podstawie żądania i obliczany przy użyciu algorytmu SHA256, a następnie zakodowany przy użyciu kodowania Base64.

Ten fragment kodu przedstawia format ciągu sygnatury klucza współdzielonego:

StringToSign = VERB + "\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 + "\n" +  
               CanonicalizedHeaders +  
               CanonicalizedResource;  

W przypadku usługi Blob Storage należy określić czasownik, md5, długość zawartości, nagłówki kanoniczne i zasób kanoniczny. W tym przykładzie możesz pozostawić inne wartości puste, ale należy je umieścić, \n aby określić, że są puste.

Canonicalization to proces standaryzacji danych, które mają więcej niż jedną możliwą reprezentację. W takim przypadku standardizujesz nagłówki i zasób. Nagłówki kanoniczne to nagłówki rozpoczynające się od "x-ms-". Zasób kanoniczny jest identyfikatorem URI zasobu, w tym nazwą konta magazynu i wszystkimi parametrami zapytania (takimi jak ?comp=list). Zasób kanoniczny zawiera również wszelkie dodatkowe parametry zapytania, które mogły zostać dodane, na timeout=60przykład .

Zacznijmy od dwóch pól kanonicznych, ponieważ są one wymagane do utworzenia nagłówka Autoryzacja.

Nagłówki kanoniczne

Aby utworzyć tę wartość, pobierz nagłówki rozpoczynające się od "x-ms-" i posortuj je, a następnie sformatuj je w ciąg [key:value\n] wystąpień, połączony w jeden ciąg. W tym przykładzie nagłówki kanoniczne wyglądają następująco:

x-ms-date:Fri, 17 Nov 2017 00:44:48 GMT\nx-ms-version:2017-07-29\n

Oto kod użyty do utworzenia tych danych wyjściowych:

private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)
{
    var headers = from kvp in httpRequestMessage.Headers
        where kvp.Key.StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)
        orderby kvp.Key
        select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value };

    StringBuilder headersBuilder = new StringBuilder();

    foreach (var kvp in headers)
    {
        headersBuilder.Append(kvp.Key);
        char separator = ':';

        // Get the value for each header, strip out \r\n if found, then append it with the key.
        foreach (string headerValue in kvp.Value)
        {
            string trimmedValue = headerValue.TrimStart().Replace("\r\n", string.Empty);
            headersBuilder.Append(separator).Append(trimmedValue);

            // Set this to a comma; this will only be used
            // if there are multiple values for one of the headers.
            separator = ',';
        }

        headersBuilder.Append("\n");
    }

    return headersBuilder.ToString();
}

Zasób kanoniczny

Ta część ciągu podpisu reprezentuje konto magazynu objęte żądaniem. Pamiętaj, że identyfikator URI żądania to http://contosorest.blob.core.windows.net/?comp=list, z rzeczywistą nazwą konta (contosorest w tym przypadku). W tym przykładzie zwracana jest następująca wartość:

/contosorest/\ncomp:list

Jeśli masz parametry zapytania, ten przykład zawiera również te parametry. Oto kod, który obsługuje również dodatkowe parametry zapytania i parametry zapytania z wieloma wartościami. Pamiętaj, że kompilujesz ten kod, aby działał dla wszystkich interfejsów API REST. Chcesz uwzględnić wszystkie możliwości, nawet jeśli metoda ListContainers nie potrzebuje ich wszystkich.

private static string GetCanonicalizedResource(Uri address, string storageAccountName)
{
    // The absolute path will be "/" because for we're getting a list of containers.
    StringBuilder sb = new StringBuilder("/").Append(storageAccountName).Append(address.AbsolutePath);

    // Address.Query is the resource, such as "?comp=list".
    // This ends up with a NameValueCollection with 1 entry having key=comp, value=list.
    // It will have more entries if you have more query parameters.
    NameValueCollection values = HttpUtility.ParseQueryString(address.Query);

    foreach (var item in values.AllKeys.OrderBy(k => k))
    {
        sb.Append('\n').Append(item.ToLower()).Append(':').Append(values[item]);
    }

    return sb.ToString();
}

Teraz, po ustawieniu kanonicznych ciągów, przyjrzyjmy się, jak utworzyć sam nagłówek autoryzacji. Zacznij od utworzenia ciągu podpisu wiadomości w formacie StringToSign, który został wcześniej wyświetlony w tym artykule. To pojęcie jest łatwiejsze do wyjaśnienia przy użyciu komentarzy w kodzie, więc tutaj jest to ostateczna metoda zwracająca nagłówek autoryzacji:

internal static AuthenticationHeaderValue GetAuthorizationHeader(
    string storageAccountName, string storageAccountKey, DateTime now,
    HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
{
    // This is the raw representation of the message signature.
    HttpMethod method = httpRequestMessage.Method;
    String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
                method.ToString(),
                (method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
                  : httpRequestMessage.Content.Headers.ContentLength.ToString(),
                ifMatch,
                GetCanonicalizedHeaders(httpRequestMessage),
                GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
                md5);

    // Now turn it into a byte array.
    byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);

    // Create the HMACSHA256 version of the storage key.
    HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));

    // Compute the hash of the SignatureBytes and convert it to a base64 string.
    string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));

    // This is the actual header that will be added to the list of request headers.
    AuthenticationHeaderValue authHV = new AuthenticationHeaderValue("SharedKey",
        storageAccountName + ":" + signature);
    return authHV;
}

Po uruchomieniu tego kodu wynikowy element MessageSignature wygląda następująco:

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 17 Nov 2017 01:07:37 GMT\nx-ms-version:2017-07-29\n/contosorest/\ncomp:list

Oto końcowa wartość elementu AuthorizationHeader:

SharedKey contosorest:Ms5sfwkA8nqTRw7Uury4MPHqM6Rj2nfgbYNvUKOa67w=

AuthorizationHeader to ostatni nagłówek umieszczony w nagłówkach żądania przed opublikowaniem odpowiedzi.

Obejmuje to wszystko, co musisz wiedzieć, aby utworzyć klasę, za pomocą której można utworzyć żądanie wywołania interfejsów API REST usług storage.

Przykład: Wyświetlanie listy obiektów blob

Przyjrzyjmy się, jak zmienić kod w celu wywołania operacji List Blobs dla kontenera container-1. Ten kod jest prawie identyczny z kodem do wyświetlania listy kontenerów, a jedyną różnicą jest identyfikator URI i sposób analizowania odpowiedzi.

Jeśli przyjrzysz się dokumentacji referencyjnej listBlobs, okaże się, że metoda to GET, a identyfikator RequestURI to:

https://myaccount.blob.core.windows.net/container-1?restype=container&comp=list

W pliku ListContainersAsyncREST zmień kod, który ustawia identyfikator URI na interfejs API listBlobs. Nazwa kontenera to container-1.

String uri =
    string.Format("http://{0}.blob.core.windows.net/container-1?restype=container&comp=list",
      storageAccountName);

Następnie w miejscu obsługi odpowiedzi zmień kod, aby wyszukać obiekty blob zamiast kontenerów.

foreach (XElement container in x.Element("Blobs").Elements("Blob"))
{
    Console.WriteLine("Blob name = {0}", container.Element("Name").Value);
}

Po uruchomieniu tego przykładu uzyskasz wyniki podobne do następujących:

Nagłówki kanoniczne:

x-ms-date:Fri, 17 Nov 2017 05:16:48 GMT\nx-ms-version:2017-07-29\n

Zasób kanoniczny:

/contosorest/container-1\ncomp:list\nrestype:container

Podpis wiadomości:

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 17 Nov 2017 05:16:48 GMT
  \nx-ms-version:2017-07-29\n/contosorest/container-1\ncomp:list\nrestype:container

Nagłówek autoryzacji:

SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=

Następujące wartości pochodzą z programu Fiddler:

Żądanie:

GET http://contosorest.blob.core.windows.net/container-1?restype=container&comp=list HTTP/1.1

Nagłówki żądań:

x-ms-date: Fri, 17 Nov 2017 05:16:48 GMT
x-ms-version: 2017-07-29
Authorization: SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=
Host: contosorest.blob.core.windows.net
Connection: Keep-Alive

Kod stanu i nagłówki odpowiedzi zwrócone po wykonaniu:

HTTP/1.1 200 OK
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 7e9316da-001e-0037-4063-5faf9d000000
x-ms-version: 2017-07-29
Date: Fri, 17 Nov 2017 05:20:21 GMT
Content-Length: 1135

Treść odpowiedzi (XML): Ta odpowiedź XML zawiera listę obiektów blob i ich właściwości.

<?xml version="1.0" encoding="utf-8"?>
<EnumerationResults
    ServiceEndpoint="http://contosorest.blob.core.windows.net/" ContainerName="container-1">
    <Blobs>
        <Blob>
            <Name>DogInCatTree.png</Name>
            <Properties><Last-Modified>Fri, 17 Nov 2017 01:41:14 GMT</Last-Modified>
            <Etag>0x8D52D5C4A4C96B0</Etag>
            <Content-Length>419416</Content-Length>
            <Content-Type>image/png</Content-Type>
            <Content-Encoding />
            <Content-Language />
            <Content-MD5 />
            <Cache-Control />
            <Content-Disposition />
            <BlobType>BlockBlob</BlobType>
            <LeaseStatus>unlocked</LeaseStatus>
            <LeaseState>available</LeaseState>
            <ServerEncrypted>true</ServerEncrypted>
            </Properties>
        </Blob>
        <Blob>
            <Name>GuyEyeingOreos.png</Name>
            <Properties>
                <Last-Modified>Fri, 17 Nov 2017 01:41:14 GMT</Last-Modified>
                <Etag>0x8D52D5C4A25A6F6</Etag>
                <Content-Length>167464</Content-Length>
                <Content-Type>image/png</Content-Type>
                <Content-Encoding />
                <Content-Language />
                <Content-MD5 />
                <Cache-Control />
                <Content-Disposition />
                <BlobType>BlockBlob</BlobType>
                <LeaseStatus>unlocked</LeaseStatus>
                <LeaseState>available</LeaseState>
                <ServerEncrypted>true</ServerEncrypted>
            </Properties>
            </Blob>
        </Blobs>
    <NextMarker />
</EnumerationResults>

Podsumowanie

W tym artykule przedstawiono sposób tworzenia żądania do interfejsu API REST usługi Blob Storage. Za pomocą żądania można pobrać listę kontenerów lub listę obiektów blob w kontenerze. Wiesz już, jak utworzyć podpis autoryzacji dla wywołania interfejsu API REST i jak używać go w żądaniu REST. Na koniec wiesz już, jak zbadać odpowiedź.

Następne kroki