Vytvoření proxy serveru rozhraní API pro GeoCatalog pomocí služby Azure API Management

Tento článek vás provede nastavením služby Azure API Management (APIM) jako proxy rozhraní API před planetárním počítačem Společnosti Microsoft Pro GeoCatalog. S touto konfigurací můžete:

  • Povolit anonymní přístup: Volající nepotřebují vlastní přihlašovací údaje Microsoft Entra. APIM ověřuje svou totožnost v GeoCatalogu jejich jménem pomocí spravované identity.
  • Jiné ověřování než Entra: Volající můžou podporovat ověřovací metody, které nejsou založené na Entra. APIM se ověřuje v GeoCatalogu v jeho zastoupení pomocí spravované identity.
  • Vynutit řízení přístupu na úrovni kolekce: omezit, které kolekce katalogů STAC (Spatiotemporal Access Catalog) jsou viditelné prostřednictvím proxy serveru, přestože GeoCatalogs nativně nepodporují řízení přístupu na úrovni role a kolekce (RBAC - Role-Based Access Control).

Následující diagram znázorňuje architekturu před a po přidání proxy serveru APIM:

Před Každý volající se ověřuje přímo v GeoCatalogu:

caller ──(Entra token)──► GeoCatalog

Po APIM se nachází mezi volajícími a GeoCatalogem, zpracovává ověřování a řízení přístupu:

caller ──(anonymous / APIM Subscription Keys)──► APIM ──(managed identity token)──► GeoCatalog

Předpoklady

Přiřazení spravované identity k APIM

Než může služba APIM ověřit vaši službu GeoCatalog, je potřeba přiřadit uživatelem spravovanou identitu k instanci APIM.

  1. Na portálu Azure přejděte k vaší instanci služby API Management.
  2. Na levém bočním panelu vyberte Identitu .
  3. Vyberte kartu Přiřazeno uživatelem.
  4. Vyberte Přidat, a pak zvolte spravovanou identitu přiřazenou uživatelem, která má v GeoCatalogu roli GeoCatalog Reader.
  5. Potvrďte volbu Přidat.

Vytvoření rozhraní API v APIM

Definujte nové rozhraní API ve službě APIM, které zprostředkovává požadavky do back-endu GeoCatalogu.

  1. V instanci APIM vyberte API z levého panelu.

  2. Vyberte + Přidat rozhraní API>HTTP.

  3. Nakonfigurujte rozhraní API s následujícími nastaveními:

    Setting Value
    Zobrazovaný název Popisný název (například GeoCatalog API)
    Adresa URL webové služby Koncový bod GeoCatalogu (například https://<name>.<id>.<region>.geocatalog.spatio.azure.com)
    Schéma URL HTTPS
    Přípona adresy URL rozhraní API Nechat prázdné (kořenová cesta)
    Požadováno předplatné Ne, pro anonymní přístup; Ano, pro přístup na základě klíče předplatného
  4. Vyberte Vytvořit.

Definování operací rozhraní API

Přidejte následující operace, které odpovídají povrchu rozhraní API GeoCatalog. Operace se zástupným znakem (/*) předávají všechny odpovídající požadavky na back-end. Explicitní operace shromažďování umožňují později použít zásady specifické pro kolekci pro řízení přístupu.

Zobrazované jméno Metoda Šablona adresy URL
GET GET /*
Získejte položky kolekce GET /stac/collections/{collection_id}/items
Získání jedné kolekce GET /stac/collections/{collection_id}
Získání podzdrojů kolekce GET /stac/collections/{collection_id}/*
POST POST /*

Přidání jednotlivých operací:

  1. Vyberte rozhraní API, které jste vytvořili.
  2. Vyberte + Přidat operaci.
  3. Zadejte zobrazovaný název, metodu a šablonu ADRESY URL z předchozí tabulky.
  4. Vyberte Uložit.

Konfigurace zásad na úrovni rozhraní API

Zásady na úrovni rozhraní API zpracovávají ověřování a přepis adres URL pro celé rozhraní API. Tato zásada získá token ze spravované identity přiřazené uživatelem a připojí ho ke každému požadavku odeslanému na backend GeoCatalogu.

  1. Vyberte rozhraní API, které jste vytvořili, a pak vyberte Všechny operace.
  2. V části Zpracování příchozích dat vyberte <ikonu /> (editor kódu).
  3. Obsah zásad nahraďte následujícími zásadami:
<policies>
    <inbound>
        <base />
        <authentication-managed-identity
            resource="https://geocatalog.spatio.azure.com"
            client-id="<managed-identity-client-id>" />
        <set-header name="Accept-Encoding"
            exists-action="delete" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <find-and-replace
            from="https://<name>.<id>.<region>.geocatalog.spatio.azure.com"
            to="https://<apim-name>.azure-api.net" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Nahraďte následující zástupné symboly:

Zástupný symbol Value
<managed-identity-client-id> ID klienta spravované identity přiřazené uživatelem k APIM
<name>.<id>.<region> Komponenty vašeho koncového bodu GeoCatalogu
<apim-name> Název instance APIM

Následující tabulka popisuje jednotlivé elementy zásad:

Prvek zásad Purpose
authentication-managed-identity Získá token pro https://geocatalog.spatio.azure.com cílovou skupinu pomocí zadané spravované identity a připojí ho k odchozí žádosti.
set-header (odstranit Accept-Encoding) Odebere hlavičku Accept-Encoding z příchozích požadavků. Podívejte se na proč odstranit Accept-Encoding.
find-and-replace Přepíše back-endovou adresu URL GeoCatalogu v těle odpovědí na adresu URL brány APIM. Bez tohoto přepisu zveřejní odkazy STAC (self, rootparent, atd.) adresu URL back-endu volajícím.

Proč odstranit Accept-Encoding

Klienti jako Python requests a httpx odesílají výchozím způsobem Accept-Encoding: gzip, deflate. Když back-end obdrží tuto hlavičku, vrátí komprimovanou odpověď. Odchozí zásady APIM, jako je find-and-replace, fungují na nezpracovaném těle odpovědi a nemohou jej dekomprimovat, takže tiše nedělají nic. Odstraněním hlavičky přinutíte back-end vrátit nekomprimovanou odpověď, kterou mohou zpracovat výstupní zásady.

Note

curl a wget ve výchozím nastavení neposílají Accept-Encoding. To znamená, že odchozí zásady se zdají správně fungovat při testování těmito nástroji. Nekonzistence se zobrazí pouze u klientů, kteří požadují kompresi.

Vynucení řízení přístupu na úrovni kolekce

Ve výchozím nastavení geoCatalog zveřejňuje všechny své kolekce všem ověřeným volajícím. Pokud chcete omezit, které kolekce jsou viditelné prostřednictvím SLUŽBY APIM, použijte zásady na úrovni operací, které blokují široké zjišťování STAC a vynucují seznam povolených.

Definování povolených kolekcí

Vytvořte pojmenovanou hodnotu v APIM pro uložení seznamu povolených ID kolekcí:

  1. V instanci APIM vyberte na levém bočním panelu pojmenované hodnoty .
  2. Vyberte + Přidat.
  3. Nastavte název na allowed-collections.
  4. Nastavte hodnotu na čárkami oddělený seznam povolených ID kolekcí (například sentinel-2-l2a,landsat-8-c2-l2).
  5. Vyberte Uložit.

Blokování cílové stránky a seznamu kolekcí

Zablokujte trasy, které odhalí každou kolekci v katalogu. Přidejte následující operace a připojte zásadu, která zajistí okamžité vrácení 404.

Zobrazované jméno Metoda Šablona adresy URL
Blokovat kořenový adresář GET /
Blokové kolekce GET /stac/collections

U obou operací použijte následující zásady na úrovni operací:

<policies>
    <inbound>
        <base />
        <return-response>
            <set-status code="404" reason="Not Found" />
        </return-response>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Koncový bod STAC /stac/search přijímá collections parametr – jako řetězec dotazu na GET nebo v textu JSON v POST. Bez zábradlí by volající mohl prohledávat každou kolekci v katalogu. Následující politiky ověřují, že jsou požadovány pouze kolekce z povoleného souboru.

Přidejte dvě operace:

Zobrazované jméno Metoda Šablona adresy URL
Hledání GET GET /stac/search
Vyhledávání POST POST /stac/search

GET /stac/search policy (vyhledávací pravidlo)

Tato zásada ověří collections parametr dotazu. Každá hodnota oddělená čárkami musí být v povolené sadě. Požadavky bez parametru collections jsou odmítnuty parametrem 403 Forbidden.

Pro operaci vyhledávání GET použijte následující zásady:

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var raw = context.Request.Url.Query
                    .GetValueOrDefault("collections", "");
                if (string.IsNullOrWhiteSpace(raw)) {
                    return true;
                }
                foreach (var c in raw.ToLower().Split(
                    new [] { "," },
                    StringSplitOptions.RemoveEmptyEntries))
                {
                    if (!c.Trim().Equals(allowed)) {
                        return true;
                    }
                }
                return false;
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Note

Výrazy zásad APIM se spouštějí v omezeném prostředí C#. Použijte condition='@{...}' (atribut s jednoduchými uvozovkami), takže dvojité uvozovky fungují uvnitř výrazu. Vyhněte se parametrům obecného typu (například GetValueOrDefault<string>) a lambda výrazům LINQ – místo toho použijte explicitní přetypování a smyčky foreach.

POST /stac/search politika

Tato zásada parsuje tělo JSON a ověří collections array. Požadavky bez parametru collections jsou odmítnuty parametrem 403 Forbidden.

Na operaci hledání POST použijte následující zásady:

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <set-variable name="requestBody"
            value="@(context.Request.Body
                .As&lt;string&gt;(
                    preserveContent: true))" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var body = (string)context
                    .Variables["requestBody"];
                var json = Newtonsoft.Json.Linq
                    .JObject.Parse(body);
                var arr = json["collections"]
                    as Newtonsoft.Json.Linq.JArray;
                if (arr == null || arr.Count == 0) {
                    return true;
                }
                foreach (var token in arr) {
                    if (!token.ToString().Trim()
                        .ToLower().Equals(allowed))
                    {
                        return true;
                    }
                }
                return false;
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Vynucení povolených kolekcí na koncových bodech sbírky

Bez explicitních operací přejdou požadavky typu GET /stac/collections/sentinel-2-l2a nebo GET /stac/collections/sentinel-2-l2a/items ke zástupnému symbolu GET /* a dostanou se na backend bez jakékoliv kontroly na úrovni kolekce. Použijte zásadu parametru cesty, která ověřuje collection_id proti {{allowed-collections}} na následující operace, které jste vytvořili v Definování operací rozhraní API:

Zobrazované jméno Metoda Šablona adresy URL
Získání jedné kolekce GET /stac/collections/{collection_id}
Získání podzdrojů kolekce GET /stac/collections/{collection_id}/*
Získejte položky kolekce GET /stac/collections/{collection_id}/items

U všech tří operací použijte následující zásady:

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var collectionId = (string)context
                    .Request.MatchedParameters[
                        "collection_id"];
                return !collectionId.Trim()
                    .ToLower().Equals(allowed);
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Vynucení povolených kolekcí na trasách tokenů SAS

Rozhraní API SAS GeoCatalog umožňuje volajícím generovat tokeny úložiště a podepisovat HREF prostředků. Bez omezení může volající získat tokeny pro libovolnou kolekci. Následující zásady zajišťují přístup pouze k povoleným kolekcím.

Přidejte následující operace:

Zobrazované jméno Metoda Šablona adresy URL
Získání tokenu SAS GET /sas/token/{collection_id}
Blokovat znaménko SAS GET /sas/sign

Použijte zásadu 404 blokování (stejnou jako blokování kořenového adresáře a kolekcí) na operaci blokování podpisu SAS. Volající by místo toho měli používat /sas/token/{collection_id} pro získání SAS tokenů na úrovni kolekce.

Na operaci tokenu GET SAS použijte následující zásady:

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var collectionId = (string)context
                    .Request.MatchedParameters[
                        "collection_id"];
                return !collectionId.Trim()
                    .ToLower().Equals(allowed);
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Vynucení povolených kolekcí na datových trasách

Koncové /data/mosaic/ body poskytují vykreslování dlaždic, ořezávání ohraničujících rámců a registraci vyhledávání. Jsou potřeba dvě skupiny zásad:

  1. Zaregistrovat vyhledávání – ověřte collections pole v textu JSON.
  2. Všechny ostatní sběrné trasy – ověřte collectionId parametr cesty.

Přidejte následující operace:

Zobrazované jméno Metoda Šablona adresy URL
Hledání v registru POST POST /data/mosaic/register
Shromažďování dat GET GET /data/mosaic/collections/{collectionId}/*

POST /data/mozaika/registrovat zásady

Tato zásada ověří collections array v textu JSON oproti povolené sadě. Požadavky bez parametru collections jsou odmítnuty.

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <set-variable name="requestBody"
            value="@(context.Request.Body
                .As&lt;string&gt;(
                    preserveContent: true))" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var body = (string)context
                    .Variables["requestBody"];
                var json = Newtonsoft.Json.Linq
                    .JObject.Parse(body);
                var arr = json["collections"]
                    as Newtonsoft.Json.Linq.JArray;
                if (arr == null || arr.Count == 0) {
                    return true;
                }
                foreach (var token in arr) {
                    if (!token.ToString().Trim()
                        .ToLower().Equals(allowed))
                    {
                        return true;
                    }
                }
                return false;
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

GET /data/mosaic/collections/{collectionId}/* zásady

Tato zásada ověří collectionId parametr cesty vůči povolené sadě. Tuto zásadu použijte u operací shromažďování dat GET .

<policies>
    <inbound>
        <base />
        <set-variable name="allowedCsv"
            value="{{allowed-collections}}" />
        <choose>
            <when condition='@{
                var allowed = ((string)context
                    .Variables["allowedCsv"])
                    .Trim().ToLower();
                var collectionId = (string)context
                    .Request.MatchedParameters[
                        "collectionId"];
                return !collectionId.Trim()
                    .ToLower().Equals(allowed);
            }'>
                <return-response>
                    <set-status code="403"
                        reason="Forbidden" />
                    <set-body>
                        Collection not allowed.
                    </set-body>
                </return-response>
            </when>
        </choose>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Nejčastější dotazy

Jak můžu aktualizovat seznam povolených kolekcí?

Upravte hodnotu s názvem allowed-collections v instanci APIM. Nejsou potřeba žádné změny zásad.

Co se stane, když volající vynechá parametr kolekce?

Žádost je odmítnuta s 403 Forbidden. Volající musí vždy určit, které kolekce chtějí prohledávat.