Partnerközpont – webhookok
A következőre vonatkozik: Partnerközpont | A 21Vianet által üzemeltetett Partnerközpont | Partnerközpont a Microsoft Cloud for US Government számára
Megfelelő szerepkörök: globális rendszergazda | Számlázási Rendszergazda | Rendszergazda ügynök | Értékesítési ügynök | Segélyszolgálati ügynök
A Partnerközpont Webhook API-kkal a partnerek regisztrálhatnak az erőforrás-változási eseményekre. Ezek az események HTTP POST-k formájában érkeznek a partner regisztrált URL-címére. Ha eseményt szeretne fogadni a Partnerközpontból, a partnerek visszahívást fognak üzemeltetni, ahol a Partnerközpont közzéteheti az erőforrás-változási eseményt. Az esemény digitálisan alá lesz írva, így a partner ellenőrizheti, hogy a partnerközpontból küldte-e. A webhookértesítések csak azokra a környezetekre aktiválódnak, amelyek a co-sell legújabb konfigurációját használják.
A partnerek a Partnerközpont által támogatott webhookesemények közül választhatnak, például az alábbi példákból.
Észlelt Azure-csalási esemény ("azure-fraud-event-detected")
Ez az esemény az Azure-ból való csalás észlelésekor jön elő.
Delegált Rendszergazda kapcsolat által jóváhagyott esemény ("dap-admin-relationship-approved")
Ez az esemény akkor jön létre, amikor a delegált Rendszergazda jogosultságokat az ügyfél bérlője jóváhagyta.
Az ügyfélesemény által elfogadott viszonteladói kapcsolat ("reseller-relationship-accepted-by-customer")
Ez az esemény akkor jön létre, ha az ügyfélbérlemény jóváhagyja a viszonteladói kapcsolatot.
Delegált Rendszergazda kapcsolat megszakadt esemény ("dap-admin-relationship-terminated")
Ez az esemény akkor jön létre, amikor az ügyfél megszüntette a delegált Rendszergazda jogosultságokat.
Dap Rendszergazda Microsoft-esemény által megszakított kapcsolat ("dap-admin-relationship-terminated-by-microsoft")
Ez az esemény akkor jön létre, amikor a Microsoft leállítja a DAP-t a partner és az ügyfél bérlője között, ha a DAP több mint 90 napig inaktív.
Részletes Rendszergazda Hozzáférés-hozzárendelés aktivált eseménye ("granular-admin-access-assignment-activated")
Ez az esemény akkor jön létre, amikor a partner aktiválja a Részletes delegált Rendszergazda Jogosultságok hozzáférési hozzárendelést, miután a Microsoft Entra-szerepkörök adott biztonsági csoportokhoz lettek rendelve.
Részletes Rendszergazda Hozzáférés-hozzárendelés létrehozott eseménye ("granular-admin-access-assignment-created")
Ez az esemény akkor jön létre, amikor a partner létrehozza a Részletes delegált Rendszergazda Jogosultságok hozzáférési hozzárendelést. A partnerek adott biztonsági csoportokhoz rendelhetnek ügyfél által jóváhagyott Microsoft Entra-szerepköröket.
Részletes Rendszergazda Hozzáférés-hozzárendelés törölt eseménye ("granular-admin-access-assignment-deleted")
Ez az esemény akkor jön létre, amikor a partner törli a Részletes delegált Rendszergazda jogosultságok hozzáférési hozzárendelését.
Részletes Rendszergazda Hozzáférés-hozzárendelés frissített eseménye ("granular-admin-access-assignment-updated")
Ez az esemény akkor jön létre, amikor a partner frissíti a Részletes delegált Rendszergazda Jogosultságok hozzáférési hozzárendelését.
Részletes Rendszergazda Kapcsolat aktivált eseménye ("granular-admin-relationship-activated")
Ez az esemény akkor jön létre, amikor a részletes delegált Rendszergazda jogosultságok létrejönnek, és aktívak az ügyfél jóváhagyásához.
Részletes Rendszergazda kapcsolat által jóváhagyott esemény ("granular-admin-relationship-approved")
Ez az esemény akkor jön létre, amikor az ügyfél bérlője jóváhagyta a részletes delegált Rendszergazda jogosultságokat.
Részletes Rendszergazda kapcsolat lejárt eseménye ("granular-admin-relationship-expired")
Ez az esemény akkor jön elő, ha a részletes delegált Rendszergazda jogosultságok lejártak.
Részletes Rendszergazda Kapcsolat frissített eseménye ("részletes-rendszergazda-kapcsolat frissítve")
Ez az esemény akkor jön létre, ha a részletes delegált Rendszergazda jogosultságokat a partner/ügyfél bérlője frissíti.
Részletes Rendszergazda Kapcsolat automatikusan bővített eseménye ("részletes-rendszergazda-kapcsolat-automatikusan meghosszabbítva")
Ez az esemény akkor jön létre, amikor a rendszer automatikusan kiterjeszti a részletes delegált Rendszergazda jogosultságokat.
Részletes Rendszergazda kapcsolat megszakadt eseménye ("granular-admin-relationship-terminated")
Ez az esemény akkor jön létre, ha a részletes delegált Rendszergazda jogosultságokat a partner/ügyfél bérlője leállítja.
Új kereskedelmi migrálás befejezve ("new-commerce-migration-completed")
Ez az esemény akkor jön létre, amikor az új kereskedelmi migrálás befejeződött.
Új kereskedelmi migrálás létrehozva ("new-commerce-migration-created")
Ez az esemény az új kereskedelmi migrálás létrehozásakor jön létre.
Az új kereskedelmi migrálás sikertelen ("new-commerce-migration-failed")
Ez az esemény akkor jön létre, ha az új kereskedelmi migrálás sikertelen.
Az új kereskedelmi áttelepítési ütemezés meghiúsult ("new-commerce-migration-schedule-failed")
Ez az esemény akkor jön létre, ha az új kereskedelmi migrálási ütemezés meghiúsul.
Javaslat által létrehozott esemény ("javaslat létrehozva")
Ez az esemény az átirányítás létrehozásakor jön létre.
Javaslat frissítve esemény ("javaslat frissítve")
Ez az esemény a javaslat frissítésekor jön létre.
Kapcsolódó javaslattal létrehozott esemény ("related-referral-created")
Ez az esemény a kapcsolódó javaslat létrehozásakor jön létre.
Kapcsolódó javaslat frissített eseménye ("related-referral-updated")
Ez az esemény a kapcsolódó javaslat frissítésekor jön létre.
Előfizetés frissítve esemény ("előfizetés frissítve")
Ez az esemény akkor jön elő, amikor az előfizetés megváltozik. Ezek az események akkor jönnek létre, ha belső változás történik a Partnerközpont API-val végzett módosítások mellett.
Feljegyzés
Az előfizetés módosítása és az Előfizetés frissítése esemény aktiválása között akár 48 óra is lehet.
Tesztesemény ("teszt-létrehozva")
Ez az esemény lehetővé teszi a regisztráció önálló előkészítését és tesztelését egy tesztesemény kérésével, majd a folyamat nyomon követésével. Az esemény kézbesítése közben a Microsofttól kapott hibaüzenetek láthatók. Ez a korlátozás csak a "teszt által létrehozott" eseményekre vonatkozik. A hét napnál régebbi adatok törlődnek.
Küszöbérték túllépte az eseményt ("usagerecords-thresholdExceeded")
Ez az esemény akkor keletkezik, ha a Microsoft Azure-használat mennyisége bármely ügyfél esetében meghaladja a használati költségkeretet (a küszöbértéket). További információ: (Azure-költségkeret beállítása az ügyfelek számára/partnerközpont/set-an-azure-spending-budget-for-your-customers).
A jövőbeni webhookesemények olyan erőforrásokhoz lesznek hozzáadva, amelyek a partner által nem irányítható rendszerben változnak, és további frissítéseket végeznek, hogy az események a lehető legközelebb legyenek a "valós idejű" állapothoz. A partnerek visszajelzése arról, hogy mely események adnak értéket a vállalkozásuknak, hasznos lesz annak meghatározásában, hogy milyen új eseményeket kell hozzáadniuk.
A Partnerközpont által támogatott webhookesemények teljes listájáért tekintse meg a Partnerközpont webhookeseményeit.
Előfeltételek
- Hitelesítő adatok a Partnerközpont hitelesítésében leírtak szerint. Ez a forgatókönyv támogatja az önálló alkalmazással és az App+Felhasználói hitelesítő adatokkal való hitelesítést is.
Események fogadása a Partnerközpontból
Ahhoz, hogy eseményeket fogadjon a Partnerközpontból, közzé kell tennie egy nyilvánosan elérhető végpontot. Mivel ez a végpont elérhető, ellenőriznie kell, hogy a kommunikáció a Partnerközpontból származik-e. Minden fogadott webhookesemény digitálisan alá van írva egy, a Microsoft Roothoz láncolást használó tanúsítvánnyal. Az esemény aláírásához használt tanúsítványra mutató hivatkozás is meg lesz adva. Ez lehetővé teszi a tanúsítvány megújítását anélkül, hogy újra kellene üzembe helyeznie vagy újrakonfigurálnia a szolgáltatást. A Partnerközpont 10 kísérletet tesz az esemény kézbesítésére. Ha az esemény még mindig nem érkezik meg 10 kísérlet után, akkor az offline üzenetsorba kerül, és a kézbesítéskor nem történik további kísérlet.
Az alábbi minta egy partnerközpontból közzétett eseményt mutat be.
POST /webhooks/callback
Content-Type: application/json
Authorization: Signature VOhcjRqA4f7u/4R29ohEzwRZibZdzfgG5/w4fHUnu8FHauBEVch8m2+5OgjLZRL33CIQpmqr2t0FsGF0UdmCR2OdY7rrAh/6QUW+u+jRUCV1s62M76jbVpTTGShmrANxnl8gz4LsbY260LAsDHufd6ab4oejerx1Ey9sFC+xwVTa+J4qGgeyIepeu4YCM0oB2RFS9rRB2F1s1OeAAPEhG7olp8B00Jss3PQrpLGOoAr5+fnQp8GOK8IdKF1/abUIyyvHxEjL76l7DVQN58pIJg4YC+pLs8pi6sTKvOdSVyCnjf+uYQWwmmWujSHfyU37j2Fzz16PJyWH41K8ZXJJkw==
X-MS-Certificate-Url: https://3psostorageacct.blob.core.windows.net/cert/pcnotifications-dispatch.microsoft.com.cer
X-MS-Signature-Algorithm: rsa-sha256
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Content-Length: 195
{
"EventName": "test-created",
"ResourceUri": "http://localhost:16722/v1/webhooks/registration/test",
"ResourceName": "test",
"AuditUri": null,
"ResourceChangeUtcDate": "2017-11-16T16:19:06.3520276+00:00"
}
Feljegyzés
Az Engedélyezési fejléc "Signature" (Aláírás) sémával rendelkezik. Ez a tartalom base64 kódolású aláírása.
A visszahívás hitelesítése
A Partnerközponttól kapott visszahívási esemény hitelesítéséhez kövesse az alábbi lépéseket:
Ellenőrizze, hogy vannak-e a szükséges fejlécek (engedélyezés, x-ms-certificate-url, x-ms-signature-algoritmus).
Töltse le a tartalom aláírásához használt tanúsítványt (x-ms-certificate-url).
Ellenőrizze a tanúsítványláncot.
Ellenőrizze a tanúsítvány "szervezetét".
Olvassa el a tartalmat UTF8 kódolással egy pufferbe.
Hozzon létre egy RSA titkosítási szolgáltatót.
Ellenőrizze, hogy az adatok megegyeznek-e a megadott kivonatoló algoritmussal (például SHA256) aláírt adatokkal.
Ha az ellenőrzés sikeres, dolgozza fel az üzenetet.
Feljegyzés
Alapértelmezés szerint az aláírási jogkivonat egy engedélyezési fejlécben lesz elküldve. Ha a SignatureTokenToMsSignatureHeadert igaz értékre állítja a regisztrációban, az aláírási jogkivonatot a rendszer az x-ms-signature fejlécben küldi el.
Eseménymodell
Az alábbi táblázat egy Partnerközpont-esemény tulajdonságait ismerteti.
Tulajdonságok
Név | Leírás |
---|---|
EventName | Az esemény neve. A(z) {resource}-{action} formában. Például: "test-created". |
ResourceUri | A módosított erőforrás URI-ja. |
ResourceName | A módosított erőforrás neve. |
AuditUrl | Opcionális. A naplózási rekord URI-ja. |
ResourceChangeUtcDate | Az erőforrás változásának dátuma és időpontja UTC formátumban. |
Minta
Az alábbi minta egy Partnerközpont-esemény struktúráját mutatja be.
{
"EventName": "test-created",
"ResourceUri": "http://api.partnercenter.microsoft.com/webhooks/v1/registration/validationEvents/c0bfd694-3075-4ec5-9a3c-733d3a890a1f",
"ResourceName": "test",
"AuditUri": null,
"ResourceChangeUtcDate": "2017-11-16T16:19:06.3520276+00:00"
}
Webhook API-k
Hitelesítés
A Webhook API-khoz intézett összes hívás hitelesítése az Engedélyezési fejléc Tulajdonos jogkivonatával történik. Hozzáférési jogkivonat beszerzése a hozzáféréshez https://api.partnercenter.microsoft.com
. Ez a jogkivonat ugyanaz a jogkivonat, amely a Partnerközpont többi API-jának eléréséhez használatos.
Események listájának lekérése
A Webhook API-k által jelenleg támogatott események listáját adja vissza.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration/events
Példa kérése
GET /webhooks/v1/registration/events
content-type: application/json
authorization: Bearer eyJ0e.......
accept: */*
host: api.partnercenter.microsoft.com
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 183
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: c0bcf3a3-46e9-48fd-8e05-f674b8fd5d66
MS-RequestId: 79419bbb-06ee-48da-8221-e09480537dfc
X-Locale: en-US
[ "subscription-updated", "test-created", "usagerecords-thresholdExceeded" ]
Regisztráció események fogadásához
Regisztrál egy bérlőt a megadott események fogadásához.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration
Példa kérése
POST /webhooks/v1/registration
Content-Type: application/json
Authorization: Bearer eyJ0e.....
Accept: */*
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Content-Length: 219
{
"WebhookUrl": "{{YourCallbackUrl}}",
"WebhookEvents": ["subscription-updated", "test-created"]
}
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 346
Content-Type: application/json; charset=utf-8
content-encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: 718f2336-8b56-4f42-93ac-54896047c59a
MS-RequestId: f04b1b5e-87b4-4d95-b087-d65fffec0bd2
{
"SubscriberId": "e82cac64-dc67-4cd3-849b-78b6127dd57d",
"WebhookUrl": "{{YourCallbackUrl}}",
"WebhookEvents": [ "subscription-updated", "test-created" ]
}
Regisztráció megtekintése
Egy bérlő Webhooks-eseményregisztrációját adja vissza.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration
Példa kérése
GET /webhooks/v1/registration
Content-Type: application/json
Authorization: Bearer ...
Accept: */*
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 341
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: c3b88ab0-b7bc-48d6-8c55-4ae6200f490a
MS-RequestId: ca30367d-4b24-4516-af08-74bba6dc6657
X-Locale: en-US
{
"WebhookUrl": "{{YourCallbackUrl}}",
"WebhookEvents": ["subscription-updated", "test-created"]
}
Eseményregisztráció frissítése
Frissítések egy meglévő eseményregisztrációt.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration
Példa kérése
PUT /webhooks/v1/registration
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOR...
Accept: */*
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Content-Length: 258
{
"WebhookUrl": "{{YourCallbackUrl}}",
"WebhookEvents": ["subscription-updated", "test-created"]
}
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 346
Content-Type: application/json; charset=utf-8
content-encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: 718f2336-8b56-4f42-93ac-54896047c59a
MS-RequestId: f04b1b5e-87b4-4d95-b087-d65fffec0bd2
{
"SubscriberId": "e82cac64-dc67-4cd3-849b-78b6127dd57d",
"WebhookUrl": "{{YourCallbackUrl}}",
"WebhookEvents": [ "subscription-updated", "test-created" ]
}
Tesztesemény küldése a regisztráció ellenőrzéséhez
Létrehoz egy teszteseményt a Webhooks-regisztráció ellenőrzéséhez. Ez a teszt annak ellenőrzésére szolgál, hogy fogadhat-e eseményeket a Partnerközpontból. Az események adatai hét nappal a kezdeti esemény létrehozása után törlődnek. Az érvényesítési esemény elküldése előtt regisztrálnia kell magát a "teszt által létrehozott" eseményre a regisztrációs API használatával.
Feljegyzés
Az érvényesítési esemény közzétételekor percenként 2 kérelemre vonatkozó korlátozás van érvényben.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration/validationEvents
Példa kérése
POST /webhooks/v1/registration/validationEvents
MS-CorrelationId: 3ef0202b-9d00-4f75-9cff-15420f7612b3
Authorization: Bearer ...
Accept: */*
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Content-Length:
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 181
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: 04af2aea-d413-42db-824e-f328001484d1
MS-RequestId: 2f498d5a-a6ab-468f-98d8-93c96da09051
X-Locale: en-US
{ "correlationId": "04af2aea-d413-42db-824e-f328001484d1" }
Az esemény kézbesítésének ellenőrzése
Az érvényesítési esemény aktuális állapotát adja vissza. Ez az ellenőrzés hasznos lehet az eseménykézbesítési problémák elhárításához. A válasz minden egyes, az esemény kézbesítésére tett kísérlet eredményét tartalmazza.
Erőforrás URL-címe
https://api.partnercenter.microsoft.com/webhooks/v1/registration/validationEvents/{correlationId}
Példa kérése
GET /webhooks/v1/registration/validationEvents/04af2aea-d413-42db-824e-f328001484d1
MS-CorrelationId: 3ef0202b-9d00-4f75-9cff-15420f7612b3
Authorization: Bearer ...
Accept: */*
Host: api.partnercenter.microsoft.com
Accept-Encoding: gzip, deflate
Példa válaszra
HTTP/1.1 200
Status: 200
Content-Length: 469
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
MS-CorrelationId: 497e0a23-9498-4d6c-bd6a-bc4d6d0054e7
MS-RequestId: 0843bdb2-113a-4926-a51c-284aa01d722e
X-Locale: en-US
{
"correlationId": "04af2aea-d413-42db-824e-f328001484d1",
"partnerId": "00234d9d-8c2d-4ff5-8c18-39f8afc6f7f3",
"status": "completed",
"callbackUrl": "{{YourCallbackUrl}}",
"results": [{
"responseCode": "OK",
"responseMessage": "",
"systemError": false,
"dateTimeUtc": "2017-12-08T21:39:48.2386997"
}]
}
Példa aláírás-ellenőrzésre
Minta visszahívásvezérlő aláírása (ASP.NET)
[AuthorizeSignature]
[Route("webhooks/callback")]
public IHttpActionResult Post(PartnerResourceChangeCallBack callback)
Aláírás érvényesítése
Az alábbi példa bemutatja, hogyan adhat hozzá engedélyezési attribútumot ahhoz a vezérlőhöz, amely visszahívásokat fogad a Webhook-eseményekről.
namespace Webhooks.Security
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using Microsoft.Partner.Logging;
/// <summary>
/// Signature based Authorization
/// </summary>
public class AuthorizeSignatureAttribute : AuthorizeAttribute
{
private const string MsSignatureHeader = "x-ms-signature";
private const string CertificateUrlHeader = "x-ms-certificate-url";
private const string SignatureAlgorithmHeader = "x-ms-signature-algorithm";
private const string MicrosoftCorporationIssuer = "O=Microsoft Corporation";
private const string SignatureScheme = "Signature";
/// <inheritdoc/>
public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
ValidateAuthorizationHeaders(actionContext.Request);
await VerifySignature(actionContext.Request);
}
private static async Task<string> GetContentAsync(HttpRequestMessage request)
{
// By default the stream can only be read once and we need to read it here so that we can hash the body to validate the signature from microsoft.
// Load into a buffer, so that the stream can be accessed here and in the api when it binds the content to the expected model type.
await request.Content.LoadIntoBufferAsync();
var s = await request.Content.ReadAsStreamAsync();
var reader = new StreamReader(s);
var body = await reader.ReadToEndAsync();
// set the stream position back to the beginning
if (s.CanSeek)
{
s.Seek(0, SeekOrigin.Begin);
}
return body;
}
private static void ValidateAuthorizationHeaders(HttpRequestMessage request)
{
var authHeader = request.Headers.Authorization;
if (string.IsNullOrWhiteSpace(authHeader?.Parameter) && string.IsNullOrWhiteSpace(GetHeaderValue(request.Headers, MsSignatureHeader)))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Authorization header missing."));
}
var signatureHeaderValue = GetHeaderValue(request.Headers, MsSignatureHeader);
if (authHeader != null
&& !string.Equals(authHeader.Scheme, SignatureScheme, StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrWhiteSpace(signatureHeaderValue)
&& !signatureHeaderValue.StartsWith(SignatureScheme, StringComparison.OrdinalIgnoreCase))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Unauthorized, $"Authorization scheme needs to be '{SignatureScheme}'."));
}
if (string.IsNullOrWhiteSpace(GetHeaderValue(request.Headers, CertificateUrlHeader)))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, $"Request header {CertificateUrlHeader} missing."));
}
if (string.IsNullOrWhiteSpace(GetHeaderValue(request.Headers, SignatureAlgorithmHeader)))
{
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.BadRequest, $"Request header {SignatureAlgorithmHeader} missing."));
}
}
private static string GetHeaderValue(HttpHeaders headers, string key)
{
headers.TryGetValues(key, out var headerValues);
return headerValues?.FirstOrDefault();
}
private static async Task VerifySignature(HttpRequestMessage request)
{
// Get signature value from either authorization header or x-ms-signature header.
var base64Signature = request.Headers.Authorization?.Parameter ?? GetHeaderValue(request.Headers, MsSignatureHeader).Split(' ')[1];
var signatureAlgorithm = GetHeaderValue(request.Headers, SignatureAlgorithmHeader);
var certificateUrl = GetHeaderValue(request.Headers, CertificateUrlHeader);
var certificate = await GetCertificate(certificateUrl);
var content = await GetContentAsync(request);
var alg = signatureAlgorithm.Split('-'); // for example RSA-SHA1
var isValid = false;
var logger = GetLoggerIfAvailable(request);
// Validate the certificate
VerifyCertificate(certificate, request, logger);
if (alg.Length == 2 && alg[0].Equals("RSA", StringComparison.OrdinalIgnoreCase))
{
var signature = Convert.FromBase64String(base64Signature);
var csp = (RSACryptoServiceProvider)certificate.PublicKey.Key;
var encoding = new UTF8Encoding();
var data = encoding.GetBytes(content);
var hashAlgorithm = alg[1].ToUpper();
isValid = csp.VerifyData(data, CryptoConfig.MapNameToOID(hashAlgorithm), signature);
}
if (!isValid)
{
// log that we were not able to validate the signature
logger?.TrackTrace(
"Failed to validate signature for webhook callback",
new Dictionary<string, string> { { "base64Signature", base64Signature }, { "certificateUrl", certificateUrl }, { "signatureAlgorithm", signatureAlgorithm }, { "content", content } });
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Signature verification failed"));
}
}
private static ILogger GetLoggerIfAvailable(HttpRequestMessage request)
{
return request.GetDependencyScope().GetService(typeof(ILogger)) as ILogger;
}
private static async Task<X509Certificate2> GetCertificate(string certificateUrl)
{
byte[] certBytes;
using (var webClient = new WebClient())
{
certBytes = await webClient.DownloadDataTaskAsync(certificateUrl);
}
return new X509Certificate2(certBytes);
}
private static void VerifyCertificate(X509Certificate2 certificate, HttpRequestMessage request, ILogger logger)
{
if (!certificate.Verify())
{
logger?.TrackTrace("Failed to verify certificate for webhook callback.", new Dictionary<string, string> { { "Subject", certificate.Subject }, { "Issuer", certificate.Issuer } });
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Certificate verification failed."));
}
if (!certificate.Issuer.Contains(MicrosoftCorporationIssuer))
{
logger?.TrackTrace($"Certificate not issued by {MicrosoftCorporationIssuer}.", new Dictionary<string, string> { { "Issuer", certificate.Issuer } });
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.Unauthorized, $"Certificate not issued by {MicrosoftCorporationIssuer}."));
}
}
}
}
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: