Dela via


Signera en HTTP-begäran

I den här självstudien får du lära dig hur du signerar en HTTP-begäran med en HMAC-signatur.

Kommentar

Vi rekommenderar starkt att du använder Azure SDK:er. Metoden som beskrivs här är ett reservalternativ för fall där Azure SDK:er inte kan användas av någon anledning.

Förutsättningar

Innan du kommer igång måste du:

Signera en HTTP-begäran med C#

Åtkomstnyckelautentisering använder en delad hemlig nyckel för att generera en HMAC-signatur för varje HTTP-begäran. Den här signaturen genereras med SHA256-algoritmen och skickas i Authorization rubriken med hjälp av schemat HMAC-SHA256 . Till exempel:

Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"

hmac-sha256-signature består av:

  • HTTP-verb (till exempel GET eller PUT)
  • SÖKVÄG för HTTP-begäran
  • x-ms-date
  • Host
  • x-ms-content-sha256

Ställ in

Följande steg beskriver hur du skapar auktoriseringshuvudet.

Skapa ett nytt C#-program

I ett konsolfönster, till exempel cmd, PowerShell eller Bash, använder du dotnet new kommandot för att skapa en ny konsolapp med namnet SignHmacTutorial. Det här kommandot skapar ett enkelt "Hello World"-C#-projekt med en enda källfil: Program.cs.

dotnet new console -o SignHmacTutorial

Ändra katalogen till den nyligen skapade appmappen. dotnet build Använd kommandot för att kompilera programmet.

cd SignHmacTutorial
dotnet build

Installera -paketet

Installera paketet Newtonsoft.Json som används för brödtexts serialisering.

dotnet add package Newtonsoft.Json

Uppdatera metoddeklarationen så att den Main stöder asynkron kod. Använd följande kod för att börja.

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.
        }
    }
}

Skapa ett meddelande om begäran

I det här exemplet signerar vi en begäran om att skapa en ny identitet med hjälp av API:et för Communication Services-autentisering (version 2021-03-07).

Lägg till följande kod i metoden 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")
};

Ersätt resourceEndpoint med det verkliga resursslutpunktsvärdet.

Skapa en innehållshash

Innehållshash är en del av din HMAC-signatur. Använd följande kod för att beräkna innehållshashen. Du kan lägga till den här metoden Program.cs i Main under -metoden.

static string ComputeContentHash(string content)
{
    using var sha256 = SHA256.Create();
    byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(content));
    return Convert.ToBase64String(hashedBytes);
}

Beräkna en signatur

Använd följande kod för att skapa en metod för att beräkna din HMAC-signatur.

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);
}

Ersätt resourceAccessKey med en åtkomstnyckel för din verkliga Communication Services-resurs.

Skapa en auktoriseringshuvudsträng

Nu ska vi konstruera strängen som vi ska lägga till i vårt auktoriseringshuvud.

  1. Förbered värden för rubrikerna som ska signeras.
    1. Ange den aktuella tidsstämpeln med hjälp av tidszonen Coordinated Universal Time (UTC).
    2. Hämta utfärdaren för begäran (DNS-värdnamnet eller IP-adressen och portnumret).
    3. Beräkna en innehållshash.
  2. Förbered en sträng att signera.
  3. Beräkna signaturen.
  4. Sammanfoga strängen, som ska användas i auktoriseringshuvudet.

Lägg till följande kod i metoden 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}";

Lägga till rubriker i requestMessage

Använd följande kod för att lägga till de nödvändiga rubrikerna i din 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);

Testa klienten

Anropa slutpunkten med hjälp HttpClientav och kontrollera svaret.

HttpClient httpClient = new HttpClient
{
    BaseAddress = requestUri
};
var response = await httpClient.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);

Förutsättningar

Innan du kommer igång måste du:

Signera en HTTP-begäran med Python

Åtkomstnyckelautentisering använder en delad hemlig nyckel för att generera en HMAC-signatur för varje HTTP-begäran. Den här signaturen genereras med SHA256-algoritmen och skickas i Authorization rubriken med hjälp av schemat HMAC-SHA256 . Till exempel:

Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"

hmac-sha256-signature består av:

  • HTTP-verb (till exempel GET eller PUT)
  • SÖKVÄG för HTTP-begäran
  • x-ms-date
  • Host
  • x-ms-content-sha256

Ställ in

Följande steg beskriver hur du skapar auktoriseringshuvudet.

Skapa ett nytt Python-skript

Öppna Visual Studio Code eller valfri annan IDE eller redigerare och skapa en ny fil med namnet sign_hmac_tutorial.py. Spara den här filen i en känd mapp.

Lägga till nödvändiga importer

Uppdatera skriptet sign_hmac_tutorial.py med följande kod för att börja.

import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
from urllib import request

Förbereda data för begäran

I det här exemplet signerar vi en begäran om att skapa en ny identitet med hjälp av API :et för autentisering av kommunikationstjänster (version 2021-03-07).

Lägg till följande kod i skriptet sign_hmac_tutorial.py .

  • Ersätt resource_endpoint_name med det verkliga värdet för resursslutpunktens namn. Det här värdet finns i avsnittet Översikt över din Azure Communication Services-resurs. Det är värdet för "Slutpunkt" efter "https://".
  • Ersätt resource_endpoint_secret med ditt verkliga slutpunktshemlighetsvärde för resursen. Det här värdet finns i avsnittet Nycklar i din Azure Communication Services-resurs. Det är värdet för "Key" – antingen primär eller 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")

Skapa en innehållshash

Innehållshash är en del av din HMAC-signatur. Använd följande kod för att beräkna innehållshashen. Du kan lägga till den här metoden i sign_hmac_tutorial.py skriptet.

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

Beräkna en signatur

Använd följande kod för att skapa en metod för att beräkna din HMAC-signatur.

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

Hämta aktuell UTC-tidsstämpel enligt RFC1123 standard

Använd följande kod för att hämta önskat datumformat oberoende av nationella inställningar.

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)

Skapa en auktoriseringshuvudsträng

Nu ska vi konstruera strängen som vi ska lägga till i vårt auktoriseringshuvud.

  1. Förbered värden för rubrikerna som ska signeras.
    1. Ange den aktuella tidsstämpeln med hjälp av tidszonen Coordinated Universal Time (UTC).
    2. Hämta utfärdaren för begäran (DNS-värdnamnet eller IP-adressen och portnumret).
    3. Beräkna en innehållshash.
  2. Förbered en sträng att signera.
  3. Beräkna signaturen.
  4. Sammanfoga strängen, som ska användas i auktoriseringshuvudet.

Lägg till följande kod i skriptet sign_hmac_tutorial.py .

# 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}"

Lägga till sidhuvuden

Använd följande kod för att lägga till de nödvändiga rubrikerna.

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"

Testa klienten

Anropa slutpunkten och kontrollera svaret.

req = request.Request(request_uri, content, request_headers, method='POST')
with request.urlopen(req) as response:
  response_string = json.load(response)
print(response_string)

Rensa resurser

Om du vill rensa och ta bort en Communication Services-prenumeration tar du bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort. Du kan läsa mer om hur du rensar Azure Communication Services-resurser och rensar Azure Functions-resurser.

Nästa steg

Du kanske också vill: