Signieren einer HTTP-Anforderung
In diesem Tutorial erfahren Sie, wie Sie eine HTTP-Anforderung mit einer HMAC-Signatur signieren.
Hinweis
Es wird dringend empfohlen, Azure SDKs zu verwenden. Bei dem hier beschriebenen Ansatz handelt es sich um eine Fallbackoption für den Fall, dass Azure SDKs nicht verwendet werden können.
Voraussetzungen
Führen Sie die folgenden Schritte aus, bevor Sie beginnen:
- Erstellen Sie ein Azure-Konto mit einem aktiven Abonnement. Details finden Sie auf der Seite zum Erstellen eines kostenloses Azure-Kontos.
- Installieren Sie Visual Studio.
- Erstellen Sie eine Azure Communication Services-Ressource. Ausführlichere Informationen hierzu finden Sie unter Schnellstart: Erstellen und Verwalten einer Communication Services-Ressource. Für dieses Tutorial benötigen Sie Ihren Ressourcenendpunkt (resourceEndpoint) und Ihren Ressourcenzugriffsschlüssel (resourceAccessKey).
Signieren einer HTTP-Anforderung mit C#
Bei der Authentifizierung per Zugriffsschlüssel wird ein gemeinsamer geheimer Schlüssel verwendet, um eine HMAC-Signatur für jede HTTP-Anforderung zu generieren. Diese Signatur wird mit dem SHA256-Algorithmus generiert und im Header Authorization
unter Verwendung des Schemas HMAC-SHA256
gesendet. Beispiel:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
hmac-sha256-signature
umfasst Folgendes:
- HTTP-Verb (z. B.
GET
oderPUT
) - HTTP-Anforderungspfad
- x-ms-date
- Host
- x-ms-content-sha256
Einrichten
In den folgenden Schritten wird beschrieben, wie Sie den Autorisierungsheader erstellen:
Erstellen einer neuen C#-Anwendung
Verwenden Sie in einem Konsolenfenster (z. B. cmd, PowerShell oder Bash) den Befehl dotnet new
zum Erstellen einer neuen Konsolen-App mit dem Namen SignHmacTutorial
. Dieser Befehl erstellt ein einfaches „Hallo Welt“-C#-Projekt mit einer einzigen Quelldatei: Program.cs.
dotnet new console -o SignHmacTutorial
Wechseln Sie zum Ordner der neu erstellten App. Verwenden Sie den Befehl dotnet build
, um die Anwendung zu kompilieren.
cd SignHmacTutorial
dotnet build
Installieren des Pakets
Installieren Sie das Paket Newtonsoft.Json
für die Textserialisierung.
dotnet add package Newtonsoft.Json
Aktualisieren Sie die Deklaration der Methode Main
, sodass asynchroner Code unterstützt wird. Verwenden Sie zum Einstieg den folgenden Code:
using System;
using System.Globalization;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace SignHmacTutorial
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Azure Communication Services - Sign an HTTP request Tutorial");
// Tutorial code goes here.
}
}
}
Erstellen einer Anforderungsnachricht
In diesem Beispiel wird eine Anforderung zum Erstellen einer neuen Identität mithilfe der Authentifizierungs-API (Version 2021-03-07
) von Communication Services signiert.
Fügen Sie der Main
-Methode den folgenden Code hinzu.
string resourceEndpoint = "resourceEndpoint";
// Create a uri you are going to call.
var requestUri = new Uri($"{resourceEndpoint}/identities?api-version=2021-03-07");
// Endpoint identities?api-version=2021-03-07 accepts list of scopes as a body
var body = new
{
createTokenWithScopes = new[] { "chat" }
};
var serializedBody = JsonConvert.SerializeObject(body);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri)
{
Content = new StringContent(serializedBody, Encoding.UTF8, "application/json")
};
Ersetzen Sie resourceEndpoint
durch den Wert Ihres tatsächlichen Ressourcenendpunkts.
Erstellen eines Inhaltshashs
Der Inhaltshash ist Teil Ihrer HMAC-Signatur. Verwenden Sie den folgenden Code, um den Inhaltshash zu berechnen. Diese Methode können Sie unter der Methode Main
zu Program.cs
hinzufügen:
static string ComputeContentHash(string content)
{
using var sha256 = SHA256.Create();
byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(content));
return Convert.ToBase64String(hashedBytes);
}
Berechnen einer Signatur
Verwenden Sie den folgenden Code, um eine Methode zum Berechnen der HMAC-Signatur zu erstellen.
static string ComputeSignature(string stringToSign)
{
string secret = "resourceAccessKey";
using var hmacsha256 = new HMACSHA256(Convert.FromBase64String(secret));
var bytes = Encoding.UTF8.GetBytes(stringToSign);
var hashedBytes = hmacsha256.ComputeHash(bytes);
return Convert.ToBase64String(hashedBytes);
}
Ersetzen Sie resourceAccessKey
durch den Zugriffsschlüssel Ihrer tatsächlichen Communication Services-Ressource.
Erstellen einer Autorisierungsheader-Zeichenfolge
In diesem Abschnitt wird die Zeichenfolge erstellt, die Sie später unserem Autorisierungsheader hinzufügen.
- Bereiten Sie Werte für die zu signierenden Header vor.
- Geben Sie den aktuellen Zeitstempel in der Zeitzone UTC (Koordinierte Weltzeit) an.
- Rufen Sie die Anforderungsstelle (DNS-Hostname oder IP-Adresse und Portnummer) ab.
- Berechnen Sie einen Inhaltshash.
- Bereiten Sie eine Zeichenfolge für die Signierung vor.
- Berechnen Sie die Signatur.
- Verketten Sie die Zeichenfolge für den Autorisierungsheader.
Fügen Sie der Main
-Methode den folgenden Code hinzu.
// Specify the 'x-ms-date' header as the current UTC timestamp according to the RFC1123 standard
var date = DateTimeOffset.UtcNow.ToString("r", CultureInfo.InvariantCulture);
// Get the host name corresponding with the 'host' header.
var host = requestUri.Authority;
// Compute a content hash for the 'x-ms-content-sha256' header.
var contentHash = ComputeContentHash(serializedBody);
// Prepare a string to sign.
var stringToSign = $"POST\n{requestUri.PathAndQuery}\n{date};{host};{contentHash}";
// Compute the signature.
var signature = ComputeSignature(stringToSign);
// Concatenate the string, which will be used in the authorization header.
var authorizationHeader = $"HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature={signature}";
Hinzufügen von Headern zu „requestMessage“
Verwenden Sie den folgenden Code, um Ihrer Anforderungsnachricht (requestMessage
) die erforderlichen Header hinzuzufügen:
// Add a date header.
requestMessage.Headers.Add("x-ms-date", date);
// Add a host header.
// In C#, the 'host' header is added automatically by the 'HttpClient'. However, this step may be required on other platforms such as Node.js.
// Add a content hash header.
requestMessage.Headers.Add("x-ms-content-sha256", contentHash);
// Add an authorization header.
requestMessage.Headers.Add("Authorization", authorizationHeader);
Testen des Clients
Rufen Sie den Endpunkt mithilfe von HttpClient
auf, und überprüfen Sie die Antwort.
HttpClient httpClient = new HttpClient
{
BaseAddress = requestUri
};
var response = await httpClient.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Voraussetzungen
Führen Sie die folgenden Schritte aus, bevor Sie beginnen:
- Erstellen Sie ein Azure-Konto mit einem aktiven Abonnement. Details finden Sie auf der Seite zum Erstellen eines kostenloses Azure-Kontos.
- Laden Sie Python herunter, und installieren Sie die Programmiersprache.
- Laden Sie Visual Studio Code oder eine andere IDE herunter, die Python unterstützt.
- Erstellen Sie eine Azure Communication Services-Ressource. Ausführlichere Informationen hierzu finden Sie unter Schnellstart: Erstellen und Verwalten einer Communication Services-Ressource. Sie benötigen Ihren resource_endpoint_name und Ihr resource_endpoint_secret für dieses Tutorial.
Signieren einer HTTP-Anforderung mit Python
Bei der Authentifizierung per Zugriffsschlüssel wird ein gemeinsamer geheimer Schlüssel verwendet, um eine HMAC-Signatur für jede HTTP-Anforderung zu generieren. Diese Signatur wird mit dem SHA256-Algorithmus generiert und im Header Authorization
unter Verwendung des Schemas HMAC-SHA256
gesendet. Beispiel:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
hmac-sha256-signature
umfasst Folgendes:
- HTTP-Verb (z. B.
GET
oderPUT
) - HTTP-Anforderungspfad
- x-ms-date
- Host
- x-ms-content-sha256
Einrichten
In den folgenden Schritten wird beschrieben, wie Sie den Autorisierungsheader erstellen:
Erstellen eines Python-Skripts
Öffnen Sie Visual Studio Code, eine andere IDE oder einen Editor Ihrer Wahl, und erstellen Sie eine neue Datei namens sign_hmac_tutorial.py
. Speichern Sie diese Datei in einem bekannten Ordner.
Hinzufügen der erforderlichen Importe
Aktualisieren Sie das Skript sign_hmac_tutorial.py
mit dem folgenden Code, um zu beginnen.
import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
from urllib import request
Aufbereiten von Daten für die Anforderung
In diesem Beispiel wird eine Anforderung zum Erstellen einer neuen Identität mithilfe der Authentifizierungs-API (Version 2021-03-07
) von Communication Services signiert.
Fügen Sie dem Skript sign_hmac_tutorial.py
den folgenden Code hinzu.
- Ersetzen Sie
resource_endpoint_name
durch den Namenswert Ihres tatsächlichen Ressourcenendpunkts. Diesen Wert finden Sie im Abschnitt „Übersicht“ Ihrer Azure Communication Services-Ressource. Es ist der Wert von „Endpunkt“ nach „https://“. - Ersetzen Sie
resource_endpoint_secret
durch den Geheimniswert Ihres tatsächlichen Ressourcenendpunkts. Diesen Wert finden Sie im Abschnitt „Schlüssel“ Ihrer Azure Communication Services-Ressource. Es ist der Wert von „Schlüssel“ – entweder primär oder sekundär.
host = "resource_endpoint_name"
resource_endpoint = f"https://{host}"
path_and_query = "/identities?api-version=2021-03-07"
secret = "resource_endpoint_secret"
# Create a uri you are going to call.
request_uri = f"{resource_endpoint}{path_and_query}"
# Endpoint identities?api-version=2021-03-07 accepts list of scopes as a body.
body = { "createTokenWithScopes": ["chat"] }
serialized_body = json.dumps(body)
content = serialized_body.encode("utf-8")
Erstellen eines Inhaltshashs
Der Inhaltshash ist Teil Ihrer HMAC-Signatur. Verwenden Sie den folgenden Code, um den Inhaltshash zu berechnen. Sie können diese Methode zum Skript sign_hmac_tutorial.py
hinzufügen.
def compute_content_hash(content):
sha_256 = hashlib.sha256()
sha_256.update(content)
hashed_bytes = sha_256.digest()
base64_encoded_bytes = base64.b64encode(hashed_bytes)
content_hash = base64_encoded_bytes.decode('utf-8')
return content_hash
Berechnen einer Signatur
Verwenden Sie den folgenden Code, um eine Methode zum Berechnen der HMAC-Signatur zu erstellen.
def compute_signature(string_to_sign, secret):
decoded_secret = base64.b64decode(secret)
encoded_string_to_sign = string_to_sign.encode('utf-8')
hashed_bytes = hmac.digest(decoded_secret, encoded_string_to_sign, digest=hashlib.sha256)
encoded_signature = base64.b64encode(hashed_bytes)
signature = encoded_signature.decode('utf-8')
return signature
Abrufen des aktuellen UTC-Zeitstempels gemäß dem RFC1123-Standard
Verwenden Sie den folgenden Code zum Abrufen des gewünschten Datumsformat unabhängig von den Gebietsschemaeinstellungen.
def format_date(dt):
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
utc = dt.utctimetuple()
return "{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT".format(
days[utc.tm_wday],
utc.tm_mday,
months[utc.tm_mon-1],
utc.tm_year,
utc.tm_hour,
utc.tm_min,
utc.tm_sec)
Erstellen einer Autorisierungsheader-Zeichenfolge
In diesem Abschnitt wird die Zeichenfolge erstellt, die Sie später unserem Autorisierungsheader hinzufügen.
- Bereiten Sie Werte für die zu signierenden Header vor.
- Geben Sie den aktuellen Zeitstempel in der Zeitzone UTC (Koordinierte Weltzeit) an.
- Rufen Sie die Anforderungsstelle (DNS-Hostname oder IP-Adresse und Portnummer) ab.
- Berechnen Sie einen Inhaltshash.
- Bereiten Sie eine Zeichenfolge für die Signierung vor.
- Berechnen Sie die Signatur.
- Verketten Sie die Zeichenfolge für den Autorisierungsheader.
Fügen Sie dem Skript sign_hmac_tutorial.py
den folgenden Code hinzu.
# Specify the 'x-ms-date' header as the current UTC timestamp according to the RFC1123 standard
utc_now = datetime.now(timezone.utc)
date = format_date(utc_now)
# Compute a content hash for the 'x-ms-content-sha256' header.
content_hash = compute_content_hash(content)
# Prepare a string to sign.
string_to_sign = f"POST\n{path_and_query}\n{date};{host};{content_hash}"
# Compute the signature.
signature = compute_signature(string_to_sign, secret)
# Concatenate the string, which will be used in the authorization header.
authorization_header = f"HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature={signature}"
Hinzufügen von Headern
Verwenden Sie den folgenden Code, um die erforderlichen Header hinzuzufügen.
request_headers = {}
# Add a date header.
request_headers["x-ms-date"] = date
# Add content hash header.
request_headers["x-ms-content-sha256"] = content_hash
# Add authorization header.
request_headers["Authorization"] = authorization_header
# Add content type header.
request_headers["Content-Type"] = "application/json"
Testen des Clients
Rufen Sie den Endpunkt auf, und überprüfen Sie die Antwort.
req = request.Request(request_uri, content, request_headers, method='POST')
with request.urlopen(req) as response:
response_string = json.load(response)
print(response_string)
Bereinigen von Ressourcen
Wenn Sie ein Communication Services-Abonnement bereinigen und entfernen möchten, löschen Sie die Ressource oder Ressourcengruppe. Wenn Sie die Ressourcengruppe löschen, werden auch alle anderen Ressourcen gelöscht, die ihr zugeordnet sind. Hier finden Sie weitere Informationen zum Bereinigen von Azure Communication Service-Ressourcen und zum Bereinigen von Azure Functions-Ressourcen.
Nächste Schritte
Weitere Möglichkeiten: