Partager via


Signer une requête HTTP

Dans ce tutoriel, vous allez découvrir comment signer une requête HTTP avec une signature HMAC.

Notes

Nous encourageons vivement l’utilisation de SDK Azure. L’approche décrite ici est une option de secours pour les cas où les kits de développement logiciel (SDK) Azure ne peuvent pas être utilisés pour une raison quelconque.

Prérequis

Avant de commencer, assurez-vous de :

Signer une requête HTTP avec C#

L’authentification par clé d’accès utilise une clé secrète partagée afin de générer une signature HMAC pour chaque requête HTTP. Cette signature est générée avec l’algorithme SHA256 et est envoyée dans l’en-tête Authorization à l’aide du schéma HMAC-SHA256. Par exemple :

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

La signature hmac-sha256-signature est constituée des éléments suivants :

  • Verbe HTTP (par exemple GET ou PUT)
  • Un chemin de requête HTTP
  • x-ms-date
  • Host
  • x-ms-content-sha256

Programme d’installation

Les étapes suivantes décrivent comment construire l’en-tête d’autorisation.

Créer une application C#

Dans une fenêtre de console (par exemple cmd, PowerShell ou Bash), utilisez la commande dotnet new pour créer une application console avec le nom SignHmacTutorial. Cette commande crée un projet C# « Hello World » simple avec un seul fichier source : Program.cs.

dotnet new console -o SignHmacTutorial

Déplacez vos répertoires vers le dossier d’application nouvellement créé. Utilisez la commande dotnet build pour compiler votre application.

cd SignHmacTutorial
dotnet build

Installer le package

Installez le package Newtonsoft.Json, utilisé pour la sérialisation du corps.

dotnet add package Newtonsoft.Json

Mettez à jour la déclaration de la méthode Main pour prendre en charge le code asynchrone. Utilisez le code suivant pour commencer.

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

Créer un message de requête

Pour cet exemple, nous allons signer une demande de création d’une identité à l’aide de l’API Authentification Communication Services (version 2021-03-07).

Ajoutez le code suivant à la méthode 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")
};

Remplacez resourceEndpoint par votre valeur de point de terminaison de ressource réelle.

Créer un hachage de contenu

Le hachage de contenu fait partie de votre signature HMAC. Utilisez le code suivant pour calculer le hachage de contenu. Vous pouvez ajouter cette méthode à Program.cs sous la méthode Main.

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

Calculer une signature

Utilisez le code suivant pour créer une méthode destinée à calculer votre signature HMAC.

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

Remplacez resourceAccessKey par la clé d’accès de votre ressource Communication Services réelle.

Créer une chaîne d’en-tête d’autorisation

Nous allons maintenant construire la chaîne que nous ajouterons à notre en-tête d’autorisation.

  1. Préparez les valeurs des en-têtes à signer.
    1. Spécifiez l’horodatage actuel avec le fuseau horaire UTC (Coordinated Universal Time).
    2. Obtenez l’autorité de demande (nom d’hôte DNS ou adresse IP et numéro de port).
    3. Calculer un hachage de contenu.
  2. Préparer une chaîne à signer.
  3. Calculer la signature.
  4. Concaténer la chaîne qui sera utilisée dans l’en-tête d’autorisation.

Ajoutez le code suivant à la méthode 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}";

Ajouter des en-têtes à requestMessage

Utilisez le code suivant pour ajouter les en-têtes obligatoires à votre 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);

Tester le client

Appelez le point de terminaison à l’aide de HttpClient, puis vérifiez la réponse.

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

Prérequis

Avant de commencer, assurez-vous de :

Signer une requête HTTP avec Python

L’authentification par clé d’accès utilise une clé secrète partagée afin de générer une signature HMAC pour chaque requête HTTP. Cette signature est générée avec l’algorithme SHA256 et est envoyée dans l’en-tête Authorization à l’aide du schéma HMAC-SHA256. Par exemple :

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

La signature hmac-sha256-signature est constituée des éléments suivants :

  • Verbe HTTP (par exemple GET ou PUT)
  • Un chemin de requête HTTP
  • x-ms-date
  • Host
  • x-ms-content-sha256

Programme d’installation

Les étapes suivantes décrivent comment construire l’en-tête d’autorisation.

Créer un script Python

Ouvrez Visual Studio Code ou un autre IDE ou éditeur de votre choix et créez un nouveau fichier nommé sign_hmac_tutorial.py. Enregistrez ce fichier dans un dossier connu.

Ajout des importations nécessaires

Mettez à jour le script sign_hmac_tutorial.py avec le code suivant pour commencer.

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

Préparer les données pour la requête

Pour cet exemple, nous allons signer une demande de création d’une identité à l’aide de l’API Authentification Communication Services (version 2021-03-07).

Ajoutez le code suivant au script sign_hmac_tutorial.py.

  • Remplacez resource_endpoint_name par votre valeur de nom de point de terminaison de ressource réelle. Cette valeur se trouve dans la section Vue d’ensemble de votre ressource Azure Communication Services. C’est la valeur de « Point de terminaison » après « https:// ».
  • Remplacez resource_endpoint_secret par votre valeur de secret de point de terminaison de ressource réelle. Cette valeur se trouve dans la section Clés de votre ressource Azure Communication Services. C’est la valeur de la « Clé » - primaire ou secondaire.
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")

Créer un hachage de contenu

Le hachage de contenu fait partie de votre signature HMAC. Utilisez le code suivant pour calculer le hachage de contenu. Vous pouvez ajouter cette méthode au script sign_hmac_tutorial.py.

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

Calculer une signature

Utilisez le code suivant pour créer une méthode destinée à calculer votre signature HMAC.

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

Obtenir l’horodatage UTC actuel en fonction de la norme RFC1123

Utilisez le code suivant pour obtenir le format de date souhaité indépendamment des paramètres régionaux.

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)

Créer une chaîne d’en-tête d’autorisation

Nous allons maintenant construire la chaîne que nous ajouterons à notre en-tête d’autorisation.

  1. Préparez les valeurs des en-têtes à signer.
    1. Spécifiez l’horodatage actuel avec le fuseau horaire UTC (Coordinated Universal Time).
    2. Obtenez l’autorité de demande (nom d’hôte DNS ou adresse IP et numéro de port).
    3. Calculer un hachage de contenu.
  2. Préparer une chaîne à signer.
  3. Calculer la signature.
  4. Concaténer la chaîne qui sera utilisée dans l’en-tête d’autorisation.

Ajoutez le code suivant au script 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}"

Ajouter les en-têtes

Utilisez le code suivant pour ajouter les en-têtes obligatoires.

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"

Tester le client

Appelez le point de terminaison, puis vérifiez la réponse.

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

Nettoyer les ressources

Pour nettoyer et supprimer un abonnement Communication Services, supprimez la ressource ou le groupe de ressources. La suppression du groupe de ressources efface également les autres ressources qui y sont associées. Apprenez-en davantage sur le nettoyage des ressources Azure Communication Service et le nettoyage des ressources Azure Functions.

Étapes suivantes

Vous pouvez également :