Een HTTP-aanvraag ondertekenen
In deze zelfstudie leert u hoe u een HTTP-aanvraag kunt ondertekenen met een HMAC-handtekening.
Notitie
We raden u ten zeere aan om Azure SDK's te gebruiken. De hier beschreven aanpak is een terugvaloptie voor gevallen waarin Azure SDK's om welke reden dan ook niet kunnen worden gebruikt.
Vereisten
Voordat u aan de slag gaat, moet u het volgende doen:
- Maak een Azure-account met een actief abonnement. Zie Gratis een account maken voor meer informatie.
- Installeer Visual Studio.
- Maak een Azure Communication Services-resource. Zie Een Azure Communication Services resource maken voor meer informatie. U moet uw resourceEndpoint en resourceAccessKey vastleggen voor deze zelfstudie.
Een HTTP-aanvraag ondertekenen met C #
Toegangssleutelverificatie maakt gebruik van een gedeelde geheime sleutel om een HMAC-handtekening te genereren voor elke HTTP-aanvraag. Deze handtekening wordt gegenereerd met het SHA256-algoritme en wordt verzonden in de Authorization
header met behulp van het HMAC-SHA256
schema. Bijvoorbeeld:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
De hmac-sha256-signature
bestaat uit:
- HTTP-werkwoord (bijvoorbeeld
GET
ofPUT
) - HTTP-aanvraagpad
- x-ms-date
- Host
- x-ms-content-sha256
Instellen
In de volgende stappen wordt beschreven hoe u de autorisatieheader maakt.
Een nieuwe C#-toepassing maken
Gebruik in een consolevenster, zoals cmd, PowerShell of Bash, de dotnet new
opdracht om een nieuwe console-app te maken met de naam SignHmacTutorial
. Met deze opdracht maakt u een eenvoudig Hallo wereld-C#-project met één bronbestand: Program.cs.
dotnet new console -o SignHmacTutorial
Wijzig uw map in de zojuist gemaakte app-map. Gebruik de dotnet build
opdracht om uw toepassing te compileren.
cd SignHmacTutorial
dotnet build
Het pakket installeren
Installeer het pakket Newtonsoft.Json
dat wordt gebruikt voor serialisatie van de hoofdtekst.
dotnet add package Newtonsoft.Json
Werk de Main
methodedeclaratie bij om asynchrone code te ondersteunen. Gebruik de volgende code om te beginnen.
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.
}
}
}
Een aanvraagbericht maken
In dit voorbeeld ondertekenen we een aanvraag om een nieuwe identiteit te maken met behulp van de Communication Services Authentication-API (versie 2021-03-07
).
Voeg de volgende code toe aan de methode Main
.
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")
};
Vervang door resourceEndpoint
de eindpuntwaarde van uw echte resource.
Een inhouds-hash maken
De inhouds-hash maakt deel uit van uw HMAC-handtekening. Gebruik de volgende code om de inhouds-hash te berekenen. U kunt deze methode toevoegen aan Progam.cs
onder de Main
-methode.
static string ComputeContentHash(string content)
{
using var sha256 = SHA256.Create();
byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(content));
return Convert.ToBase64String(hashedBytes);
}
Een handtekening berekenen
Gebruik de volgende code om een methode te maken voor het berekenen van uw HMAC-handtekening.
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);
}
Vervang door een toegangssleutel resourceAccessKey
van uw echte Communication Services-resource.
Een autorisatieheadertekenreeks maken
We gaan nu de tekenreeks maken die we aan onze autorisatie-header gaan toevoegen.
- Waarden voorbereiden voor de headers die moeten worden ondertekend.
- Geef de huidige tijdstempel op met behulp van de UTC-tijdzone (Coordinated Universal Time).
- Haal de aanvraaginstantie (DNS-hostnaam of IP-adres en het poortnummer) op.
- Een inhoudshash berekenen.
- Een tekenreeks voorbereiden om te ondertekenen.
- De handtekening berekenen.
- Voeg de tekenreeks samen, die wordt gebruikt in de autorisatieheader.
Voeg de volgende code toe aan de methode Main
.
// 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}";
Headers toevoegen aan requestMessage
Gebruik de volgende code om de vereiste headers toe te voegen aan uw requestMessage
.
// 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);
De client testen
Roep het eindpunt aan met behulp van HttpClient
en controleer het antwoord.
HttpClient httpClient = new HttpClient
{
BaseAddress = requestUri
};
var response = await httpClient.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Vereisten
Voordat u aan de slag gaat, moet u het volgende doen:
- Maak een Azure-account met een actief abonnement. Zie Gratis een account maken voor meer informatie.
- Download en installeer Python.
- Download en installeer Visual Studio Code of andere IDE die ondersteuning biedt voor Python.
- Maak een Azure Communication Services-resource. Zie Een Azure Communication Services resource maken voor meer informatie. Voor deze zelfstudie hebt u uw resource_endpoint_name en resource_endpoint_secret nodig.
Een HTTP-aanvraag ondertekenen met Python
Toegangssleutelverificatie maakt gebruik van een gedeelde geheime sleutel om een HMAC-handtekening te genereren voor elke HTTP-aanvraag. Deze handtekening wordt gegenereerd met het SHA256-algoritme en wordt verzonden in de Authorization
header met behulp van het HMAC-SHA256
schema. Bijvoorbeeld:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
De hmac-sha256-signature
bestaat uit:
- HTTP-werkwoord (bijvoorbeeld
GET
ofPUT
) - HTTP-aanvraagpad
- x-ms-date
- Host
- x-ms-content-sha256
Instellen
In de volgende stappen wordt beschreven hoe u de autorisatieheader maakt.
Een nieuw Python-script maken
Open Visual Studio Code of een andere IDE of editor van uw keuze en maak een nieuw bestand met de naam sign_hmac_tutorial.py
. Sla dit bestand op in een bekende map.
Benodigde importbewerkingen toevoegen
Werk het sign_hmac_tutorial.py
script bij met de volgende code om te beginnen.
import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
from urllib import request
Gegevens voorbereiden voor de aanvraag
In dit voorbeeld ondertekenen we een aanvraag voor het maken van een nieuwe identiteit met behulp van de Communication Services Authentication-API (versie 2021-03-07
).
Voeg de volgende code toe aan het sign_hmac_tutorial.py
script.
- Vervang door
resource_endpoint_name
de waarde van het echte resource-eindpunt. Deze waarde vindt u in de sectie Overzicht van uw Azure Communication Services-resource. Dit is de waarde van 'Eindpunt' na 'https://'. - Vervang door
resource_endpoint_secret
de waarde van het eindpuntgeheim van uw echte resource. Deze waarde vindt u in de sectie Sleutels van uw Azure Communication Services-resource. Dit is de waarde van 'Sleutel', ofwel primair of secundair.
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")
Een inhouds-hash maken
De inhouds-hash maakt deel uit van uw HMAC-handtekening. Gebruik de volgende code om de inhouds-hash te berekenen. U kunt deze methode toevoegen aan een sign_hmac_tutorial.py
script.
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
Een handtekening berekenen
Gebruik de volgende code om een methode te maken voor het berekenen van uw HMAC-handtekening.
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
Huidige UTC-tijdstempel ophalen volgens de RFC1123-standaard
Gebruik de volgende code om de gewenste datumnotatie op te halen, onafhankelijk van landinstellingen.
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)
Een autorisatieheadertekenreeks maken
We gaan nu de tekenreeks maken die we aan onze autorisatieheader gaan toevoegen.
- Waarden voorbereiden voor de headers die moeten worden ondertekend.
- Geef de huidige tijdstempel op met behulp van de UTC-tijdzone (Coordinated Universal Time).
- Haal de aanvraaginstantie (DNS-hostnaam of IP-adres en het poortnummer) op.
- Een inhoudshash berekenen.
- Een tekenreeks voorbereiden om te ondertekenen.
- De handtekening berekenen.
- Voeg de tekenreeks samen, die wordt gebruikt in de autorisatieheader.
Voeg de volgende code toe aan het sign_hmac_tutorial.py
script.
# 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}"
Headers toevoegen
Gebruik de volgende code om de vereiste headers toe te voegen.
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"
De client testen
Roep het eindpunt aan en controleer het antwoord.
req = request.Request(request_uri, content, request_headers, method='POST')
with request.urlopen(req) as response:
response_string = json.load(response)
print(response_string)
Resources opschonen
Als u een Communication Services-abonnement wilt opschonen en verwijderen, verwijdert u de resource of resourcegroep. Als u de resourcegroep verwijdert, worden ook alle bijbehorende resources verwijderd. Meer informatie over het opschonen van Azure Communication Services resources en het opschonen van Azure Functions resources.
Volgende stappen
U kunt ook het volgende doen: