Sdílet prostřednictvím


Integrace API brány s Ocelotem

Návod

Tento obsah je výňatek z eBooku, architektury mikroslužeb .NET pro kontejnerizované aplikace .NET, které jsou k dispozici na .NET Docs nebo jako zdarma ke stažení PDF, které lze číst offline.

eBook o architektuře mikroslužeb .NET pro kontejnerizované aplikace .NET, miniatura na obálce.

Důležité

Referenční aplikace mikroslužeb eShopOnContainers v současné době používá funkce, které poskytuje Envoy k implementaci služby API Gateway místo dříve odkazovaných ocelot. Tuto volbu jsme udělali kvůli integrované podpoře protokolu WebSocket v nástroji Envoy, která je vyžadována pro novou komunikaci mezi službami gRPC implementovanou v eShopOnContainers. Tuto část jsme si ale v průvodci zachovali, abyste mohli ocelot považovat za jednoduchou, schopnou a odlehčenou bránu rozhraní API, která je vhodná pro scénáře na úrovni produkce. Nejnovější verze Ocelot také obsahuje zásadní změnu ve schématu JSON. Zvažte použití Ocelot < v16.0.0 nebo použijte klíčové trasy místo ReRoutes.

Navrhujte a architektujte brány rozhraní API

Následující diagram architektury znázorňuje, jak byly brány rozhraní API implementované s Ocelot v eShopOnContainers.

Diagram znázorňující architekturu eShopOnContainers

Obrázek 6–28 Architektura eShopOnContainers s branami rozhraní API

Tento diagram znázorňuje, jak se celá aplikace nasadí do jednoho hostitele Dockeru nebo vývojového počítače s Dockerem pro Windows nebo Dockerem pro Mac. Nasazení do jakéhokoli orchestrátoru by bylo podobné, ovšem každý kontejner v diagramu by se v orchestrátoru mohl škálovat horizontálně.

Kromě toho by se prostředky infrastruktury, jako jsou databáze, mezipaměť a zprostředkovatelé zpráv, měly přesměrovat z orchestrátoru a nasadit je do vysoce dostupných systémů pro infrastrukturu, jako je Azure SQL Database, Azure Cosmos DB, Azure Redis, Azure Service Bus nebo jakékoli místní řešení clusteringu s vysokou dostupností.

Jak si můžete všimnout také v diagramu, několik bran rozhraní API umožňuje, aby bylo více vývojových týmů autonomní (v tomto případě marketingové funkce versus nákupní funkce) při vývoji a nasazování mikroslužeb a vlastních souvisejících bran rozhraní API.

Pokud byste měli jednu monolitickou bránu rozhraní API, která by znamenala, že jeden bod bude aktualizován několika vývojovými týmy, které by mohly spojit všechny mikroslužby s jednou částí aplikace.

Při dalším návrhu může být někdy jemně odstupňovaná brána rozhraní API omezena také na jednu obchodní mikroslužbu v závislosti na zvolené architektuře. Hranice brány rozhraní API diktované firmou nebo doménou vám pomůžou získat lepší návrh.

Například podrobná členitost na úrovni brány rozhraní API může být zvláště užitečná pro pokročilejší složené aplikace uživatelského rozhraní, které jsou založené na mikroslužbách, protože koncept jemně odstupňované brány rozhraní API je podobný službě složení uživatelského rozhraní.

V předchozí části se podíváme na další podrobnosti o vytváření složených uživatelských rozhraní založených na mikroslužbách.

Pro mnoho středně velkých a velkých aplikací je použití na míru vytvořeného produktu API Gateway obvykle dobrým přístupem, ale nemělo by se to stát jediným monolitickým agregátorem nebo unikátní centrální vlastní bránou API, ledaže by tato brána API umožňovala několik nezávislých konfiguračních oblastí pro více vývojových týmů, které vytvářejí autonomní mikroslužby.

Ukázkové mikroslužby nebo kontejnery pro přesměrování přes brány rozhraní API

Například eShopOnContainers má přibližně šest interních typů mikroslužeb, které je potřeba publikovat prostřednictvím bran rozhraní API, jak je znázorněno na následujícím obrázku.

Snímek obrazovky se složkou Services zobrazující její podsložky

Obrázek 6–29 Složky mikroslužeb v řešení eShopOnContainers v rámci sady Visual Studio

O službě Identity v návrhu, jež je vynechána ze směrování API Gateway z důvodu, že se jedná o jedinou průřezovou záležitost v systému, přestože s Ocelotem je možné ji zahrnout jako součást seznamu pro přesměrování.

Všechny tyto služby jsou v současné době implementovány jako ASP.NET základní služby webového rozhraní API, jak můžete zjistit z kódu. Pojďme se zaměřit na jednu z mikroslužeb, jako je kód mikroslužby Katalogu.

Snímek obrazovky Průzkumníka řešení s obsahem projektu Catalog.API

Obrázek 6–30 Ukázková mikroslužba webového rozhraní API (mikroslužba katalogu)

Vidíte, že mikroslužba katalogu je typickým projektem webového rozhraní API ASP.NET Core s několika řadiči a metodami, jako je následující kód.

[HttpGet]
[Route("items/{id:int}")]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType(typeof(CatalogItem),(int)HttpStatusCode.OK)]
public async Task<IActionResult> GetItemById(int id)
{
    if (id <= 0)
    {
        return BadRequest();
    }
    var item = await _catalogContext.CatalogItems.
                                          SingleOrDefaultAsync(ci => ci.Id == id);
    //…

    if (item != null)
    {
        return Ok(item);
    }
    return NotFound();
}

Požadavek HTTP spustí kód v jazyce C#, který přistupuje k databázi mikroslužby, a provádí jakoukoli další požadovanou akci.

Pokud jde o adresu URL mikroslužby, když jsou kontejnery nasazené v místním vývojovém počítači (místním hostiteli Dockeru), kontejner každé mikroslužby má vždy interní port (obvykle port 80) zadaný v jeho souboru Dockerfile, jak je znázorněno v následujícím souboru dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

Port 80 zobrazený v kódu je interní v rámci hostitele Dockeru, takže není dostupný klientskými aplikacemi.

Klientské aplikace mají přístup pouze k externím portům (pokud existují) publikovaným při nasazování pomocí docker-compose.

Tyto externí porty by se neměly publikovat při nasazování do produkčního prostředí. Z tohoto konkrétního důvodu, proč chcete používat bránu rozhraní API, abyste se vyhnuli přímé komunikaci mezi klientskými aplikacemi a mikroslužbami.

Při vývoji ale chcete přistupovat k mikroslužbě nebo kontejneru přímo a spouštět ho přes Swagger. To je důvod, proč se v eShopOnContainers zadají externí porty i v případě, že ji brána ROZHRANÍ API ani klientské aplikace nebudou používat.

Tady je příklad docker-compose.override.yml souboru pro mikroslužbu katalogu:

catalog-api:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=http://0.0.0.0:80
    - ConnectionString=YOUR_VALUE
    - ... Other Environment Variables
  ports:
    - "5101:80"   # Important: In a production environment you should remove the external port (5101) kept here for microservice debugging purposes.
                  # The API Gateway redirects and access through the internal port (80).

V konfiguraci docker-compose.override.yml je interní port katalogového kontejneru nastaven na 80, ale port pro externí přístup je 5101. Tento port by ale aplikace neměla používat při použití služby API Gateway, pouze k ladění, spuštění a testování pouze mikroslužby katalogu.

Za normálních okolností nebudete nasazovat s docker-compose do produkčního prostředí, protože správné produkční prostředí pro mikroslužby je orchestrátor, jako je Kubernetes nebo Service Fabric. Při nasazování do těchto prostředí používáte různé konfigurační soubory, ve kterých nebudete publikovat přímo žádný externí port pro mikroslužby, ale vždy použijete reverzní proxy server z brány rozhraní API.

Spusťte mikroslužbu katalogu v místním hostiteli Dockeru. Buď spusťte úplné řešení eShopOnContainers ze sady Visual Studio (spouští se všechny služby v souborech docker-compose), nebo spusťte mikroslužbu katalogu pomocí následujícího příkazu docker-compose v CMD nebo PowerShellu umístěném ve složce, kde se nachází docker-compose.yml a docker-compose.override.yml jsou umístěné.

docker-compose run --service-ports catalog-api

Tento příkaz spustí pouze kontejner služby catalog-api plus závislosti zadané v docker-compose.yml. V tomto případě kontejner SQL Serveru a kontejner RabbitMQ.

Pak můžete přímo přistupovat k mikroslužbě katalogu a zobrazit jeho metody prostřednictvím uživatelského rozhraní Swaggeru, který přistupuje přímo přes tento "externí" port, v tomto případě http://host.docker.internal:5101/swagger:

Snímek obrazovky s uživatelským rozhraním Swagger zobrazující rozhraní REST API Catalog.API

Obrázek 6–31 Testování mikroslužby katalogu pomocí uživatelského rozhraní Swaggeru

V tomto okamžiku můžete v kódu jazyka C# v sadě Visual Studio nastavit zarážku, otestovat mikroslužbu pomocí metod vystavených v uživatelském rozhraní Swaggeru a nakonec všechno vyčistit pomocí docker-compose down příkazu.

Komunikace s mikroslužbou s přímým přístupem však v tomto případě prostřednictvím externího portu 5101 přesně odpovídá tomu, čemu se v aplikaci chcete vyhnout. A můžete se tomu vyhnout nastavením další úrovně nepřímého směrování API Gateway (Ocelot v tomto případě). Klientská aplikace tak nebude přímo přistupovat k mikroslužbě.

Implementace bran rozhraní API s Ocelotem

Ocelot je v podstatě sada middlewaru, kterou můžete použít v určitém pořadí.

Ocelot je navržený tak, aby fungoval pouze s ASP.NET Core. Nejnovější verze balíčku je 18.0, která cílí na .NET 6, a proto není vhodná pro aplikace rozhraní .NET Framework.

Ocelot a jeho závislosti nainstalujete do projektu ASP.NET Core pomocí balíčku NuGet ocelot ze sady Visual Studio.

Install-Package Ocelot

V eShopOnContainers je implementace služby API Gateway jednoduchou ASP.NET projektem Core WebHost a middleware Ocelot zpracovává všechny funkce služby API Gateway, jak je znázorněno na následujícím obrázku:

Snímek obrazovky Průzkumníka řešení zobrazující projekt brány rozhraní Ocelot API

Obrázek 6–32 Základní projekt OcelotApiGw v eShopOnContainers

Tento projekt ASP.NET Core WebHost je sestaven se dvěma jednoduchými soubory: Program.cs a Startup.cs.

Program.cs stačí pouze vytvořit a nakonfigurovat standardní ASP.NET Core BuildWebHost.

namespace OcelotApiGw
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args)
        {
            var builder = WebHost.CreateDefaultBuilder(args);

            builder.ConfigureServices(s => s.AddSingleton(builder))
                    .ConfigureAppConfiguration(
                          ic => ic.AddJsonFile(Path.Combine("configuration",
                                                            "configuration.json")))
                    .UseStartup<Startup>();
            var host = builder.Build();
            return host;
        }
    }
}

Důležitým bodem zde pro Ocelot je configuration.json soubor, který musíte poskytnout tvůrci prostřednictvím AddJsonFile() metody. Tady configuration.json specifikujete všechny ReRoutes rozhraní API Gateway, což znamená externí koncové body s konkrétními porty a obdobné interní koncové body, obvykle s různými porty.

{
    "ReRoutes": [],
    "GlobalConfiguration": {}
}

Konfigurace má dvě části. Pole ReRoutes a GlobalConfiguration. ReRoutes jsou objekty, které říkají Ocelotovi, jak zacházet s upstreamovou žádostí. Globální konfigurace umožňuje přepsat konkrétní nastavení ReRoute. To je užitečné, pokud nechcete spravovat spoustu konkrétních nastavení ReRoute.

Tady je zjednodušený příklad konfiguračního souboru ReRoute z jedné z bran rozhraní API z eShopOnContainers.

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "catalog-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/c/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ]
    },
    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
    }

  ],
    "GlobalConfiguration": {
      "RequestIdKey": "OcRequestId",
      "AdministrationPath": "/administration"
    }
  }

Hlavní funkcí služby Ocelot API Gateway je přijímat příchozí požadavky HTTP a předávat je do podřízené služby, aktuálně jako další požadavek HTTP. Ocelot popisuje směrování jedné žádosti do druhé jako ReRoute.

Pojďme se například zaměřit na jednu z reroute v configuration.json výše, konfiguraci mikroslužby Basket.

{
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [ "POST", "PUT", "GET" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
}

Objekt DownstreamPathTemplate, Scheme a DownstreamHostAndPorts vytvoří interní adresu URL mikroslužby, na kterou se bude tento požadavek předávat.

Port je interní port používaný službou. Při používání kontejnerů se port určený v dockerfile zadává.

Jedná se Host o název služby, který závisí na rozlišení názvů služeb, které používáte. Při použití docker-compose jsou názvy služeb poskytovány hostitelem Dockeru, který používá názvy služeb poskytované v souborech docker-compose. Pokud používáte orchestrátor, jako je Kubernetes nebo Service Fabric, měl by se tento název přeložit pomocí DNS nebo překladu názvů poskytovaného jednotlivými orchestrátory.

DownstreamHostAndPorts je pole, které obsahuje hostitele a port všech podřízených služeb, kterým chcete předávat požadavky. Tato konfigurace obvykle bude obsahovat jenom jednu položku, ale někdy můžete chtít vyrovnávat zatížení požadavků na podřízené služby a Ocelot vám umožní přidat více než jednu položku a pak vybrat nástroj pro vyrovnávání zatížení. Pokud ale používáte Azure a jakýkoli orchestrátor, je pravděpodobně vhodnější vyrovnávat zatížení s cloudovou a orchestrátorovou infrastrukturou.

UpstreamPathTemplate je adresa URL, kterou Ocelot použije k identifikaci toho, který downstreamPathTemplate použít pro danou žádost od klienta. Nakonec se používá UpstreamHttpMethod, aby Ocelot mohl rozlišovat mezi různými požadavky (GET, POST, PUT) na stejnou adresu URL.

V tuto chvíli můžete mít jednu bránu rozhraní API Ocelot (ASP.NET Core WebHost) pomocí jednoho nebo více sloučených souborů configuration.json nebo můžete konfiguraci uložit také do úložiště Consul KV.

Jak je ale uvedeno v částech architektury a návrhu, pokud opravdu chcete mít autonomní mikroslužby, může být lepší rozdělit tuto monolitickou bránu rozhraní API na několik bran rozhraní API a/nebo BFF (back-end pro front-end). Pro tento účel se podíváme, jak tento přístup implementovat s kontejnery Dockeru.

Použití jedné jediné Docker image ke spuštění více různých typů kontejnerů API Gateway / BFF.

V eShopOnContainers používáme jednu image kontejneru Dockeru se službou Ocelot API Gateway, ale v době běhu vytvoříme různé služby/kontejnery pro každý typ služby API-Gateway/BFF tím, že poskytneme jiný soubor configuration.json pomocí svazku Dockeru pro přístup k jiné složce PC pro každou službu.

Diagram jedné image Dockeru brány Ocelot pro všechny brány rozhraní API

Obrázek 6–33 Opětovné použití jednoho Ocelot Docker image napříč různými typy API Gateway

V eShopOnContainers je vytvořen "Generic Ocelot API Gateway Docker Image" s projektem nazvaným "OcelotApiGw" a obrazem s názvem "eshop/ocelotapigw", který je specifikován v souboru docker-compose.yml. Při nasazování do Dockeru pak budou čtyři kontejnery API-Gateway vytvořené ze stejné image Dockeru, jak je znázorněno v následujícím extrakci ze souboru docker-compose.yml.

  mobileshoppingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  mobilemarketingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  webshoppingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

  webmarketingapigw:
    image: eshop/ocelotapigw:${TAG:-latest}
    build:
      context: .
      dockerfile: src/ApiGateways/ApiGw-Base/Dockerfile

Kromě toho, jak vidíte v následujícím souboru docker-compose.override.yml, jediným rozdílem mezi těmito kontejnery služby API Gateway je konfigurační soubor Ocelot, který se pro každý kontejner služby liší a je určený za běhu prostřednictvím svazku Dockeru.

mobileshoppingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5200:80"
  volumes:
    - ./src/ApiGateways/Mobile.Bff.Shopping/apigw:/app/configuration

mobilemarketingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5201:80"
  volumes:
    - ./src/ApiGateways/Mobile.Bff.Marketing/apigw:/app/configuration

webshoppingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5202:80"
  volumes:
    - ./src/ApiGateways/Web.Bff.Shopping/apigw:/app/configuration

webmarketingapigw:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - IdentityUrl=http://identity-api
  ports:
    - "5203:80"
  volumes:
    - ./src/ApiGateways/Web.Bff.Marketing/apigw:/app/configuration

Kvůli předchozímu kódu a jak je znázorněno v níže uvedeném Visual Studio Exploreru, je k definování jednotlivých konkrétních služeb business/BFF API brána potřeba pouze jeden soubor configuration.json, protože čtyři API brány jsou založené na stejném obrazu Dockeru.

Snímek obrazovky zobrazující všechny brány rozhraní API se soubory configuration.json

Obrázek 6–34 Jediný soubor potřebný k definování každé brány rozhraní API / BFF s Ocelot je konfigurační soubor.

Rozdělením brány rozhraní API na několik bran rozhraní API mohou různé vývojové týmy, zaměřené na různé podmnožiny mikroslužeb, spravovat své vlastní brány rozhraní API pomocí nezávislých konfiguračních souborů Ocelot. Navíc ve stejnou dobu můžou znovu použít stejnou image Ocelot Dockeru.

Pokud nyní spustíte eShopOnContainers s bránami rozhraní API, které jsou ve výchozím nastavení součástí VS při otevření řešení eShopOnContainers-ServicesAndWebApps.sln, nebo při spuštění příkazu "docker-compose up", budou provedeny následující ukázkové směrování.

Například při návštěvě upstreamové adresy URL http://host.docker.internal:5202/api/v1/c/catalog/items/2/ obsluhované bránou rozhraní API webshoppingapigw získáte stejný výsledek z interní podřízené adresy URL http://catalog-api/api/v1/2 v rámci hostitele Dockeru, jako v následujícím prohlížeči.

Snímek obrazovky prohlížeče zobrazující odpověď procházející bránou rozhraní API

Obrázek 6–35 Přístup k mikroslužbě prostřednictvím adresy URL poskytované bránou rozhraní API

Kvůli důvodům testování nebo ladění, pokud chcete získat přímý přístup ke kontejneru Catalog Docker (pouze ve vývojovém prostředí) bez průchodu bránou API, protože catalog-api je interní DNS zpracování na hostiteli Dockeru (pověřené služební zjišťování, které je zpracované názvy služeb docker-compose), jediným způsobem, jak přímo přistupovat ke kontejneru, je prostřednictvím externího portu publikovaného v docker-compose.override.yml, který je určen pouze pro testy ve vývoji, například http://host.docker.internal:5101/api/v1/Catalog/items/1 v následujícím webovém prohlížeči.

Snímek obrazovky prohlížeče zobrazující přímou odpověď na Catalog.api

Obrázek 6–36 Přímý přístup k mikroslužbě pro účely testování

Aplikace je ale nakonfigurovaná tak, aby přistupovala ke všem mikroslužbám prostřednictvím bran rozhraní API, ne prostřednictvím přímých "zkratek".

Model agregace brány v eShopOnContainers

Jak bylo uvedeno dříve, flexibilní způsob implementace agregace požadavků je pomocí vlastních služeb prostřednictvím kódu. Vybraný způsob implementace agregace v eShopOnContainers je použití explicitní služby ASP.NET Core Web API systému pro každý agregátor.

Podle toho je diagram složení služby API Gateway ve skutečnosti trochu rozšířen při zvažování služeb agregátoru, které se nezobrazují v diagramu zjednodušené globální architektury zobrazené dříve.

V následujícím diagramu můžete také vidět, jak agregační služby fungují se souvisejícími bránami rozhraní API.

Diagram architektury eShopOnContainers zobrazující služby agregátoru

Obrázek 6–37 Architektura eShopOnContainers se službami agregátoru

Při bližším pohledu na oblast Nakupování na následujícím obrázku můžete vidět, že při používání agregátorových služeb v branách API se sníží nadměrná komunikace mezi klientskými aplikacemi a mikroslužbami.

Diagram znázorňující přiblížení architektury eShopOnContainers

Obrázek 6–38 Přiblížení obrazu služeb Agregátoru

Můžete si všimnout, že když diagram ukazuje možné požadavky přicházející z bran rozhraní API, může to být složité. Na druhou stranu, když použijete vzor agregátoru, můžete vidět, jak šipky modře zjednodušují komunikaci z pohledu klientské aplikace. Tento model nejen pomáhá snížit chattnost a latenci komunikace, ale také výrazně zlepšuje uživatelské prostředí pro vzdálené aplikace (mobilní aplikace a aplikace SPA).

V případě obchodní oblasti marketingu a mikroslužeb je to jednoduchý případ použití, takže nebylo nutné používat agregátory, ale v případě potřeby by to mohlo být také možné.

Ověřování a autorizace ve službě Ocelot API Gateway

Ve službě Ocelot API Gateway můžete umístit ověřovací službu, jako je ASP.NET Core Web API služba používající IdentityServer, který poskytuje autentizační token, a to buď mimo nebo uvnitř API Gateway.

Vzhledem k tomu, že eShopOnContainers používá více API bran s hranicemi založenými na BFF a obchodních oblastech, je autentizační služba vynechána z API bran, jak je zvýrazněno žlutě v následujícím diagramu.

Diagram znázorňující mikroslužbu identity pod bránou rozhraní API

Obrázek 6–39 Pozice služby Identity v eShopOnContainers

Ocelot však také podporuje umístění mikroslužby Identity/Auth v rámci hranice brány API, stejně jako v tomto dalším diagramu.

Diagram znázorňující ověřování ve službě Ocelot API Gateway

Obrázek 6–40 Ověřování v Ocelot

Jak ukazuje předchozí diagram, když je mikroslužba identity pod bránou rozhraní API (AG): 1) AG vyžaduje autentizační token z mikroslužby identity, 2) Mikroslužba identity vrací token do AG, 3–4) AG žádá o služby z mikroslužeb pomocí autentizačního tokenu. Vzhledem k tomu, že aplikace eShopOnContainers rozdělila bránu rozhraní API na více bran BFF (back-end pro front-end) a brány rozhraní API obchodních oblastí, bylo by další možností vytvořit další bránu rozhraní API pro průřezové otázky. Tato volba by byla spravedlivá v složitější architektuře založené na mikroslužbách s několika různými aspekty mikroslužeb. Vzhledem k tomu, že eShopOnContainers má pouze jednu průřezovou záležitost, bylo pro jednoduchost rozhodnuto řešit službu zabezpečení mimo oblast API brány.

V každém případě pokud je aplikace zabezpečená na úrovni brány rozhraní API, při pokusu o použití jakékoli zabezpečené mikroslužby se nejprve navštíví ověřovací modul služby Ocelot API Gateway. Tím se přesměruje požadavek HTTP k mikroslužbě identita nebo ověřování, abyste získali přístupový token a mohli navštívit chráněné služby s přístupovým tokenem.

Způsob, jak zabezpečit jakoukoli službu na úrovni API Gateway pomocí ověřování, je nastavením AuthenticationProviderKey v příslušných nastaveních na configuration.json.

    {
      "DownstreamPathTemplate": "/api/{version}/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "basket-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/api/{version}/b/{everything}",
      "UpstreamHttpMethod": [],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "IdentityApiKey",
        "AllowedScopes": []
      }
    }

Při spuštění Ocelot se podívá na ReRoutes AuthenticationOptions.AuthenticationProviderKey a zkontroluje, jestli je u daného klíče zaregistrovaný zprostředkovatel ověřování. Pokud tam není, Ocelot se nespustí. Pokud existuje, použije ReRoute při spuštění daného poskytovatele.

Vzhledem k tomu, že Ocelot WebHost je nakonfigurován s authenticationProviderKey = "IdentityApiKey", který bude vždy vyžadovat ověření, když tato služba má jakékoliv požadavky bez ověřovacího tokenu.

namespace OcelotApiGw
{
    public class Startup
    {
        private readonly IConfiguration _cfg;

        public Startup(IConfiguration configuration) => _cfg = configuration;

        public void ConfigureServices(IServiceCollection services)
        {
            var identityUrl = _cfg.GetValue<string>("IdentityUrl");
            var authenticationProviderKey = "IdentityApiKey";
                         //…
            services.AddAuthentication()
                .AddJwtBearer(authenticationProviderKey, x =>
                {
                    x.Authority = identityUrl;
                    x.RequireHttpsMetadata = false;
                    x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" }
                    };
                });
            //...
        }
    }
}

Pak musíte také nastavit autorizaci pomocí atributu [Authorize] u jakéhokoli prostředku, ke kterým se má přistupovat, jako jsou mikroslužby, například v následujícím kontroleru mikroslužeb košíku.

namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
{
    [Route("api/v1/[controller]")]
    [Authorize]
    public class BasketController : Controller
    {
      //...
    }
}

ValidAudiences, jako například "basket", jsou korelovány s publikem definovaným v každé mikroslužbě pomocí funkce ConfigureServices() ve třídě Startup, jak je uvedeno v kódu níže.

// prevent from mapping "sub" claim to nameidentifier.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

var identityUrl = Configuration.GetValue<string>("IdentityUrl");

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

}).AddJwtBearer(options =>
{
    options.Authority = identityUrl;
    options.RequireHttpsMetadata = false;
    options.Audience = "basket";
});

Pokud se pokusíte získat přístup k libovolné zabezpečené mikroslužbě, například k mikroslužbě Basket, která používá URL typu ReRoute založenou na API Gateway, http://host.docker.internal:5202/api/v1/b/basket/1, obdržíte chybu 401 Neautorizováno, pokud nezadáte platný token. Na druhé straně, pokud je adresa URL ReRoute ověřena, Ocelot vyvolá jakékoli podřízené schéma, které je k němu přidružené (interní adresa URL mikroslužby).

Autorizace na úrovni Ocelot's ReRoutes. Ocelot podporuje autorizaci na základě deklarací identity vyhodnocenou po ověření. Autorizaci nastavíte na úrovni trasy přidáním následujících řádků do konfigurace ReRoute.

"RouteClaimsRequirement": {
    "UserType": "employee"
}

V tomto příkladu Ocelot při zavolání autorizačního middlewaru zjistí, jestli má uživatel v tokenu typ nároku 'UserType' a zda je hodnota tohoto nároku 'employee'. Pokud tomu tak není, uživatel nebude oprávněn a odpověď bude 403 Zakázáno.

Použití Kubernetes Ingress a Ocelot API brány

Při použití Kubernetes (například v clusteru Azure Kubernetes Service) obvykle sjednocujete všechny požadavky HTTP prostřednictvím vrstvy příchozího přenosu dat Kubernetes na základě Nginx.

Pokud v Kubernetes nepoužíváte žádný přístup k příchozímu přenosu dat, pak vaše služby a pody mají IP adresy směrovatelné pouze sítí clusteru.

Pokud ale používáte přístupovou metodu, budete mít střední vrstvu mezi internetem a vašimi službami (včetně API bran), která funguje jako reverzní proxy.

Definice Ingressu je soubor pravidel, která umožňují příchozím připojením dosáhnout služeb clusteru. Ingress je nakonfigurován tak, aby poskytoval externě dostupné URL adresy služeb, vyvažoval zátěž provozu, zajišťoval ukončení SSL a poskytoval další funkce. Uživatelé požadují Ingress odesláním prostředku Ingress na server rozhraní API.

V eShopOnContainers při vývoji místně a použití pouze vašeho vývojového počítače jako hostitele Dockeru nepoužíváte žádné příchozí přenosy dat, ale pouze několik bran rozhraní API.

Při cílení na "produkční" prostředí založené na Kubernetes používá eShopOnContainers jako vrstvu před API bránami ingress. Klienti tak stále volají stejnou základní adresu URL, ale požadavky se směrují na více bran rozhraní API nebo BFF.

Brány rozhraní API jsou front-endy nebo fasády, které zobrazují pouze služby, ale ne webové aplikace, které jsou obvykle mimo jejich rozsah. Kromě toho můžou brány rozhraní API skrýt určité interní mikroslužby.

Ingress však pouze přesměrovává požadavky HTTP a nesnaží se skrýt žádnou mikroslužbu ani webovou aplikaci.

Mít vrstvu Nginx pro příchozí přenos dat v Kubernetes před webovými aplikacemi a několika Ocelot API bránami / BFF je ideální architektura, jak je znázorněno v následujícím diagramu.

Diagram znázorňující, jak vrstva příchozího přenosu dat zapadá do prostředí AKS

Obrázek 6–41 Úroveň příchozího přenosu dat v eShopOnContainers při nasazení do Kubernetes

Kubernetes Ingress funguje jako reverzní proxy server pro veškerý provoz k aplikaci, včetně webových aplikací, které nespadají do rozsahu API brány. Když do Kubernetes nasadíte eShopOnContainers, zveřejní pouze několik služeb nebo koncových bodů prostřednictvím ingress služby, v podstatě jde o následující postfixy adres URL:

  • / pro klientskou webovou aplikaci SPA
  • /webmvc pro klientskou webovou aplikaci MVC
  • /webstatus pro webovou aplikaci klientu zobrazující stav/zdravotní kontroly
  • /webshoppingapigw pro webové BFF a obchodní procesy nakupování
  • /webmarketingapigw pro obchodní procesy BFF a marketing na webu
  • /mobileshoppingapigw pro mobilní obchodní procesy BFF a nakupování
  • /mobilemarketingapigw pro mobilní obchodní procesy BFF a marketing

Při nasazování do Kubernetes každá brána rozhraní API Ocelot používá pro každý pod , na kterém běží brány rozhraní API, jiný souborconfiguration.json. Tyto souboryconfiguration.jsonjsou poskytovány připojením svazku nastaveným na základě konfigurační mapy Kubernetes s názvem 'ocelot', s využitím původně skriptu deploy.ps1. Každý kontejner připojí svůj související konfigurační soubor do složky kontejneru s názvem /app/configuration.

Ve zdrojových souborech eShopOnContainers najdete původní soubory "configuration.json" ve k8s/ocelot/ složce. Každý BFF/APIGateway má jeden soubor.

Další průřezové funkce ve službě Ocelot API Gateway

Při použití služby Ocelot API Gateway jsou k dispozici další důležité funkce, které jsou popsány na následujících odkazech.