Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird gezeigt, wie Sie einen Azure Storage REST-API-Vorgang aufrufen, indem Sie eine autorisierte REST-Anforderung mit C# erstellen. Nachdem Sie erfahren haben, wie Sie einen REST-API-Vorgang für Blob Storage aufrufen, können Sie ähnliche Schritte für alle anderen Azure Storage REST-Vorgänge ausführen.
Voraussetzungen
Die Beispielanwendung listet die Blob-Container für ein Speicherkonto auf. Um den Code in diesem Artikel auszuprobieren, benötigen Sie die folgenden Elemente:
Installieren Sie Visual Studio , und fügen Sie die Azure-Entwicklungsarbeitslast ein. Dieses Beispiel wurde mit Visual Studio 2019 erstellt. Wenn Sie eine andere Version verwenden, kann die Anleitung geringfügig variieren.
Ein Azure-Abonnement. Wenn Sie noch kein Azure-Abonnement haben, erstellen Sie ein kostenloses Konto, bevor Sie beginnen.
Ein allgemeines Speicherkonto. Wenn Sie noch kein Speicherkonto haben, lesen Sie "Erstellen eines Speicherkontos".
Das Beispiel in diesem Artikel zeigt, wie sie die Container in einem Speicherkonto auflisten. Um die Ausgabe anzuzeigen, fügen Sie einige Blob-Container zum Speicherkonto hinzu, bevor Sie beginnen.
Herunterladen der Beispielanwendung
Die Beispielanwendung ist eine Konsolenanwendung, die in C# geschrieben wurde.
Verwenden Sie Git , um eine Kopie der Anwendung in Ihre Entwicklungsumgebung herunterzuladen.
git clone https://github.com/Azure-Samples/storage-dotnet-rest-api-with-auth.git
Mit diesem Befehl wird das Repository in Ihren lokalen Git-Ordner geklont. Navigieren Sie zum Öffnen der Visual Studio-Lösung zum Ordner "storage-dotnet-rest-api-with-auth", und öffnen Sie StorageRestApiAuth.sln.
Informationen zu REST
Representational State Transfer (REST) ist eine Architektur, mit der Sie mit einem Dienst über ein Internetprotokoll wie HTTP/HTTPS interagieren können. REST ist unabhängig von der Software, die auf dem Server oder client ausgeführt wird. Die REST-API kann von jeder Plattform aufgerufen werden, die HTTP/HTTPS unterstützt. Sie können eine Anwendung schreiben, die auf einem Mac, Windows, Linux, einem Android-Smartphone oder -Tablet, iPhone, iPod oder Website ausgeführt wird, und dieselbe REST-API für alle diese Plattformen verwenden.
Ein Aufruf der REST-API besteht aus einer Vom Client gestellten Anforderung und einer antwort, die vom Dienst zurückgegeben wird. In der Anforderung senden Sie eine URL mit Informationen dazu, welchen Vorgang Sie aufrufen möchten, die zu bearbeitende Ressource, alle Abfrageparameter und Header sowie je nach aufgerufenem Vorgang eine Nutzlast von Daten. Die Antwort des Diensts enthält einen Statuscode, eine Reihe von Antwortheadern und abhängig von dem aufgerufenen Vorgang eine Nutzlast von Daten.
Informationen zur Beispielanwendung
Die Beispielanwendung listet die Container in einem Speicherkonto auf. Sobald Sie verstehen, wie die Informationen in der REST-API-Dokumentation mit Ihrem tatsächlichen Code korreliert, sind andere REST-Aufrufe einfacher zu ermitteln.
Wenn Sie sich die BLOB-Dienst-REST-API ansehen, werden alle Vorgänge angezeigt, die Sie im Blob-Speicher ausführen können. Die Speicherclientbibliotheken sind Wrapper um die REST-APIs herum, wodurch der Zugriff auf Speicherressourcen einfach ist, ohne die REST-APIs direkt zu verwenden. Manchmal möchten Sie jedoch die REST-API anstelle einer Speicherclientbibliothek verwenden.
Vorgang "Container auflisten"
Dieser Artikel konzentriert sich auf den Vorgang "Listencontainer" . Die folgenden Informationen helfen Ihnen, einige der Felder in der Anforderung und Antwort zu verstehen.
Anforderungsmethode: GET. Dieses Verb ist die HTTP-Methode, die Sie als Eigenschaft des Anforderungsobjekts angeben. Andere Werte für dieses Verb sind HEAD, PUT und DELETE, abhängig von der API, die Sie aufrufen.
Anforderungs-URI: https://myaccount.blob.core.windows.net/?comp=list. Der Anforderungs-URI wird aus dem Blob Storage-Kontoendpunkt https://myaccount.blob.core.windows.net und der Ressourcenzeichenfolge /?comp=list erstellt.
URI-Parameter: Es gibt zusätzliche Abfrageparameter, die Sie beim Aufrufen von ListContainers verwenden können. Einige dieser Parameter sind Timeout für den Aufruf (in Sekunden) und das Präfix, das zum Filtern verwendet wird.
Ein weiterer hilfreicher Parameter ist maxresults: Wenn mehr Container als dieser Wert verfügbar sind, enthält der Antworttext ein NextMarker-Element , das den nächsten Container angibt, der für die nächste Anforderung zurückgegeben werden soll. Um dieses Feature zu verwenden, geben Sie den NextMarker-Wert als Markerparameter im URI an, wenn Sie die nächste Anforderung ausführen. Wenn Sie dieses Feature verwenden, ist es vergleichbar mit dem Durchblättern der Ergebnisse.
Um zusätzliche Parameter zu verwenden, fügen Sie sie an die Ressourcenzeichenfolge mit dem Wert an, wie im folgenden Beispiel:
/?comp=list&timeout=60&maxresults=100
Anforderungsheader: In diesem Abschnitt werden die erforderlichen und optionalen Anforderungsheader aufgelistet. Drei der Header sind erforderlich: ein Autorisierungsheader , x-ms-date (enthält die UTC-Zeit für die Anforderung) und x-ms-version (gibt die zu verwendende Version der REST-API an). Das Einschließen der x-ms-client-request-ID in die Header ist optional. Sie können den Wert für dieses Feld auf beliebig festlegen, und er wird in die Speicheranalyseprotokolle geschrieben, wenn die Protokollierung aktiviert ist.
Anforderungstext: Es gibt keinen Anforderungstext für ListContainers. Der Anforderungstext wird für alle PUT-Vorgänge verwendet, wenn Blobs hochgeladen werden (einschließlich „SetContainerAccessPolicy“). Der Anforderungstext ermöglicht es Ihnen, eine XML-Liste der anzuwendenden gespeicherten Zugriffsrichtlinien zu senden. Gespeicherte Zugriffsrichtlinien werden im Artikel Using Shared Access Signatures (SAS) erläutert.
Antwortstatuscode: Teilt alle Statuscodes mit, die Sie kennen müssen. In diesem Beispiel ist ein HTTP-Statuscode von 200 ok. Eine vollständige Liste der HTTP-Statuscodes finden Sie in den Statuscodedefinitionen. Informationen zum Anzeigen von Fehlercodes speziell für die Speicher-REST-APIs finden Sie unter "Allgemeine REST-API-Fehlercodes".
Antwortkopfzeilen: Dazu gehören Content-Type; x-ms-request-id, die von Ihnen übergebene Anforderungs-ID; x-ms-version, welche die verwendete Version des Blob-Dienstes angibt; und das Datum, das in UTC ist und angibt, wann die Anforderung gestellt wurde.
Antworttext: Dieses Feld ist eine XML-Struktur, die die angeforderten Daten bereitstellt. In diesem Beispiel ist die Antwort eine Liste der Container und deren Eigenschaften.
Erstellen der REST-Anforderung
Verwenden Sie bei der Ausführung in der Produktion aus Sicherheitsgründen nicht HTTP, sondern immer HTTPS. Für diese Übung verwenden wir HTTP, damit Sie die Anforderungs- und Antwortdaten anzeigen können. Um die Anforderungs- und Antwortinformationen in den tatsächlichen REST-Aufrufen anzuzeigen, können Sie Fiddler oder eine ähnliche Anwendung herunterladen. In der Visual Studio-Projektmappe sind der Name und der Schlüssel des Speicherkontos in der Klasse hartcodiert. Die ListContainersAsyncREST-Methode übergibt den Speicherkontonamen und den Speicherkontoschlüssel an die Methoden, mit denen die verschiedenen Komponenten der REST-Anforderung erstellt werden. In einer realen Anwendung befinden sich der Name und der Schlüssel des Speicherkontos in einer Konfigurationsdatei, Umgebungsvariablen oder werden aus einem Azure Key Vault abgerufen.
In unserem Beispielprojekt befindet sich der Code zum Erstellen des Autorisierungsheaders in einer separaten Klasse. Die Idee ist, dass Sie die gesamte Klasse nehmen und sie zu Ihrer eigenen Lösung hinzufügen und sie "wie sie ist" verwenden können. Der Autorisierungs-Header-Code funktioniert für die meisten REST-API-Aufrufe an Azure Storage.
Um die Anforderung zu erstellen, bei der es sich um ein HttpRequestMessage-Objekt handelt, wechseln Sie in Program.cs zu ListContainersAsyncREST. Die Schritte zum Erstellen der Anforderung sind:
- Erstellen Sie den URI, der zum Aufrufen des Diensts verwendet werden soll.
- Erstellen Sie das HttpRequestMessage-Objekt, und legen Sie die Nutzlast fest. Die Nutzlast ist null für ListContainersAsyncREST, da nichts übergeben wird.
- Fügen Sie die Anforderungsheader für x-ms-date und x-ms-version hinzu.
- Rufen Sie den Autorisierungsheader ab, und fügen Sie ihn hinzu.
Einige grundlegende Informationen, die Sie benötigen:
- Für ListContainers ist die Methode
GET. Dieser Wert wird beim Instanziieren der Anforderung festgelegt. - Die Ressource ist der Abfrageteil des URI, der angibt, welche API aufgerufen wird, sodass der Wert lautet
/?comp=list. Wie bereits erwähnt, befindet sich die Ressource auf der Referenzdokumentationsseite, auf der die Informationen zur ListContainers-API angezeigt werden. - Der URI wird erstellt, indem der Blob-Dienstendpunkt für dieses Speicherkonto erstellt und die Ressource verkettet wird. Der Wert für den Anforderungs-URI lautet
http://contosorest.blob.core.windows.net/?comp=list. - Für ListContainers ist requestBody null, und es gibt keine zusätzlichen Header.
Verschiedene APIs können andere Parameter aufweisen, die übergeben werden sollen, z. B. ifMatch. Ein Beispiel für die Verwendung von ifMatch ist beim Aufrufen von PutBlob. In diesem Fall legen Sie "ifMatch" auf ein eTag fest, und es aktualisiert nur den Blob, wenn das von Ihnen bereitgestellte eTag mit dem aktuellen eTag im Blob übereinstimmt. Wenn eine andere Person das Blob seit dem Abrufen des eTags aktualisiert hat, wird ihre Änderung nicht überschrieben.
Legen Sie zuerst die uri und die requestPayload fest.
// 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;
Instanziieren Sie als Nächstes die Anforderung, indem Sie die Methode auf GET festlegen und den URI angeben.
// Instantiate the request message with a null payload.
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{ Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{
Fügen Sie die Anforderungsheader für x-ms-date und x-ms-version hinzu. An dieser Stelle im Code fügen Sie auch alle zusätzlichen HTTP-Anforderungsheader hinzu, die für den Aufruf erforderlich sind. In diesem Beispiel gibt es keine zusätzlichen Kopfzeilen. Ein Beispiel für eine API, die zusätzliche Header übergibt, ist der ACL-Vorgang "Container festlegen". Dieser API-Aufruf fügt einen Header namens "x-ms-blob-public-access" und den Wert für die Zugriffsebene hinzu.
// 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.
Rufen Sie die Methode auf, mit der der Autorisierungsheader erstellt wird, und fügen Sie sie den Anforderungsheadern hinzu. Der Autorisierungsheader wird im weiteren Verlauf des Artikels erstellt. Der Methodenname ist "GetAuthorizationHeader", den Sie in diesem Codeausschnitt sehen können:
// Get the authorization header and add it.
httpRequestMessage.Headers.Authorization = AzureStorageAuthenticationHelper.GetAuthorizationHeader(
storageAccountName, storageAccountKey, now, httpRequestMessage);
An diesem Punkt enthält httpRequestMessage die REST-Anforderung, vollständig mit den Autorisierungsheadern.
Senden der Anforderung
Nachdem Sie die Anforderung erstellt haben, können Sie die SendAsync-Methode aufrufen, um sie an Azure Storage zu senden. Überprüfen Sie, ob der Wert des Antwortstatuscodes 200 ist, was bedeutet, dass der Vorgang erfolgreich war. Analysieren Sie als Nächstes die Antwort. In diesem Fall erhalten Sie eine XML-Liste von Containern. Sehen wir uns den Code zum Aufrufen der GetRESTRequest-Methode an, um die Anforderung zu erstellen, die Anforderung auszuführen, und überprüfen Sie dann die Antwort auf die Liste der Container.
// 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);
}
}
}
}
Wenn Sie einen Netzwerksniffer wie Fiddler beim Aufruf von SendAsync ausführen, können Sie die Anforderungs- und Antwortinformationen anzeigen. Sehen wir uns an. Der Name des Speicherkontos lautet "contosorest".
Anforderung:
GET /?comp=list HTTP/1.1
Anforderungsheader:
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
Statuscode und Antwortheader, die nach der Ausführung zurückgegeben werden:
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
Antworttext (XML): Für den Vorgang "Listencontainer" zeigt dies die Liste der Container und deren Eigenschaften an.
<?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>
Nachdem Sie nun verstehen, wie Sie die Anforderung erstellen, den Dienst aufrufen und die Ergebnisse analysieren, erfahren Sie, wie Sie den Autorisierungsheader erstellen.
Erstellen des Autorisierungsheaders
Tipp
Azure Storage unterstützt die Microsoft Entra-Integration für Blobs und Warteschlangen. Die Microsoft Entra-ID bietet eine wesentlich einfachere Oberfläche für die Autorisierung einer Anforderung an Azure Storage. Weitere Informationen zur Verwendung der Microsoft Entra-ID zum Autorisieren von REST-Vorgängen finden Sie unter "Autorisieren mit Microsoft Entra-ID". Eine Übersicht über die Microsoft Entra-Integration in Azure Storage finden Sie unter Authentifizieren des Zugriffs auf Azure Storage mithilfe der Microsoft Entra-ID.
Weitere Informationen zu Autorisierungskonzepten finden Sie unter Autorisieren von Anforderungen an Azure Storage.
Lassen Sie uns diesen Artikel auf genau benötigte Elemente destillieren und den Code anzeigen.
Verwenden Sie zunächst die Autorisierung für gemeinsam genutzte Schlüssel. Das Autorisierungsheaderformat sieht wie folgt aus:
Authorization="SharedKey <storage account name>:<signature>"
Das Signaturfeld ist ein hashbasierter Nachrichtenauthentifizierungscode (HMAC), der aus der Anforderung erstellt und mithilfe des SHA256-Algorithmus berechnet und dann mithilfe der Base64-Codierung codiert wird.
Dieser Codeausschnitt zeigt das Format der Signaturzeichenfolge für gemeinsam genutzte Schlüssel:
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;
Für Blob-Speicher geben Sie VERB, md5, Inhaltslänge, kanonische Header und kanonische Ressource an. Sie können die anderen für dieses Beispiel leer lassen, aber geben Sie \n an, dass sie leer sind.
Die Kanonisierung ist ein Prozess der Standardisierung von Daten mit mehr als einer möglichen Darstellung. In diesem Fall standardisieren Sie die Header und die Ressource. Die kanonischen Kopfzeilen sind die Kopfzeilen, die mit "x-ms-" beginnen. Die kanonisierte Ressource ist der URI der Ressource, einschließlich des Speicherkontonamens und aller Abfrageparameter (wie ?comp=list). Die kanonische Ressource enthält auch alle zusätzlichen Abfrageparameter, die Sie möglicherweise hinzugefügt haben, wie z. B. timeout=60.
Beginnen wir mit den beiden kanonischen Feldern, da sie zum Erstellen des Autorisierungsheaders erforderlich sind.
Kanonische Kopfzeilen
Rufen Sie zum Erstellen dieses Werts die Kopfzeilen ab, die mit "x-ms-" beginnen, und sortieren Sie sie, und formatieren Sie sie dann in eine Zeichenfolge mit [key:value\n] Instanzen, verkettet in einer Zeichenfolge. In diesem Beispiel sehen die kanonischen Kopfzeilen wie folgt aus:
x-ms-date:Fri, 17 Nov 2017 00:44:48 GMT\nx-ms-version:2017-07-29\n
Hier sehen Sie den Code, der zum Erstellen dieser Ausgabe verwendet wird:
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();
}
Vereinheitlichte Ressource
Dieser Teil der Signaturzeichenfolge stellt das Speicherkonto dar, das von der Anforderung adressiert wird. Denken Sie daran, dass der Anforderungs-URI http://contosorest.blob.core.windows.net/?comp=list mit dem tatsächlichen Kontonamen (contosorest in diesem Fall) ist. In diesem Beispiel wird dies zurückgegeben:
/contosorest/\ncomp:list
Wenn Sie Abfrageparameter haben, enthält dieses Beispiel auch diese Parameter. Hier ist der Code, der auch zusätzliche Abfrageparameter und Abfrageparameter mit mehreren Werten behandelt. Denken Sie daran, dass Sie diesen Code für alle REST-APIs erstellen. Sie möchten alle Möglichkeiten einbeziehen, auch wenn die ListContainers-Methode nicht alle benötigt.
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();
}
Nachdem die kanonisierten Zeichenfolgen festgelegt wurden, schauen wir uns an, wie der Autorisierungsheader selbst erstellt wird. Zunächst erstellen Sie eine Zeichenfolge der Nachrichtensignatur im Format von StringToSign, das zuvor in diesem Artikel angezeigt wurde. Dieses Konzept ist einfacher zu erläutern, indem Kommentare im Code verwendet werden. Hier ist also die endgültige Methode, die den Autorisierungsheader zurückgibt:
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;
}
Wenn Sie diesen Code ausführen, sieht das resultierende MessageSignature wie im folgenden Beispiel aus:
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
Hier sehen Sie den endgültigen Wert für AuthorizationHeader:
SharedKey contosorest:Ms5sfwkA8nqTRw7Uury4MPHqM6Rj2nfgbYNvUKOa67w=
Der AuthorizationHeader ist der letzte Header, der in den Anforderungsheadern platziert wird, bevor die Antwort veröffentlicht wird.
Dies deckt alles ab, was Sie wissen müssen, um eine Klasse zusammenzustellen, mit der Sie eine Anforderung erstellen können, um die REST-APIs der Speicherdienste aufzurufen.
Beispiel: Auflisten von Blobs
Sehen wir uns an, wie Sie den Code ändern, um den Listen-Blobs-Vorgang für Containercontainer-1 aufzurufen. Dieser Code ist fast identisch mit dem Code zum Auflisten von Containern, die einzigen Unterschiede sind der URI und die Analyse der Antwort.
Wenn Sie sich die Referenzdokumentation für ListBlobs ansehen, stellen Sie fest, dass die Methode GET ist und der RequestURI lautet:
https://myaccount.blob.core.windows.net/container-1?restype=container&comp=list
Ändern Sie im Abschnitt ListContainersAsyncREST den Code, der den URI der API zu ListBlobs festlegt. Der Containername ist container-1.
String uri =
string.Format("http://{0}.blob.core.windows.net/container-1?restype=container&comp=list",
storageAccountName);
Ändern Sie dann an der Stelle, an der Sie die Antwort behandeln, den Code so, dass er anstelle von Containern nach Blobs sucht.
foreach (XElement container in x.Element("Blobs").Elements("Blob"))
{
Console.WriteLine("Blob name = {0}", container.Element("Name").Value);
}
Wenn Sie dieses Beispiel ausführen, erhalten Sie Ergebnisse wie die folgenden:
Kanonische Kopfzeilen:
x-ms-date:Fri, 17 Nov 2017 05:16:48 GMT\nx-ms-version:2017-07-29\n
Kanonisierte Ressource:
/contosorest/container-1\ncomp:list\nrestype:container
Nachrichtensignatur:
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
Autorisierungsheader:
SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=
Die folgenden Werte stammen aus Fiddler:
Anforderung:
GET http://contosorest.blob.core.windows.net/container-1?restype=container&comp=list HTTP/1.1
Anforderungsheader:
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
Statuscode und Antwortheader, die nach der Ausführung zurückgegeben werden:
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
Antworttext (XML): Diese XML-Antwort zeigt die Liste der Blobs und deren Eigenschaften an.
<?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>
Zusammenfassung
In diesem Artikel haben Sie erfahren, wie Sie eine Anforderung an die BLOB-Speicher-REST-API senden. Mit der Anforderung können Sie eine Liste von Containern oder eine Liste von Blobs in einem Container abrufen. Sie haben erfahren, wie Sie die Autorisierungssignatur für den REST-API-Aufruf erstellen und wie sie in der REST-Anforderung verwendet werden. Schließlich haben Sie gelernt, wie Sie die Antwort untersuchen.