Implementace bran rozhraní API s Ocelotem

Tip

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.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

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 zvolili kvůli integrované podpoře protokolu WebSocket, kterou nová komunikace mezi službami gRPC implementovala 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.

Návrh bran rozhraní API a jejich návrh

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

Diagram showing the eShopOnContainers architecture.

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 ale bylo podobné, ale jakýkoli kontejner v diagramu by se v orchestrátoru mohl škálovat na více instancí.

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í vlastního produktu brány rozhraní API obvykle dobrým přístupem, ale ne jako jediný monolitický agregátor nebo jedinečná centrální vlastní brána rozhraní API, pokud tato služba API Gateway umožňuje více nezávislých oblastí konfigurace pro několik vývojových týmů vytvářejících 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.

Screenshot of the Services folder showing its subfolders.

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

Informace o službě Identity v návrhu, který vynechává směrování brány rozhraní API, protože se jedná o jediný průřezový problém v systému, i když s Ocelotem je také možné ho zahrnout jako součást přesměrování seznamů.

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.

Screenshot of Solution Explorer showing Catalog.API project contents.

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 skončí s tímto druhem kódu jazyka C#, který přistupuje k databázi mikroslužeb, a všechny další požadované akce.

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 existuje) publikovaným při nasazování pomocí docker-composenástroje .

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 docker-compose.override.yml konfigurace interního portu kontejneru katalogu je port 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:

Screenshot of Swagger UI showing the Catalog.API REST 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ých zprostředkování služby 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 s balíčkem 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:

Screenshot of Solution Explorer showing Ocelot API gateway project.

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čí vytvořit a nakonfigurovat typickou 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 zadáte všechny reroute brány rozhraní API, což znamená externí koncové body s konkrétními porty a korelovanými interními koncovými body, obvykle používají různé 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 z výše uvedeného, 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žití kontejnerů port zadaný v souboru dockerfile.

Jedná se Host o název služby, který závisí na překladu 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 tomto okamžiku můžete mít jednu bránu rozhraní API Ocelot (ASP.NET Core WebHost) pomocí jednoho nebo několika 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é image kontejneru Dockeru ke spuštění více různých typů kontejnerů API / 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 pro každou službu poskytneme jiný soubor configuration.json pomocí svazku Dockeru pro přístup k jiné složce PC pro každou službu.

Diagram of a single Ocelot gateway Docker image for all API gateways.

Obrázek 6–33 Opětovné použití jedné image Ocelot Dockeru napříč několika typy brány rozhraní API

V eShopOnContainers se vytvoří "Generic Ocelot API Gateway Docker Image" s projektem s názvem OcelotApiGw a názvem image "eshop/ocelotapigw", který je zadán v souboru docker-compose.yml. Při nasazování do Dockeru se pak vytvoří č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

Vzhledem k tomu, že předchozí kód a jak je znázorněno v níže uvedeném Průzkumníku sady Visual Studio, je jediným souborem potřebným k definování jednotlivých konkrétních služeb business/BFF API Gateway jen configuration.json soubor, protože čtyři brány rozhraní API jsou založené na stejné imagi Dockeru.

Screenshot showing all API gateways with configuration.json files.

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 do několika bran ROZHRANÍ API můžou různé vývojové týmy zaměřené na různé podmnožina mikroslužeb spravovat 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 teď spustíte eShopOnContainers s branami rozhraní API (ve výchozím nastavení je součástí VS při otevírání eShopOnContainers-ServicesAndWebApps.sln řešení nebo pokud spustíte příkaz docker-compose up), provede se následující ukázkové trasy.

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.

Screenshot of a browser showing a response going through API gateway.

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

Kvůli testování nebo ladění důvodů, pokud chcete přímý přístup ke kontejneru Dockeru katalogu (pouze ve vývojovém prostředí) bez průchodu bránou rozhraní API, protože catalog-api je interní překlad DNS pro hostitele Dockeru (zjišťování služby zpracovávané 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 k dispozici pouze pro vývojové testy, například http://host.docker.internal:5101/api/v1/Catalog/items/1 v následujícím prohlížeči.

Screenshot of a browser showing a direct response to the 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 jsme představili dříve, flexibilní způsob implementace agregace požadavků je s vlastními službami podle kódu. Můžete také implementovat agregaci požadavků s funkcí Agregace požadavků v Ocelot, ale nemusí být tak flexibilní, jak potřebujete. Proto je vybraný způsob implementace agregace v eShopOnContainers s explicitním ASP.NET službou webového rozhraní API core pro každý agregátor.

Podle takového přístupu je diagram složení brány rozhraní API v realitě 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 of eShopOnContainers architecture showing aggregator services.

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

Při dalším přiblížení v oblasti obchodní oblasti Nakupování na následujícím obrázku vidíte, že při používání služeb agregátoru v branách rozhraní API se zmenší chatování mezi klientskými aplikacemi a mikroslužbami.

Diagram showing eShopOnContainers architecture zoom in.

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

Můžete si všimnout, jak diagram znázorňuje možné požadavky přicházející z bran rozhraní API, které může 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 sednout ověřovací službu, jako je služba webového rozhraní API ASP.NET Core, pomocí IdentityServeru poskytujícího ověřovací token, a to buď ven, nebo uvnitř brány rozhraní API.

Vzhledem k tomu, že eShopOnContainers používá více bran ROZHRANÍ API s hranicemi založenými na BFF a obchodních oblastech, služba Identity/Auth se vynechá z bran rozhraní API, jak je zvýrazněné žlutě v následujícím diagramu.

Diagram showing Identity microservice beneath the API gateway.

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

Ocelot ale podporuje také mikroslužbu Identity/Auth v rámci hranice brány rozhraní API, stejně jako v tomto dalším diagramu.

Diagram showing authentication in an 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) Skupina dostupnosti vyžaduje ověřovací token z mikroslužby identity, 2) Mikroslužba identity vrací token do skupiny dostupnosti, 3–4) Žádosti skupiny dostupnosti z mikroslužeb pomocí ověřovací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á v eShopOnContainers jen jeden křížový problém, rozhodl se kvůli jednoduchosti zpracovat službu zabezpečení z sféry služby API Gateway.

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 na návštěvu mikroslužby Identita nebo ověřování, abyste získali přístupový token, abyste mohli navštívit chráněné služby s access_token.

Způsob zabezpečení pomocí ověřování jakékoli služby na úrovni brány rozhraní API je nastavením AuthenticationProviderKey v jeho související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 vyžadovat ověřování vždy, když tato služba má jakékoli 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
    {
      //...
    }
}

ValidAudience, jako je například "basket", korelují s cílovou skupinou definovanou v každé mikroslužbě s AddJwtBearer() konfiguracíServices() třídy Startup, například 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 jakékoli zabezpečené mikroslužbě, jako je mikroslužba Basket s adresou URL ReRoute založenou na bráně rozhraní API, http://host.docker.internal:5202/api/v1/b/basket/1získáte 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 se při zavolání autorizačního middlewaru Ocelot zjistí, jestli má uživatel v tokenu typ deklarace Identity UserType a pokud je hodnota této deklarace "employee". Pokud tomu tak není, uživatel nebude autorizovaný a odpověď bude 403 zakázáno.

Použití příchozího přenosu dat Kubernetes a bran rozhraní API Ocelot

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řístup příchozího přenosu dat, budete mít střední úroveň mezi internetem a vašimi službami (včetně bran rozhraní API), která funguje jako reverzní proxy server.

Jako definici je příchozí přenos dat kolekce pravidel, která umožňují příchozím připojením spojit se se službami clusteru. Příchozí přenos dat je nakonfigurovaný tak, aby poskytoval externě dostupné adresy URL služeb, vyrovnává zatížení provozu, ukončení protokolu SSL a další. Uživatelé požadují příchozí přenos dat tak, že poSTing prostředek příchozího přenosu dat 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 ale eShopOnContainers před bránami rozhraní API používá příchozí přenos dat. 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.

Příchozí přenos dat ale jenom přesměrovává požadavky HTTP, ale nepokouší se skrýt žádnou mikroslužbu nebo webovou aplikaci.

S úrovní Nginx příchozího přenosu dat v Kubernetes před webovými aplikacemi a několika bran rozhraní API Ocelot / BFF je ideální architektura, jak je znázorněno v následujícím diagramu.

A diagram showing how an ingress tier fits into the AKS environment.

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

Příchozí přenos dat Kubernetes funguje jako reverzní proxy server pro veškerý provoz do aplikace, včetně webových aplikací, které jsou mimo rozsah brány api. Když do Kubernetes nasadíte eShopOnContainers, zveřejní pouze několik služeb nebo koncových bodů prostřednictvím příchozího přenosu dat, v podstatě následující seznam oprav adres URL:

  • / pro klientskou webovou aplikaci SPA
  • /webmvc pro klientskou webovou aplikaci MVC
  • /webstatus pro klientskou webovou aplikaci zobrazující stav nebo kontrolu stavu
  • /webshoppingapigw pro webové obchodní procesy BFF a nakupování
  • /webmarketingapigw pro webové obchodní procesy BFF a marketing
  • /mobileshoppingapigw pro mobilní obchodní procesy BFF a nakupování
  • /mobilemarketingapigw pro mobilní obchodní procesy BFF a marketing

Při nasazování do Kubernetes používá každá brána rozhraní API Ocelot jiný soubor configuration.json pro každý pod , na kterém běží brány rozhraní API. Tyto soubory "configuration.json" jsou poskytovány připojením svazku vytvořeného pomocí skriptu deploy.ps1 vytvořeného na mapě konfigurace Kubernetes s názvem ocelot. Každý kontejner připojí svůj související konfigurační soubor do složky kontejneru s názvem /app/configuration.

V souborech zdrojového kódu 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.