Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описывается, как подписать HTTP-запрос с помощью хэш-кода проверки подлинности сообщений (HMAC).
Note
Мы рекомендуем использовать пакеты SDK Azure для подписывания HTTP-запроса. Подход, описанный в этой статье, является резервным вариантом, если пакеты SDK Azure не могут использоваться по какой-либо причине.
В этом руководстве описано, как:
- Создайте сообщение запроса.
- Создайте хэш содержимого.
- Вычисление подписи.
- Создайте строку заголовка авторизации.
- Добавьте заголовки.
Prerequisites
- Создайте учетную запись Azure с активной подпиской. Если у вас нет подписки Azure, см. статью "Создание учетной записи бесплатно".
- Установить Visual Studio.
- Создание ресурса Служб коммуникации Azure. Если у вас нет ресурса, см. статью "Создание ресурса служб коммуникации". Для этого руководства вам необходимо задокументировать параметры
resourceEndpointиresourceAccessKey.
Подписывание HTTP-запроса с помощью C#
Проверка подлинности на основе ключа доступа использует для создания подписей HMAC для всех HTTP-запросов общий секретный ключ. Эта сигнатура создается с использованием алгоритма SHA256 и отправляется в заголовок Authorization с помощью схемы HMAC-SHA256. Рассмотрим пример.
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
В состав hmac-sha256-signature входит следующее:
- HTTP-команда (например,
GETилиPUT) - Путь HTTP-запроса
- x-ms-date
- Host
- x-ms-content-sha256
Настройте заголовок авторизации
Выполните следующие действия, чтобы создать заголовок авторизации.
Создание нового приложения C#
В окне консоли (cmd, PowerShell или Bash) выполните команду dotnet new, чтобы создать консольное приложение с именем SignHmacTutorial. Эта команда создает простой проект Hello World на языке C# с одним файлом исходного кода: Program.cs.
dotnet new console -o SignHmacTutorial
Измените каталог на созданную папку приложения. Чтобы скомпилировать приложение, используйте dotnet build команду.
cd SignHmacTutorial
dotnet build
Установка пакета
Установите пакет Newtonsoft.Json, который используется для сериализации текстовой части.
dotnet add package Newtonsoft.Json
Обновите объявление метода Main, чтобы он поддерживал асинхронный код. Используйте следующий код для начала.
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.
}
}
}
Создание сообщения запроса
В этом примере вы подписываете запрос на создание нового удостоверения с помощью API проверки подлинности служб коммуникации (версия 2021-03-07).
Добавьте следующий код в метод 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")
};
Замените resourceEndpoint фактическим значением конечной точки ресурса.
Создание хэша содержимого
Хэш содержимого является частью сигнатуры HMAC. Используйте следующий код, чтобы вычислить хэш содержимого. Этот метод можно добавить в Program.cs, используя метод Main.
static string ComputeContentHash(string content)
{
using var sha256 = SHA256.Create();
byte[] hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(content));
return Convert.ToBase64String(hashedBytes);
}
Вычисление сигнатуры
Используйте следующий код, чтобы создать метод для вычисления сигнатуры 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);
}
Замените resourceAccessKey ключом доступа к реальному ресурсу Служб коммуникации.
Создание строки заголовка авторизации
Теперь вы создаете строку, добавляемую в заголовок авторизации.
- Подготовьте значения для подписываемых заголовков.
- Укажите текущую метку времени с помощью часового пояса UTC.
- Получите полномочия для запроса. Используйте имя узла или IP-адрес системы доменных имен (DNS) и номер порта.
- Вычислите хэш содержимого.
- Подготовьте строку к подписыванию.
- Вычислите сигнатуру.
- Объедините строку, которая используется в заголовке авторизации.
Добавьте следующий код в метод 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}";
Добавление заголовков в requestMessage
Используйте следующий код, чтобы добавить необходимые заголовки в 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);
Тестирование клиента
Вызовите конечную точку с помощью HttpClient и проверьте ответ.
HttpClient httpClient = new HttpClient
{
BaseAddress = requestUri
};
var response = await httpClient.SendAsync(requestMessage);
var responseString = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseString);
Prerequisites
- Создайте учетную запись Azure с активной подпиской. Если у вас нет подписки Azure, см. статью "Создание учетной записи бесплатно".
- Скачайте и установите Python.
- Скачайте и установите Visual Studio Code или другую интегрированную среду разработки (IDE), которая поддерживает Python.
- Создание ресурса Служб коммуникации Azure. Если у вас нет ресурса, см. статью "Создание ресурса служб коммуникации". Вам нужны
resource_endpoint_nameиresource_endpoint_secretпараметры для этого примера.
Подписать HTTP-запрос с помощью Python
Проверка подлинности на основе ключа доступа использует для создания подписей HMAC для всех HTTP-запросов общий секретный ключ. Эта сигнатура создается с использованием алгоритма SHA256 и отправляется в заголовок Authorization с помощью схемы HMAC-SHA256. Рассмотрим пример.
Authorization: "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=<hmac-sha256-signature>"
В состав hmac-sha256-signature входит следующее:
- HTTP-команда (например,
GETилиPUT) - Путь HTTP-запроса
- x-ms-date
- Host
- x-ms-content-sha256
Настройте заголовок авторизации
Выполните следующие действия, чтобы создать заголовок авторизации.
Создание сценария Python
Откройте Visual Studio Code или другую среду разработки (IDE) или редактор по вашему выбору. Создайте файл с именем sign_hmac_tutorial.py. Сохраните этот файл в известную папку.
Добавьте необходимые импорты
Обновите скрипт с помощью следующего sign_hmac_tutorial.py кода, чтобы начать работу.
import base64
import hashlib
import hmac
import json
from datetime import datetime, timezone
from urllib import request
Подготовка данных для запроса
В этом примере вы подписываете запрос на создание нового удостоверения с помощью API проверки подлинности служб коммуникации (версия 2021-03-07).
Добавьте следующий код в sign_hmac_tutorial.py скрипт.
- Замените
resource_endpoint_nameзначением имени конечной точки реального ресурса. Это значение можно найти в разделе "Обзор " ресурса служб коммуникации. Это значениеEndpointпослеhttps://. - Замените
resource_endpoint_secretна фактическое секретное значение конечной точки ресурса. Это значение можно найти в разделе "Ключи " ресурса служб коммуникации. Это значение ключа, которое является первичным или вторичным.
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")
Создание хэша содержимого
Хэш содержимого является частью сигнатуры HMAC. Используйте следующий код, чтобы вычислить хэш содержимого. Этот метод можно добавить в 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
Вычисление сигнатуры
Используйте следующий код, чтобы создать метод для вычисления сигнатуры 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
Получение текущей метки времени UTC в соответствии со стандартом RFC1123
Используйте следующий код, чтобы получить формат даты, который не зависит от параметров языкового стандарта.
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)
Создание строки заголовка авторизации
Теперь вы создаете строку, добавляемую в заголовок авторизации.
- Подготовьте значения для подписываемых заголовков.
- Укажите текущую метку времени с помощью часового пояса UTC.
- Получите полномочия для запроса. Используйте имя узла или IP-адрес системы доменных имен (DNS) и номер порта.
- Вычислите хэш содержимого.
- Подготовьте строку к подписыванию.
- Вычислите сигнатуру.
- Объедините строку, которая используется в заголовке авторизации.
Добавьте следующий код в 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}"
Добавление заголовков
Используйте следующий код, чтобы добавить необходимые заголовки.
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"
Тестирование клиента
Вызовите конечную точку и проверьте ответ.
req = request.Request(request_uri, content, request_headers, method='POST')
with request.urlopen(req) as response:
response_string = json.load(response)
print(response_string)
Очистка ресурсов
Чтобы очистить и удалить подписку на Службы коммуникации, удалите ресурс или группу ресурсов. При удалении группы ресурсов также удаляются все связанные с ней ресурсы. Вы можете узнать больше о том, как очистить ресурсы Служб коммуникации Azure и очистить ресурсы Функций Azure.