Windows Azure : Verwendung der REST API von Windows Azure Teil 2: Anfragen signieren

Von Mario Meir-Huber Autor Feed 28. October 2009 21:23

Dies ist der 2. Teil der Windows Azure REST Serie. Der 1. Teil ist hier. Im 1. Teil wurden die Grundlagen von REST und wie Windows Azure funktioniert erklärt. Dieser Teil soll nun die gesicherte Übertragung erläutern und wie diese erstellt wird. Hierfür sind einige Grundlagen hinsichtlich Verschlüsselung notwendig, welche im Posting erklärt werden. Dieses Beispiel kann übrigens auch einfach auf andere Webservices und Anwendungsfälle übertragen werden. Bei allgemeinen Techniken wird in diesem Artikel auf Wikipedia verwiesen. 

Das ganze bezeichnen wir nun mit “Request signieren”. Hierfür wollen wir eine Methode einführen, welche den Request signiert. Diese nennen wir “SignRequest”. Als Parameter brauchen wir den WebRequest, welcher signiert werden soll. Ferner wird der SharedKey (aus Windows Azure), der AccountKey und das HTTP Verb benötigt. Dies sieht dann folgendermaßen aus:

public static void SignRequest(ref HttpWebRequest TargetRequest, string SharedKey, string Account, string Verb)
{

Im Anschluss daran erstellen wir uns einen StringBuilder, welcher den Request zusammen setzt. Hierbei wird “SharedKey” als initialer Wert angegeben. Danach wird der Account und ein “:” eingefügt.

StringBuilder Authentification = new StringBuilder("SharedKey ", 128);
Authentification.Append(Account);
Authentification.Append(":");

Des weiteren muss auch das Datum eingefügt werden. Dies wird als UTC-Zeit ausgegeben. UTC steht für “Coordinated Universal Time” (Wikipedia). Dem TargetRequest (unsere Webanfrage) wird nun ein neuer Header mit der UTC Zeit eingefügt. Der Header hat den Schlüssel “x-ms-date”.

string DateNow = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
TargetRequest.Headers.Add("x-ms-date", DateNow);

Im Anschluss daran muss die Signatur erstellt werden. Auch hierfür verwenden wir einen StringBuilder.

StringBuilder Signature = new StringBuilder(Verb, 256);
Signature.Append('\n');

In den nächsten Schritten ist es notwendig, herauszufinden ob die Signatur einen Content-Type und eine Verschlüsselung verwendet. Dies muss in die Signatur eingefügt werden, da sonst ein Bad-Request entsteht. Diese können nicht ausgeführt werden.

Sollte der Request mit MD5 verschlüsselt sein, muss dies auch noch an die Signatur weitergegeben werden. Hierfür wird eine Abfrage an die Header des TargetRequests gestellt.

if (TargetRequest.Headers.AllKeys.Contains("Content-MD5"))
{
    Signature.Append(TargetRequest.Headers["Content-MD5"]);
}

Signature.Append('\n');

Wichtig ist auch noch der Content-Type. Content-Type stellt dar ob es sich um Text, XML oder ähnlichem handelt.

if (TargetRequest.Headers.AllKeys.Contains("Content-Type"))
{
    Signature.Append(TargetRequest.Headers["Content-Type"]);
}

Signature.Append("\n\n");

Wichtig ist auch, das eine Signatur jeweils einen Zeilenumbruch enthält. Danach muss noch jeder “x-ms-“ Eintrag in die Signatur eingegeben werden. Wenn wir zum letzten Beitrag zurück gehen, erinnern wir uns an folgende Signatur:

x-ms-version: 2009-04-14
x-ms-date: Tue, 18 Nov 2008 00:55:16 GMT Authorization: SharedKey myaccount:Q7tar7qqM2LD/Wey7OQNPP3hMNap9wjg+g9AlAYeFls=

Dies können wir sehr komfortabel mit folgender LinQ Abfrage lösen:

var query = from key in TargetRequest.Headers.AllKeys where key.StartsWith("x-ms-") orderby key select key.ToLower();

foreach (string key in query)
{
    Signature.Append(key);
    Signature.Append(':');
    Signature.Append(TargetRequest.Headers[key].Replace("\r\n", string.Empty).Trim());
    Signature.Append('\n');
}

Anschließend muss auch noch der Account und der Abfragepfad in die Signatur eingetragen werden.

Signature.Append('/');
Signature.Append(Account);
Signature.Append(TargetRequest.RequestUri.AbsolutePath);

Sollte ein “comp” in der URL vorkommen, muss dies der Signatur noch mitgegeben werden (was das genau ist wird im nächsten Posting erklärt). Hierfür verwenden wir das HttpUtility, welches aus dem Namespace “System.Web” kommt (hierfür ist die Referenz noch notwendig). Danach wird das “comp” Statement hinzugefügt, sollte dieses auch benötigt werden.

string comp = HttpUtility.ParseQueryString(TargetRequest.RequestUri.Query)["comp"];

if (!string.IsNullOrEmpty(comp))
{
    Signature.Append("?comp=");
    Signature.Append(comp);
}

Damit wäre auch bereits der Großteil der Signierung und Verschlüsselung gelöst. Damit es nun jedoch wirklich noch sicher ist, muss auch noch ein Verschlüsselungsalgorithmus verwendet werden. Hierfür gibt es in .NET mehrere Möglichkeiten:

  • Verschlüsseln mittels kryptografischen Hashs
  • Verschlüsseln mittels kryptografischer Signatur
  • Verschlüsseln mittels öffentlichem Schlüssel
  • Verschlüsseln mittels geheimen Schlüssel

Für Windows Azure wird eine Verschlüsselungstechnologie mittels kryptografischen Hashs gewählt, wobei HMACSHA256 zum Einsatz kommt. Hierfür wird die Signatur mittels diesem Algorithmus verschlüsselt.

HMACSHA256 Coding = new HMACSHA256(Convert.FromBase64String(SharedKey));
byte[] HashCode = Coding.ComputeHash(Encoding.UTF8.GetBytes(Signature.ToString()));
Authentification.Append(Convert.ToBase64String(HashCode));
TargetRequest.Headers.Add("Authorization", Authentification.ToString());

Wer mehr über Verschlüsselnung in .NET wissen will, sollte sich das MSDN-Kapitel zu Verschlüsselung ansehen.

Im nächsten und letzten Posting geht es darum, wie man eine MessageQueue in Windows Azure mit REST erstellen kann.

General | Cloud-Computing

Tags:  Feed Tag,  Feed Tag

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading



Windows Phone 7

Was halten Sie von Windows Phone 7



Show Results

Werbepause

CodeFest.at on Facebook

Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

www.microsoft.com/austria | © 2009 Microsoft Corporation. Alle Rechte vorbehalten.
BlogEngine.NET 1.5.0.7 powered by atwork