Bagikan melalui


Menandatangani permintaan HTTP

Dalam tutorial ini, Anda akan mempelajari cara menandatangani permintaan HTTP dengan tanda tangan HMAC.

Catatan

Kami sangat mendorong untuk menggunakan Azure SDK. Pendekatan yang dijelaskan di sini adalah opsi fallback untuk kasus ketika Azure SDK tidak dapat digunakan karena alasan apa pun.

Prasyarat

Sebelum memulai, pastikan untuk:

Menandatangani permintaan dengan C#

Autentikasi kunci akses menggunakan kunci rahasia bersama untuk menghasilkan tanda tangan Kode Autentikasi Pesan Berbasis Hash terhadap setiap permintaan. Tanda tangan ini dihasilkan dengan algoritma SHA256 dan dikirim di header Authorization dengan menggunakan skema HMAC-SHA256. Contohnya:

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

hmac-sha256-signature terdiri dari:

  • Kata kerja HTTP (misalnya, GET atau PUT)
  • Jalur permintaan
  • x-ms-date
  • Host
  • x-ms-content-sha256

Siapkan

Langkah-langkah berikut menjelaskan cara membuat header otorisasi.

Membuat aplikasi C# baru

Di jendela konsol, seperti cmd, PowerShell, atau Azure CLI, gunakan perintah dotnet new untuk membuat aplikasi konsol baru bernama SignHmacTutorial. Perintah ini membuat proyek C# "Halo Dunia" sederhana dengan file sumber tunggal: Program.cs.

dotnet new console -o SignHmacTutorial

Ubah direktori Anda ke folder aplikasi yang baru dibuat. Gunakan perintah dotnet build untuk mengompilasi aplikasi Anda.

cd SignHmacTutorial
dotnet build

Memasang paket

Pasang paket Newtonsoft.Json yang digunakan untuk serialisasi isi.

dotnet add package Newtonsoft.Json

Perbarui deklarasi metode Main untuk mendukung kode asinkron. Gunakan kode berikut untuk memulai.

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

Membuat pesan permintaan

Untuk contoh ini, kita akan menandatangani permintaan untuk membuat identitas baru dengan menggunakan API Autentikasi Communication Services (versi 2021-03-07).

Tambahkan kode berikut ke metode 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")
};

Ganti resourceEndpoint dengan nilai titik akhir sumber daya Anda yang sebenarnya.

Membuat hash konten

Hash konten adalah bagian dari tanda tangan Kode Autentikasi Pesan Berbasis Hash Anda. Gunakan kode berikut untuk menghitung hash konten. Anda dapat menambahkan metode ini ke Progam.cs di metode Main.

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

Menghitung tanda tangan

Gunakan kode berikut untuk membuat metode untuk menghitung tanda tangan Kode Autentikasi Pesan Berbasis Hash Anda.

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

Ganti resourceAccessKey dengan kunci akses sumber daya Communication Services Anda yang sebenarnya.

Membuat untai (karakter) header otorisasi

Kita sekarang akan menyusun untai (karakter) yang akan ditambahkan ke header otorisasi.

  1. Siapkan nilai header yang akan ditandatangani.
    1. Tentukan tanda waktu saat ini menggunakan zona Waktu Universal Terkoordinasi (UTC).
    2. Dapatkan otoritas permintaan (nama host DNS atau alamat IP dan nomor port).
    3. Hitung hash konten.
  2. Siapkan untai (karakter) untuk menandatangani.
  3. Hitung tanda tangan.
  4. Gabungkan untai (karakter) yang akan digunakan di header otorisasi.

Tambahkan kode berikut ke metode 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}";

Menambahkan header ke requestMessage

Gunakan kode berikut untuk menambahkan header yang diperlukan ke 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);

Menguji klien

Hubungi titik akhir dengan menggunakan HttpClient, dan periksa responsnya.

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

Prasyarat

Sebelum memulai, pastikan untuk:

Menandatangani permintaan HTTP dengan Python

Autentikasi kunci akses menggunakan kunci rahasia bersama untuk menghasilkan tanda tangan Kode Autentikasi Pesan Berbasis Hash terhadap setiap permintaan. Tanda tangan ini dihasilkan dengan algoritma SHA256 dan dikirim di header Authorization dengan menggunakan skema HMAC-SHA256. Contohnya:

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

hmac-sha256-signature terdiri dari:

  • Kata kerja HTTP (misalnya, GET atau PUT)
  • Jalur permintaan
  • x-ms-date
  • Host
  • x-ms-content-sha256

Siapkan

Langkah-langkah berikut menjelaskan cara membuat header otorisasi.

Membuat skrip Python baru

Buka Visual Studio Code atau IDE atau editor pilihan Anda lainnya dan buat file baru bernama sign_hmac_tutorial.py. Simpan file ini ke folder yang diketahui.

Menambahkan impor yang diperlukan

sign_hmac_tutorial.py Perbarui skrip dengan kode berikut untuk memulai.

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

Menyiapkan data untuk permintaan

Untuk contoh ini, kami akan menandatangani permintaan untuk membuat identitas baru dengan menggunakan API Autentikasi Communication Services (versi 2021-03-07).

Tambahkan kode berikut ke sign_hmac_tutorial.py skrip.

  • Ganti resource_endpoint_name dengan nilai nama titik akhir sumber daya nyata Anda. Nilai ini dapat ditemukan di bagian Gambaran Umum sumber daya Azure Communication Services Anda. Ini adalah nilai "Titik Akhir" setelah "https://".
  • Ganti resource_endpoint_secret dengan nilai rahasia titik akhir sumber daya nyata Anda. Nilai ini dapat ditemukan di bagian Kunci dari sumber daya Azure Communication Services Anda. Ini adalah nilai "Kunci" - baik primer atau sekunder.
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")

Membuat hash konten

Hash konten adalah bagian dari tanda tangan Kode Autentikasi Pesan Berbasis Hash Anda. Gunakan kode berikut untuk menghitung hash konten. Anda dapat menambahkan metode ini ke sign_hmac_tutorial.py skrip.

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

Menghitung tanda tangan

Gunakan kode berikut untuk membuat metode untuk menghitung tanda tangan Kode Autentikasi Pesan Berbasis Hash Anda.

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

Dapatkan tanda waktu UTC saat ini sesuai dengan standar RFC1123

Gunakan kode berikut untuk mendapatkan format tanggal yang diinginkan terlepas dari pengaturan lokal.

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)

Membuat untai (karakter) header otorisasi

Kita sekarang akan menyusun untai (karakter) yang akan ditambahkan ke header otorisasi.

  1. Siapkan nilai header yang akan ditandatangani.
    1. Tentukan tanda waktu saat ini menggunakan zona Waktu Universal Terkoordinasi (UTC).
    2. Dapatkan otoritas permintaan (nama host DNS atau alamat IP dan nomor port).
    3. Hitung hash konten.
  2. Siapkan untai (karakter) untuk menandatangani.
  3. Hitung tanda tangan.
  4. Gabungkan untai (karakter) yang akan digunakan di header otorisasi.

Tambahkan kode berikut ke sign_hmac_tutorial.py skrip.

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

Menambahkan header

Gunakan kode berikut untuk menambahkan header yang diperlukan.

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"

Menguji klien

Hubungi titik akhir dan periksa responsnya.

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

Membersihkan sumber daya

Untuk membersihkan dan menghapus langganan Communication Services, hapus sumber daya atau grup sumber daya. Menghapus grup sumber daya juga dapat menghapus sumber daya lain yang terkait dengannya. Anda dapat mengetahui lebih lanjut tentang membersihkan sumber daya Azure Communication Services dan membersihkan sumber daya Azure Functions.

Langkah berikutnya

Anda mungkin juga ingin: