Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se describe cómo firmar una solicitud HTTP con una firma de código de autenticación de mensajes basado en hash (HMAC).
Nota:
Se recomienda usar los SDK de Azure para firmar una solicitud HTTP. El enfoque descrito en este artículo es una opción de reserva si los SDK de Azure no se pueden usar por ningún motivo.
En este tutorial, aprenderá a:
- Cree un mensaje de solicitud.
- Cree un hash de contenido.
- Procesamiento de una firma.
- Creación de una cadena de encabezado de autorización.
- Agregue encabezados.
Requisitos previos
- Cree una cuenta de Azure con una suscripción activa. Si no tiene una suscripción de Azure, consulte Creación de una cuenta gratuita.
- Instale Visual Studio.
- Cree un recurso de Azure Communication Services. Si no tiene un recurso, consulte Creación de un recurso de Communication Services. Debe registrar sus parámetros
resourceEndpoint
yresourceAccessKey
para este tutorial.
Firmar una solicitud HTTP con C#
La autenticación de clave de acceso usa una clave secreta compartida para generar una firma HMAC para cada solicitud HTTP. Esta firma se genera con el algoritmo SHA256 y se envía en el encabezado Authorization
mediante el esquema HMAC-SHA256
. Por ejemplo:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
hmac-sha256-signature
consta de:
- Verbo HTTP (por ejemplo,
GET
oPUT
) - Ruta de acceso de la solicitud HTTP
- x-ms-fecha
- anfitrión
- x-ms-content-sha256
Configuración del encabezado de autorización
Complete los pasos siguientes para construir el encabezado de autorización.
Creación de una aplicación de C#
En una ventana de la consola, como cmd, PowerShell o Bash, use el comando dotnet new
para crear una aplicación de consola con el nombre SignHmacTutorial
. Este comando crea un sencillo proyecto "Hola mundo" de C# con un solo archivo de origen: Program.cs
.
dotnet new console -o SignHmacTutorial
Cambie el directorio a la carpeta de aplicaciones recién creada. Para compilar la aplicación, use el dotnet build
comando .
cd SignHmacTutorial
dotnet build
Instalar el paquete
Instale el paquete Newtonsoft.Json
que se usa en la serialización del cuerpo.
dotnet add package Newtonsoft.Json
Actualice la declaración del método Main
para admitir código asincrónico. Use el código siguiente para empezar.
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.
}
}
}
Creación de un mensaje de solicitud
En este ejemplo, firma una solicitud para crear una nueva identidad mediante la API de autenticación de Communication Services (versión 2021-03-07
).
Agregue el siguiente código al método 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")
};
Reemplace resourceEndpoint
por el valor real del punto de conexión del recurso.
Creación de un hash de contenido
El código hash de contenido es parte de la firma HMAC. Utilice el siguiente código para calcular el hash del contenido. Puede agregar este método a Program.cs
en el método Main
.
static string ComputeContentHash(string content)
{
using var sha256 = SHA256.Create();
byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(content));
return Convert.ToBase64String(hashedBytes);
}
Procesamiento de una firma
Use el código siguiente para crear un método para procesar una firma 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);
}
Reemplaza resourceAccessKey
por la clave de acceso de tu recurso real de Servicios de Comunicación.
Creación de una cadena de encabezado de autorización
Ahora crea la cadena que debes añadir a tu encabezado de autorización.
- Prepare los valores de los encabezados que se van a firmar.
- Especifique la marca de tiempo actual mediante la zona horaria Hora universal coordinada (UTC).
- Obtenga la entidad de solicitud. Use el nombre de host del sistema de nombres de dominio (DNS) o la dirección IP y el número de puerto.
- Procese un hash de contenido.
- Prepare una cadena de caracteres para firmar.
- Calcule la firma.
- Concatene la cadena, que se usa en el encabezado de autorización.
Agregue el siguiente código al método 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}";
Incorporación de encabezados a requestMessage
Use el código siguiente para agregar los encabezados necesarios al requestMessage
parámetro .
// 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);
Probar el cliente
Llame al punto de conexión mediante HttpClient
y compruebe la respuesta.
HttpClient httpClient = new HttpClient
{
BaseAddress = requestUri
};
var response = await httpClient.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Requisitos previos
- Cree una cuenta de Azure con una suscripción activa. Si no tiene una suscripción de Azure, consulte Creación de una cuenta gratuita.
- Descargue e instale Python.
- Descargue e instale Visual Studio Code u otro entorno de desarrollo integrado (IDE) que admita Python.
- Cree un recurso de Azure Communication Services. Si no tiene un recurso, consulte Creación de un recurso de Communication Services. Necesita sus
resource_endpoint_name
yresource_endpoint_secret
parámetros para este ejemplo.
Firma de una solicitud HTTP con Python
La autenticación de clave de acceso usa una clave secreta compartida para generar una firma HMAC para cada solicitud HTTP. Esta firma se genera con el algoritmo SHA256 y se envía en el encabezado Authorization
mediante el esquema HMAC-SHA256
. Por ejemplo:
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
hmac-sha256-signature
consta de:
- Verbo HTTP (por ejemplo,
GET
oPUT
) - Ruta de acceso de la solicitud HTTP
- x-ms-fecha
- anfitrión
- x-ms-content-sha256
Configuración del encabezado de autorización
Complete los pasos siguientes para construir el encabezado de autorización.
Creación de un nuevo script de Python
Abra Visual Studio Code u otro IDE o editor que prefiera. Cree un nuevo archivo llamado sign_hmac_tutorial.py
. Guarde este archivo en una carpeta conocida.
Adición de las importaciones necesarias
Actualice el script sign_hmac_tutorial.py
con el código siguiente para comenzar.
import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
from urllib import request
Preparación de los datos para la solicitud
En este ejemplo, firma una solicitud para crear una nueva identidad mediante communication Services Authentication API (versión 2021-03-07
).
Agregue el siguiente código al script sign_hmac_tutorial.py
.
- Reemplace
resource_endpoint_name
por el valor real del nombre de punto de conexión del recurso. Puede encontrar este valor en la sección Información general del recurso de Communication Services. Es el valor deEndpoint
después dehttps://
. - Reemplace
resource_endpoint_secret
por el valor real del secreto del punto de conexión del recurso. Puede encontrar este valor en la sección Claves del recurso de Communication Services. Es el valor de Key, que es principal o secundario.
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 the list of scopes as a body.
body = { "createTokenWithScopes": ["chat"] }
serialized_body = json.dumps(body)
content = serialized_body.encode("utf-8")
Creación de un hash de contenido
El código hash de contenido es parte de la firma HMAC. Utilice el siguiente código para calcular el hash del contenido. Puede agregar este método al 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
Procesamiento de una firma
Use el código siguiente para crear un método para procesar una firma 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
Obtener una marca de tiempo UTC actual según el RFC1123 estándar
Use el código siguiente para obtener el formato de fecha que desea que sea independiente de la configuración regional.
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)
Creación de una cadena de encabezado de autorización
Ahora crea la cadena que debes añadir a tu encabezado de autorización.
- Prepare los valores de los encabezados que se van a firmar.
- Especifique la marca de tiempo actual mediante la zona horaria Hora universal coordinada (UTC).
- Obtenga la entidad de solicitud. Use el nombre de host del sistema de nombres de dominio (DNS) o la dirección IP y el número de puerto.
- Procese un hash de contenido.
- Prepare una cadena de caracteres para firmar.
- Calcule la firma.
- Concatene la cadena, que se usa en el encabezado de autorización.
Agregue el siguiente código al 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}"
Incorporación de encabezados
Use el código siguiente para agregar los encabezados necesarios.
request_headers = {}
# Add a date header.
request_headers["x-ms-date"] = date
# Add a content hash header.
request_headers["x-ms-content-sha256"] = content_hash
# Add an authorization header.
request_headers["Authorization"] = authorization_header
# Add a content type header.
request_headers["Content-Type"] = "application/json"
Probar el cliente
Llame al punto de conexión y compruebe la respuesta.
req = request.Request(request_uri, content, request_headers, method='POST')
with request.urlopen(req) as response:
response_string = json.load(response)
print(response_string)
Limpieza de recursos
Si quiere limpiar y quitar una suscripción de Communication Services, elimine el recurso o el grupo de recursos. Al eliminar el grupo de recursos, también se elimina cualquier otro recurso que esté asociado a él. Puede obtener más información sobre cómo limpiar los recursos de Azure Communication Services y limpiar los recursos de Azure Functions.