Megosztás a következőn keresztül:


Hogyan használhatja ki egy Service Fabric-alkalmazás kezelt identitását az Azure-szolgáltatások eléréséhez?

A Service Fabric-alkalmazások felügyelt identitásokat használhatnak a Microsoft Entra ID-alapú hitelesítést támogató egyéb Azure-erőforrások eléréséhez. Az alkalmazások beszerezhetik az identitását jelképező hozzáférési jogkivonatot, amely lehet rendszer által hozzárendelt vagy felhasználó által hozzárendelt, és "tulajdonosi" jogkivonatként használva hitelesítheti magát egy másik szolgáltatásban , más néven védett erőforrás-kiszolgálón. A jogkivonat a Service Fabric-alkalmazáshoz rendelt identitást jelöli, és csak olyan Azure-erőforrások számára lesz kibocsátva (beleértve az SF-alkalmazásokat is), amelyek megosztják az identitást. A felügyelt identitások részletes leírásáért, valamint a rendszer által hozzárendelt és a felhasználó által hozzárendelt identitások közötti különbségtételért tekintse meg a felügyelt identitások áttekintési dokumentációját. Ebben a cikkben egy felügyelt identitás-kompatibilis Service Fabric-alkalmazásra fogunk hivatkozni ügyfélalkalmazásként.

Tekintse meg a Társ mintaalkalmazást, amely bemutatja, hogy a Rendszer által hozzárendelt és a felhasználó által hozzárendelt Service Fabric-alkalmazás által felügyelt identitásokat használ a Reliable Services és a tárolók használatával.

Fontos

A felügyelt identitás egy Azure-erőforrás és egy szolgáltatásnév közötti társítást jelöli az erőforrást tartalmazó előfizetéshez társított megfelelő Microsoft Entra-bérlőben. Ezért a Service Fabric kontextusában a felügyelt identitások csak az Azure-erőforrásokként üzembe helyezett alkalmazások esetében támogatottak.

Fontos

A Service Fabric-alkalmazások felügyelt identitásának használata előtt az ügyfélalkalmazásnak hozzáférést kell biztosítani a védett erőforráshoz. Tekintse meg azoknak az Azure-szolgáltatásoknak a listáját , amelyek támogatják a Microsoft Entra-hitelesítést a támogatás ellenőrzéséhez, majd tekintse meg a megfelelő szolgáltatás dokumentációját az identitásnak a fontos erőforrásokhoz való hozzáférésének biztosításához szükséges konkrét lépésekről.

Felügyelt identitás használata az Azure.Identity használatával

Az Azure Identity SDK mostantól támogatja a Service Fabricet. Az Azure.Identity használatával egyszerűbbé válik a Service Fabric-alkalmazás által felügyelt identitások használatára vonatkozó kódírás, mivel ez kezeli a jogkivonatok lekérését, a jogkivonatok gyorsítótárazását és a kiszolgálóhitelesítést. A legtöbb Azure-erőforrás elérésekor a jogkivonat fogalma rejtve van.

A Service Fabric támogatása az alábbi nyelveken érhető el:

C#-minta a hitelesítő adatok inicializálására és a hitelesítő adatok használatával egy titkos kód lekérésére az Azure Key Vaultból:

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

namespace MyMIService
{
    internal sealed class MyMIService : StatelessService
    {
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            try
            {
                // Load the service fabric application managed identity assigned to the service
                ManagedIdentityCredential creds = new ManagedIdentityCredential();

                // Create a client to keyvault using that identity
                SecretClient client = new SecretClient(new Uri("https://mykv.vault.azure.net/"), creds);

                // Fetch a secret
                KeyVaultSecret secret = (await client.GetSecretAsync("mysecret", cancellationToken: cancellationToken)).Value;
            }
            catch (CredentialUnavailableException e)
            {
                // Handle errors with loading the Managed Identity
            }
            catch (RequestFailedException)
            {
                // Handle errors with fetching the secret
            }
            catch (Exception e)
            {
                // Handle generic errors
            }
        }
    }
}

Hozzáférési jogkivonat beszerzése REST API használatával

A felügyelt identitáshoz engedélyezett fürtökben a Service Fabric-futtatókörnyezet egy localhost-végpontot tesz elérhetővé, amellyel az alkalmazások hozzáférési jogkivonatokat szerezhetnek be. A végpont a fürt minden csomópontján elérhető, és az adott csomópont összes entitása számára elérhető. A jogosult hívók hozzáférési jogkivonatokat szerezhetnek be a végpont meghívásával és egy hitelesítési kód bemutatásával; a kódot a Service Fabric-futtatókörnyezet hozza létre minden egyes különálló szolgáltatáskód-csomag aktiválásához, és a szolgáltatáskódcsomagot futtató folyamat élettartamához van kötve.

Pontosabban egy felügyelt identitás-kompatibilis Service Fabric-szolgáltatás környezete a következő változókkal lesz üzembe helyezve:

  • "IDENTITY_ENDPOINT": a szolgáltatás felügyelt identitásának megfelelő localhost-végpont
  • "IDENTITY_HEADER": az aktuális csomóponton található szolgáltatást jelképező egyedi hitelesítési kód
  • "IDENTITY_Standard kiadásRVER_THUMBPRINT": A Service Fabric által felügyelt identitáskiszolgáló ujjlenyomata

Fontos

Az alkalmazáskódnak bizalmas adatként kell figyelembe vennie a "IDENTITY_HEADER" környezeti változó értékét – nem szabad naplózni vagy más módon terjeszteni. A hitelesítési kódnak nincs értéke a helyi csomóponton kívül, vagy miután a szolgáltatást üzemeltető folyamat leállt, de a Service Fabric szolgáltatás identitását képviseli, ezért ugyanúgy kell kezelni, mint magát a hozzáférési jogkivonatot.

Jogkivonat beszerzéséhez az ügyfél a következő lépéseket hajtja végre:

  • URI-t hoz létre a felügyelt identitásvégpont (IDENTITY_ENDPOINT érték) és az API-verzió és a jogkivonathoz szükséges erőforrás (célközönség) összefűzésével
  • get http(s) kérést hoz létre a megadott URI-hoz
  • megfelelő kiszolgálótanúsítvány-érvényesítési logikát ad hozzá
  • fejlécként hozzáadja a hitelesítési kódot (IDENTITY_HEADER értéket) a kérelemhez
  • elküldi a kérelmet

A sikeres válasz tartalmaz egy JSON hasznos adatokat az eredményül kapott hozzáférési jogkivonatot, valamint az azt leíró metaadatokat. A sikertelen válasz tartalmazza a hiba magyarázatát is. A hibakezeléssel kapcsolatos további részletekért lásd alább.

A hozzáférési jogkivonatokat a Service Fabric különböző szinteken (csomópont, fürt, erőforrás-szolgáltató szolgáltatás) gyorsítótárazza, így a sikeres válasz nem feltétlenül jelenti azt, hogy a jogkivonatot közvetlenül a felhasználói alkalmazás kérésére válaszul állították ki. A jogkivonatok az élettartamuknál rövidebb ideig lesznek gyorsítótárazva, így egy alkalmazás garantáltan érvényes jogkivonatot kap. Javasoljuk, hogy az alkalmazáskód gyorsítótárazza magát az általa beszerzett hozzáférési jogkivonatokat; a gyorsítótárazási kulcsnak tartalmaznia kell (a célközönség származtatását).

Kérésminta:

GET 'https://localhost:2377/metadata/identity/oauth2/token?api-version=2019-07-01-preview&resource=https://vault.azure.net/' HTTP/1.1 Secret: 912e4af7-77ba-4fa5-a737-56c8e3ace132

ahol:

Elem Leírás
GET A HTTP-parancs, amely azt jelzi, hogy adatokat szeretne lekérni a végpontról. Ebben az esetben egy OAuth hozzáférési jogkivonat.
https://localhost:2377/metadata/identity/oauth2/token A Service Fabric-alkalmazások felügyelt identitásvégpontja, amely a IDENTITY_ENDPOINT környezeti változón keresztül van megadva.
api-version Egy lekérdezési sztringparaméter, amely megadja a Managed Identity Token Service API-verzióját; jelenleg az egyetlen elfogadott érték az 2019-07-01-preview, és változhat.
resource Egy lekérdezési sztringparaméter, amely a célerőforrás alkalmazásazonosítójának URI-ját jelzi. Ez a kibocsátott jogkivonat (célközönség) jogcímeként aud jelenik meg. Ez a példa egy jogkivonatot kér az Azure Key Vault eléréséhez, amelynek az alkalmazásazonosítója URI https://vault.azure.net/.
Secret Egy HTTP-kérelem fejlécmezője, amelyet a Service Fabric-szolgáltatásokhoz tartozó Service Fabric felügyelt identitásjogkivonat-szolgáltatás igényel a hívó hitelesítéséhez. Ezt az értéket az SF-futtatókörnyezet adja meg IDENTITY_HEADER környezeti változón keresztül.

Mintaválasz:

HTTP/1.1 200 OK
Content-Type: application/json
{
    "token_type":  "Bearer",
    "access_token":  "eyJ0eXAiO...",
    "expires_on":  1565244611,
    "resource":  "https://vault.azure.net/"
}

ahol:

Elem Leírás
token_type A jogkivonat típusa; ebben az esetben a "Tulajdonos" hozzáférési jogkivonat, ami azt jelenti, hogy a jogkivonat előadója ('tulajdonos') a jogkivonat célja.
access_token A kért hozzáférési jogkivonat. Biztonságos REST API meghívásakor a jogkivonat a Authorization kérelem fejlécmezőjében "tulajdonosi" jogkivonatként van beágyazva, így az API hitelesítheti a hívót.
expires_on A hozzáférési jogkivonat lejáratának időbélyege; az "1970-01-01T0:0:0Z UTC" másodpercek számaként jelenik meg, és a jogkivonat jogcímének exp felel meg. Ebben az esetben a jogkivonat 2019-08-08T06:10:11+00:00 (az RFC 3339-ben) lejár.
resource Az az erőforrás, amelyhez a hozzáférési jogkivonat ki lett adva, a resource kérelem lekérdezési sztringparaméterén keresztül van megadva; megfelel a jogkivonat "aud" jogcímének.

Hozzáférési jogkivonat beszerzése C használatával#

A fentiek C#-ban lesznek:

namespace Azure.ServiceFabric.ManagedIdentity.Samples
{
    using System;
    using System.Net.Http;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Web;
    using Newtonsoft.Json;

    /// <summary>
    /// Type representing the response of the SF Managed Identity endpoint for token acquisition requests.
    /// </summary>
    [JsonObject]
    public sealed class ManagedIdentityTokenResponse
    {
        [JsonProperty(Required = Required.Always, PropertyName = "token_type")]
        public string TokenType { get; set; }

        [JsonProperty(Required = Required.Always, PropertyName = "access_token")]
        public string AccessToken { get; set; }

        [JsonProperty(PropertyName = "expires_on")]
        public string ExpiresOn { get; set; }

        [JsonProperty(PropertyName = "resource")]
        public string Resource { get; set; }
    }

    /// <summary>
    /// Sample class demonstrating access token acquisition using Managed Identity.
    /// </summary>
    public sealed class AccessTokenAcquirer
    {
        /// <summary>
        /// Acquire an access token.
        /// </summary>
        /// <returns>Access token</returns>
        public static async Task<string> AcquireAccessTokenAsync()
        {
            var managedIdentityEndpoint = Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT");
            var managedIdentityAuthenticationCode = Environment.GetEnvironmentVariable("IDENTITY_HEADER");
            var managedIdentityServerThumbprint = Environment.GetEnvironmentVariable("IDENTITY_SERVER_THUMBPRINT");
            // Latest api version, 2019-07-01-preview is still supported.
            var managedIdentityApiVersion = Environment.GetEnvironmentVariable("IDENTITY_API_VERSION");
            var managedIdentityAuthenticationHeader = "secret";
            var resource = "https://management.azure.com/";

            var requestUri = $"{managedIdentityEndpoint}?api-version={managedIdentityApiVersion}&resource={HttpUtility.UrlEncode(resource)}";

            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUri);
            requestMessage.Headers.Add(managedIdentityAuthenticationHeader, managedIdentityAuthenticationCode);
            
            var handler = new HttpClientHandler();
            handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, certChain, policyErrors) =>
            {
                // Do any additional validation here
                if (policyErrors == SslPolicyErrors.None)
                {
                    return true;
                }
                return 0 == string.Compare(cert.GetCertHashString(), managedIdentityServerThumbprint, StringComparison.OrdinalIgnoreCase);
            };

            try
            {
                var response = await new HttpClient(handler).SendAsync(requestMessage)
                    .ConfigureAwait(false);

                response.EnsureSuccessStatusCode();

                var tokenResponseString = await response.Content.ReadAsStringAsync()
                    .ConfigureAwait(false);

                var tokenResponseObject = JsonConvert.DeserializeObject<ManagedIdentityTokenResponse>(tokenResponseString);

                return tokenResponseObject.AccessToken;
            }
            catch (Exception ex)
            {
                string errorText = String.Format("{0} \n\n{1}", ex.Message, ex.InnerException != null ? ex.InnerException.Message : "Acquire token failed");

                Console.WriteLine(errorText);
            }

            return String.Empty;
        }
    } // class AccessTokenAcquirer
} // namespace Azure.ServiceFabric.ManagedIdentity.Samples

Key Vault elérése Service Fabric-alkalmazásból felügyelt identitással

Ez a minta a fentiekre épül a Key Vaultban tárolt titkos kulcsok felügyelt identitással való elérésének bemutatásához.

        /// <summary>
        /// Probe the specified secret, displaying metadata on success.  
        /// </summary>
        /// <param name="vault">vault name</param>
        /// <param name="secret">secret name</param>
        /// <param name="version">secret version id</param>
        /// <returns></returns>
        public async Task<string> ProbeSecretAsync(string vault, string secret, string version)
        {
            // initialize a KeyVault client with a managed identity-based authentication callback
            var kvClient = new Microsoft.Azure.KeyVault.KeyVaultClient(new Microsoft.Azure.KeyVault.KeyVaultClient.AuthenticationCallback((a, r, s) => { return AuthenticationCallbackAsync(a, r, s); }));

            Log(LogLevel.Info, $"\nRunning with configuration: \n\tobserved vault: {config.VaultName}\n\tobserved secret: {config.SecretName}\n\tMI endpoint: {config.ManagedIdentityEndpoint}\n\tMI auth code: {config.ManagedIdentityAuthenticationCode}\n\tMI auth header: {config.ManagedIdentityAuthenticationHeader}");
            string response = String.Empty;

            Log(LogLevel.Info, "\n== {DateTime.UtcNow.ToString()}: Probing secret...");
            try
            {
                var secretResponse = await kvClient.GetSecretWithHttpMessagesAsync(vault, secret, version)
                    .ConfigureAwait(false);

                if (secretResponse.Response.IsSuccessStatusCode)
                {
                    // use the secret: secretValue.Body.Value;
                    response = String.Format($"Successfully probed secret '{secret}' in vault '{vault}': {PrintSecretBundleMetadata(secretResponse.Body)}");
                }
                else
                {
                    response = String.Format($"Non-critical error encountered retrieving secret '{secret}' in vault '{vault}': {secretResponse.Response.ReasonPhrase} ({secretResponse.Response.StatusCode})");
                }
            }
            catch (Microsoft.Rest.ValidationException ve)
            {
                response = String.Format($"encountered REST validation exception 0x{ve.HResult.ToString("X")} trying to access '{secret}' in vault '{vault}' from {ve.Source}: {ve.Message}");
            }
            catch (KeyVaultErrorException kvee)
            {
                response = String.Format($"encountered KeyVault exception 0x{kvee.HResult.ToString("X")} trying to access '{secret}' in vault '{vault}': {kvee.Response.ReasonPhrase} ({kvee.Response.StatusCode})");
            }
            catch (Exception ex)
            {
                // handle generic errors here
                response = String.Format($"encountered exception 0x{ex.HResult.ToString("X")} trying to access '{secret}' in vault '{vault}': {ex.Message}");
            }

            Log(LogLevel.Info, response);

            return response;
        }

        /// <summary>
        /// KV authentication callback, using the application's managed identity.
        /// </summary>
        /// <param name="authority">The expected issuer of the access token, from the KV authorization challenge.</param>
        /// <param name="resource">The expected audience of the access token, from the KV authorization challenge.</param>
        /// <param name="scope">The expected scope of the access token; not currently used.</param>
        /// <returns>Access token</returns>
        public async Task<string> AuthenticationCallbackAsync(string authority, string resource, string scope)
        {
            Log(LogLevel.Verbose, $"authentication callback invoked with: auth: {authority}, resource: {resource}, scope: {scope}");
            var encodedResource = HttpUtility.UrlEncode(resource);

            // This sample does not illustrate the caching of the access token, which the user application is expected to do.
            // For a given service, the caching key should be the (encoded) resource uri. The token should be cached for a period
            // of time at most equal to its remaining validity. The 'expires_on' field of the token response object represents
            // the number of seconds from Unix time when the token will expire. You may cache the token if it will be valid for at
            // least another short interval (1-10s). If its expiration will occur shortly, don't cache but still return it to the 
            // caller. The MI endpoint will not return an expired token.
            // Sample caching code:
            //
            // ManagedIdentityTokenResponse tokenResponse;
            // if (responseCache.TryGetCachedItem(encodedResource, out tokenResponse))
            // {
            //     Log(LogLevel.Verbose, $"cache hit for key '{encodedResource}'");
            //
            //     return tokenResponse.AccessToken;
            // }
            //
            // Log(LogLevel.Verbose, $"cache miss for key '{encodedResource}'");
            //
            // where the response cache is left as an exercise for the reader. MemoryCache is a good option, albeit not yet available on .net core.

            var requestUri = $"{config.ManagedIdentityEndpoint}?api-version={config.ManagedIdentityApiVersion}&resource={encodedResource}";
            Log(LogLevel.Verbose, $"request uri: {requestUri}");

            var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUri);
            requestMessage.Headers.Add(config.ManagedIdentityAuthenticationHeader, config.ManagedIdentityAuthenticationCode);
            Log(LogLevel.Verbose, $"added header '{config.ManagedIdentityAuthenticationHeader}': '{config.ManagedIdentityAuthenticationCode}'");

            var response = await httpClient.SendAsync(requestMessage)
                .ConfigureAwait(false);
            Log(LogLevel.Verbose, $"response status: success: {response.IsSuccessStatusCode}, status: {response.StatusCode}");

            response.EnsureSuccessStatusCode();

            var tokenResponseString = await response.Content.ReadAsStringAsync()
                .ConfigureAwait(false);

            var tokenResponse = JsonConvert.DeserializeObject<ManagedIdentityTokenResponse>(tokenResponseString);
            Log(LogLevel.Verbose, "deserialized token response; returning access code..");

            // Sample caching code (continuation):
            // var expiration = DateTimeOffset.FromUnixTimeSeconds(Int32.Parse(tokenResponse.ExpiresOn));
            // if (expiration > DateTimeOffset.UtcNow.AddSeconds(5.0))
            //    responseCache.AddOrUpdate(encodedResource, tokenResponse, expiration);

            return tokenResponse.AccessToken;
        }

        private string PrintSecretBundleMetadata(SecretBundle bundle)
        {
            StringBuilder strBuilder = new StringBuilder();

            strBuilder.AppendFormat($"\n\tid: {bundle.Id}\n");
            strBuilder.AppendFormat($"\tcontent type: {bundle.ContentType}\n");
            strBuilder.AppendFormat($"\tmanaged: {bundle.Managed}\n");
            strBuilder.AppendFormat($"\tattributes:\n");
            strBuilder.AppendFormat($"\t\tenabled: {bundle.Attributes.Enabled}\n");
            strBuilder.AppendFormat($"\t\tnbf: {bundle.Attributes.NotBefore}\n");
            strBuilder.AppendFormat($"\t\texp: {bundle.Attributes.Expires}\n");
            strBuilder.AppendFormat($"\t\tcreated: {bundle.Attributes.Created}\n");
            strBuilder.AppendFormat($"\t\tupdated: {bundle.Attributes.Updated}\n");
            strBuilder.AppendFormat($"\t\trecoveryLevel: {bundle.Attributes.RecoveryLevel}\n");

            return strBuilder.ToString();
        }

        private enum LogLevel
        {
            Info,
            Verbose
        };

        private void Log(LogLevel level, string message)
        {
            if (level != LogLevel.Verbose
                || config.DoVerboseLogging)
            {
                Console.WriteLine(message);
            }
        }

Error handling

A HTTP-válasz fejlécének "állapotkód" mezője a kérés sikerességét jelzi; A 200 OK állapot sikerességet jelez, és a válasz tartalmazza a fent leírt hozzáférési jogkivonatot. Az alábbiakban a lehetséges hibaválaszok rövid felsorolását követjük.

Állapotkód Hiba oka Kezelés
404 Nem található. Ismeretlen hitelesítési kód, vagy az alkalmazás nem lett hozzárendelve felügyelt identitáshoz. Az alkalmazás beállítási vagy jogkivonat-beszerzési kódjának kijavítása.
429 Túl sok kérés. Elérte a szabályozásra vonatkozó korlátot, amelyet a Microsoft Entra ID vagy az SF szab ki. Próbálkozzon újra exponenciális visszalépéssel. Lásd az alábbi útmutatást.
4xx Hiba a kérelemben. Egy vagy több kérelemparaméter helytelen volt. Ne próbálkozzon újra. További információkért tekintse meg a hiba részleteit. A 4xx hibák tervezési időből állnak.
5xx Hiba a szolgáltatásból. A felügyelt identitás alrendszere vagy a Microsoft Entra ID átmeneti hibát adott vissza. Rövid idő után nyugodtan újrapróbálkozhat. Újrapróbálkozáskor szabályozási feltételt (429) kaphat.

Hiba esetén a megfelelő HTTP-válasz törzse tartalmaz egy JSON-objektumot a hiba részleteivel:

Elem Leírás
code Hibakód.
correlationId A hibakereséshez használható korrelációs azonosító.
message A hiba részletes leírása. A hibaleírások bármikor változhatnak. Ne függje magát a hibaüzenetet.

Mintahiba:

{"error":{"correlationId":"7f30f4d3-0f3a-41e0-a417-527f21b3848f","code":"SecretHeaderNotFound","message":"Secret is not found in the request headers."}}

Az alábbiakban a felügyelt identitásokra jellemző Service Fabric-hibák listája található:

Kód Üzenet Leírás
SecretHeaderNotFound A titkos kód nem található a kérelem fejléceiben. A hitelesítési kódot nem adták meg a kéréshez.
ManagedIdentityNotFound A felügyelt identitás nem található a megadott alkalmazásgazda számára. Az alkalmazás nem rendelkezik identitással, vagy a hitelesítési kód ismeretlen.
ArgumentNullOrEmpty Az "erőforrás" paraméter nem lehet null értékű vagy üres sztring. Az erőforrás (célközönség) nem lett megadva a kérelemben.
InvalidApiVersion Az api-verzió nem támogatott. A támogatott verzió a "2019-07-01-preview". A kérelem URI-jában megadott hiányzó vagy nem támogatott API-verzió.
InternalServerError Hiba történt. Hiba történt a felügyelt identitás alrendszerében, valószínűleg a Service Fabric-veremen kívül. Valószínűleg helytelen érték van megadva az erőforráshoz (ellenőrizze, hogy a záró "/"?)

Újrapróbálkozás – útmutató

Általában az egyetlen újrapróbálkozható hibakód a 429 (Túl sok kérés); belső kiszolgálóhibák/5xx hibakódok újrapróbálkozhatnak, de az ok végleges lehet.

A szabályozási korlátok a felügyelt identitás alrendszerére irányuló hívások számára vonatkoznak , különösen a "felsőbb rétegbeli" függőségekre (a Felügyelt identitás Azure szolgáltatására vagy a biztonságos jogkivonat-szolgáltatásra). A Service Fabric a folyamat különböző szintjein gyorsítótárazza a jogkivonatokat, de az érintett összetevők elosztott jellegéből adódóan előfordulhat, hogy a hívó inkonzisztens szabályozási válaszokat tapasztal (például egy alkalmazás egy csomópontján/példányán lesz szabályozva, de nem egy másik csomóponton, miközben jogkivonatot kér ugyanarra az identitásra.) Ha a szabályozási feltétel be van állítva, az ugyanabból az alkalmazásból érkező későbbi kérések meghiúsulhatnak a 429-ben megadott HTTP-állapotkóddal (túl sok kérés) a feltétel törléséig.

Javasoljuk, hogy a szabályozás miatt meghiúsult kérelmeket exponenciális visszalépéssel kísérelje meg újra, az alábbiak szerint:

Hívásindex Művelet a 429 fogadásakor
1 Várjon 1 másodpercet, és próbálkozzon újra
2 Várjon 2 másodpercet, és próbálkozzon újra
3 Várjon 4 másodpercet, és próbálkozzon újra
4 Várjon 8 másodpercet, és próbálkozzon újra
4 Várjon 8 másodpercet, és próbálkozzon újra
5 Várjon 16 másodpercet, és próbálkozzon újra

Erőforrás-azonosítók az Azure-szolgáltatásokhoz

Tekintse meg a Microsoft Entra-hitelesítést támogató Azure-szolgáltatásokat a Microsoft Entra-azonosítót támogató erőforrások és azok erőforrás-azonosítóinak listáját.

Következő lépések