Delen via


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:

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 of PUT)
  • 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.

  1. Waarden voorbereiden voor de headers die moeten worden ondertekend.
    1. Geef de huidige tijdstempel op met behulp van de UTC-tijdzone (Coordinated Universal Time).
    2. Haal de aanvraaginstantie (DNS-hostnaam of IP-adres en het poortnummer) op.
    3. Een inhoudshash berekenen.
  2. Een tekenreeks voorbereiden om te ondertekenen.
  3. De handtekening berekenen.
  4. 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 HttpClienten 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:

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 of PUT)
  • 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.

  1. Waarden voorbereiden voor de headers die moeten worden ondertekend.
    1. Geef de huidige tijdstempel op met behulp van de UTC-tijdzone (Coordinated Universal Time).
    2. Haal de aanvraaginstantie (DNS-hostnaam of IP-adres en het poortnummer) op.
    3. Een inhoudshash berekenen.
  2. Een tekenreeks voorbereiden om te ondertekenen.
  3. De handtekening berekenen.
  4. 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: