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:
- Skapa ett Azure-konto med en aktiv prenumeration. Mer information finns i Skapa ett konto kostnadsfritt.
- Installera Visual Studio.
- Skapa en Azure Communication Services-resurs. Mer information finns i Skapa en Azure Communication Services-resurs. Du måste registrera resursEndpoint och resourceAccessKey för den här självstudien.
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
ellerPUT
) - 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.
- Förbered värden för rubrikerna som ska signeras.
- Ange den aktuella tidsstämpeln med hjälp av tidszonen Coordinated Universal Time (UTC).
- Hämta utfärdaren för begäran (DNS-värdnamnet eller IP-adressen och portnumret).
- Beräkna en innehållshash.
- Förbered en sträng att signera.
- Beräkna signaturen.
- 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 HttpClient
av 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:
- Skapa ett Azure-konto med en aktiv prenumeration. Mer information finns i Skapa ett konto kostnadsfritt.
- Ladda ned och installera Python.
- Ladda ned och installera Visual Studio Code eller annan IDE som stöder Python.
- Skapa en Azure Communication Services-resurs. Mer information finns i Skapa en Azure Communication Services-resurs. Du behöver dina resource_endpoint_name och resource_endpoint_secret för den här självstudien.
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
ellerPUT
) - 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.
- Förbered värden för rubrikerna som ska signeras.
- Ange den aktuella tidsstämpeln med hjälp av tidszonen Coordinated Universal Time (UTC).
- Hämta utfärdaren för begäran (DNS-värdnamnet eller IP-adressen och portnumret).
- Beräkna en innehållshash.
- Förbered en sträng att signera.
- Beräkna signaturen.
- 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: