Créer un proxy d’API pour un GeoCatalog à l’aide de Gestion des API Azure

Cet article vous guide tout au long de la configuration de Azure API Management (APIM) en tant que proxy d'API pour le Microsoft Planetary Computer Pro GeoCatalog. Avec cette configuration, vous pouvez :

  • Activer l’accès anonyme : les appelants n’ont pas besoin de leurs propres informations d’identification Microsoft Entra. APIM s’authentifie auprès de GeoCatalog pour son compte à l’aide d’une identité managée.
  • Authentification non Entra : les appelants peuvent prendre en charge les méthodes d’authentification non basées sur Entra. APIM s’authentifie auprès de GeoCatalog pour son compte à l’aide d’une identité managée.
  • Appliquez le contrôle d’accès au niveau de la collection : limitez les collections Spatiotemporal Access Catalog (STAC) visibles par le biais du proxy, même si les geoCatalogs ne prennent pas en charge en mode natif le contrôle d’accès en fonction du rôle (RBAC) au niveau de la collection.

Le diagramme suivant illustre l’architecture avant et après l’ajout du proxy APIM :

Avant Chaque appelant s’authentifie directement auprès de GeoCatalog :

caller ──(Entra token)──► GeoCatalog

Après APIM se trouve entre les appelants et geoCatalog, la gestion de l’authentification et du contrôle d’accès :

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

Prerequisites

Affecter l’identité managée à APIM

Avant que APIM puisse s’authentifier auprès de votre GeoCatalog, vous devez associer l’identité managée affectée par l’utilisateur à l’instance APIM.

  1. Dans le portail Azure, accédez à votre instance Gestion des API.
  2. Sélectionnez Identité dans la barre latérale gauche.
  3. Sélectionnez l’onglet Affecté à l’utilisateur.
  4. Sélectionnez Ajouter, puis choisissez l’identité managée affectée par l’utilisateur qui a le rôle Lecteur GeoCatalog sur votre GeoCatalog .
  5. Sélectionnez Ajouter pour confirmer.

Créer l’API dans APIM

Définissez une nouvelle API dans APIM qui proxy les demandes vers votre back-end GeoCatalog.

  1. Dans votre instance APIM, sélectionnez les API dans la barre latérale gauche.

  2. Sélectionnez + Ajouter l’API>HTTP.

  3. Configurez l’API avec les paramètres suivants :

    Réglage Valeur
    Nom d'affichage Nom descriptif (par exemple, GeoCatalog API)
    Web service URL Votre point de terminaison GeoCatalog (par exemple, https://<name>.<id>.<region>.geocatalog.spatio.azure.com)
    Modèle d’URL HTTPS
    Suffixe de l’URL de l’API Laisser vide (chemin racine)
    Abonnement requis Non, pour l’accès anonyme ; Oui, pour l’accès basé sur la clé d’abonnement
  4. Cliquez sur Créer.

Définir des opérations d’API

Ajoutez les opérations suivantes pour correspondre à la surface de l’API GeoCatalog. Les opérations génériques (/*) transfèrent toutes les demandes correspondantes au back-end. Les opérations de collection explicites vous permettent d’appliquer des stratégies spécifiques à la collection ultérieurement pour le contrôle d’accès.

Nom d'affichage Méthode Modèle d’URL
GET GET /*
Obtenir des éléments de collection GET /stac/collections/{collection_id}/items
Obtenir une collection unique GET /stac/collections/{collection_id}
Obtenir des sous-ressources de collection GET /stac/collections/{collection_id}/*
POST POST /*

Pour ajouter chaque opération :

  1. Sélectionnez l’API que vous avez créée.
  2. Sélectionnez + Ajouter une opération.
  3. Entrez le nom d’affichage, la méthode et le modèle d’URL du tableau précédent.
  4. Cliquez sur Enregistrer.

Configurer la stratégie au niveau de l’API

La stratégie au niveau de l’API gère l’authentification et la réécriture d’URL pour l’ensemble de l’API. Cette stratégie acquiert un jeton à partir de l’identité managée affectée par l’utilisateur et l’attache à chaque requête transférée au serveur principal GeoCatalog.

  1. Sélectionnez l’API que vous avez créée, puis sélectionnez Toutes les opérations.
  2. Dans la section Traitement entrant , sélectionnez l’icône </> (éditeur de code).
  3. Remplacez le contenu de la stratégie par la stratégie suivante :
<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>

Remplacez les espaces réservés suivants :

Espace réservé Valeur
<managed-identity-client-id> ID client de l'identité managée attribuée par l'utilisateur à APIM
<name>.<id>.<region> Vos composants d'endpoint GeoCatalog
<apim-name> Nom de votre instance APIM

Le tableau suivant décrit chaque élément de stratégie :

Élément de stratégie Objectif
authentication-managed-identity Acquiert un jeton pour l’audience en utilisant l’identité managée spécifiée https://geocatalog.spatio.azure.com et l’attache à la demande sortante.
set-header (supprimer Accept-Encoding) Supprime l’en-tête Accept-Encoding des demandes entrantes. Découvrez pourquoi supprimer Accept-Encoding.
find-and-replace Réécrit l’URL du back-end GeoCatalog dans les corps de réponse à l’URL de passerelle APIM. Sans cette réécriture, les liens STAC (self, root, parentet ainsi de suite) exposent l’URL principale aux appelants.

Pourquoi supprimer Accept-Encoding

Les clients tels que Python requests et httpx envoient Accept-Encoding: gzip, deflate par défaut. Lorsque le serveur principal reçoit cet en-tête, il retourne une réponse compressée. Les stratégies sortantes APIM telles que find-and-replace fonctionnent sur le corps de la réponse brute et ne peuvent pas le décompresser, elles n'ont donc aucun effet en silence. La suppression de l’en-tête force le serveur à retourner une réponse décompressée que les politiques de sortie peuvent traiter.

Note

curl et wget n’envoyez Accept-Encoding pas par défaut. Cela signifie que les stratégies sortantes semblent fonctionner correctement lorsque vous testez avec ces outils. L’incohérence s’affiche uniquement avec les clients qui demandent la compression.

Appliquer le contrôle d’accès au niveau de la collection

Par défaut, un GeoCatalog expose toutes ses collections à n’importe quel appelant authentifié. Pour restreindre les collections visibles via APIM, appliquez des stratégies au niveau de l’opération qui bloquent la large découverte STAC et appliquent une liste d'autorisation.

Définir les collections autorisées

Créez une valeur nommée dans APIM pour stocker la liste des ID de collection autorisés :

  1. Dans votre instance APIM, sélectionnez Valeurs nommées dans la barre latérale gauche.
  2. Sélectionnez + Ajouter.
  3. Définissez le nom sur allowed-collections.
  4. Définissez la valeur sur une liste séparée par des virgules d'ID de collection autorisé (par exemple, sentinel-2-l2a,landsat-8-c2-l2).
  5. Cliquez sur Enregistrer.

Bloquer la page d’accueil et la liste des collections

Bloquez les itinéraires qui révèlent chaque collection dans le catalogue. Ajoutez les opérations suivantes et attachez une politique qui renvoie 404 immédiatement :

Nom d'affichage Méthode Modèle d’URL
Bloquer la racine GET /
Regroupements de blocs GET /stac/collections

Appliquez la stratégie de niveau opération suivante aux deux opérations :

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

Le point de terminaison STAC /stac/search accepte un collections paramètre , sous la forme d’une chaîne de requête sur GET ou dans le corps JSON sur POST. Sans garde-fous, un appelant peut rechercher dans chaque collection du catalogue. Les politiques suivantes valident que seules les collections de l'ensemble permis sont demandées.

Ajoutez deux opérations :

Nom d'affichage Méthode Modèle d’URL
Recherche GET GET /stac/search
Recherche POST POST /stac/search

GET /stac/stratégie de recherche

Cette stratégie valide le collections paramètre de requête. Chaque valeur séparée par des virgules doit être dans le jeu autorisé. Les requêtes sans collections paramètre sont rejetées avec 403 Forbidden.

Appliquez la stratégie suivante à l’opération de recherche GET :

<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

Les expressions de stratégie APIM s’exécutent dans un environnement C# restreint. Utilisez condition='@{...}' (attribut entre guillemets simples) pour que les guillemets doubles fonctionnent à l’intérieur de l’expression. Évitez les paramètres de type générique (par exemple GetValueOrDefault<string>) et les lambda LINQ : utilisez plutôt des conversions de type explicites et des boucles foreach explicites.

POST /stac/politique de recherche

Cette stratégie analyse le corps JSON et valide le collections tableau. Les requêtes sans collections paramètre sont rejetées avec 403 Forbidden.

Appliquez la stratégie suivante à l’opération de recherche POST :

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

Appliquer les collections autorisées sur les points de terminaison de collection

Sans opérations explicites, les requêtes telles que GET /stac/collections/sentinel-2-l2a ou GET /stac/collections/sentinel-2-l2a/items passent au wildcard et atteignent le back-end sans vérification au niveau de la collection GET /*. Appliquez la stratégie de paramètre de chemin qui valide collection_id par rapport à {{allowed-collections}} aux opérations suivantes que vous avez créées dans Définir les opérations d'API :

Nom d'affichage Méthode Modèle d’URL
Obtenir une collection unique GET /stac/collections/{collection_id}
Obtenir des sous-ressources de collection GET /stac/collections/{collection_id}/*
Récupérer des éléments de collection GET /stac/collections/{collection_id}/items

Appliquez la stratégie suivante aux trois opérations suivantes :

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

Appliquer des collections autorisées sur des itinéraires de jeton SAS

L’API SAS GeoCatalog permet aux appelants de générer des jetons de stockage et de signer des ressources HREFs. Sans restrictions, un appelant peut obtenir des jetons pour n’importe quelle collection. Les stratégies suivantes garantissent que seules les collections autorisées sont accessibles.

Ajoutez les opérations suivantes :

Nom d'affichage Méthode Modèle d’URL
Obtenir un jeton SAS GET /sas/token/{collection_id}
Bloquer le signe SAP GET /sas/sign

Appliquez la 404 stratégie de blocage (identique au bloc racine et des collections) à l’opération de signature SAS de blocage. Les appelants doivent plutôt utiliser /sas/token/{collection_id} pour obtenir des jetons SAS de niveau collection.

Appliquez la stratégie suivante à l’opération de jeton GET SAS :

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

Appliquer des regroupements autorisés sur des itinéraires de données

Les /data/mosaic/ points de terminaison fournissent le rendu des tuiles, les recadrages par boîte englobante et l'enregistrement de recherche. Deux groupes de stratégies sont nécessaires :

  1. Recherche d'enregistrement - validez le collections tableau dans le corps JSON.
  2. Toutes les autres routes de collection : validez le paramètre de chemin collectionId.

Ajoutez les opérations suivantes :

Nom d'affichage Méthode Modèle d’URL
Recherche de registre POST POST /data/mosaic/register
Collecte de données GET GET /data/mosaic/collections/{collectionId}/*

POST /data/mosaïque/stratégie d’inscription

Cette politique valide le collections tableau du corps JSON par rapport à l'ensemble autorisé. Les requêtes sans collections paramètre sont rejetées.

<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/mosaïque/collections/{collectionId}/* politique

Cette politique valide le paramètre de chemin collectionId par rapport au jeu autorisé. Appliquez cette stratégie aux deux opérations de collecte de données 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>

Questions fréquemment posées

Comment mettre à jour la liste des regroupements autorisés ?

Modifiez la allowed-collections valeur nommée dans l’instance APIM. Aucune modification de stratégie n’est nécessaire.

Que se passe-t-il si un appelant omet le paramètre collections ?

La demande est rejetée avec 403 Forbidden. Les appelants doivent toujours spécifier les collections qu’ils souhaitent rechercher.