API-átjárók implementálása az Ocelottal
Tipp.
Ez a tartalom egy részlet a .NET-alkalmazásokhoz készült .NET-alkalmazásokhoz készült eBook, .NET Microservices Architecture című eBookból, amely elérhető a .NET Docs-on vagy egy ingyenesen letölthető PDF-fájlként, amely offline módban is olvasható.
Fontos
Az eShopOnContainers referencia mikroszolgáltatási alkalmazás jelenleg az Envoy által biztosított funkciókat használja az API Gateway implementálásához a korábbi hivatkozott Ocelot helyett. Ezt a kialakítást azért választottuk, mert az Envoy beépített támogatása a WebSocket protokollhoz, amelyet az eShopOnContainersben implementált új gRPC szolgáltatásközi kommunikáció igényel. Ezt a szakaszt azonban megtartottuk az útmutatóban, így az Ocelot egyszerű, képes és egyszerűsített API Gatewayként tekinthető, amely éles környezetben használható. Emellett a legújabb Ocelot-verzió kompatibilitástörő változást is tartalmaz a json-sémáján. Fontolja meg az Ocelot < 16.0.0-s verziójának használatát, vagy használja a kulcsútvonalakat a ReRoutes helyett.
API-átjárók tervezése és tervezése
Az alábbi architektúradiagram bemutatja, hogyan implementálták az API Gatewayeket az Ocelottal az eShopOnContainersben.
6-28. ábra. eShopOnContainers architektúra API-átjárókkal
Ez a diagram bemutatja, hogy az egész alkalmazás hogyan van üzembe helyezve egyetlen Docker-gazdagépen vagy fejlesztői PC-ben a "Docker for Windows" vagy a "Docker for Mac" használatával. A vezénylőbe való üzembe helyezés azonban hasonló lenne, de a diagram bármely tárolója felskálázható a vezénylőben.
Emellett az infrastruktúra-eszközöket, például az adatbázisokat, a gyorsítótárat és az üzenetközvetítőket ki kell tölteni a vezénylőből, és magas rendelkezésre állású infrastruktúra-rendszerekbe kell üzembe helyezni, például az Azure SQL Database-ben, az Azure Cosmos DB-ben, az Azure Redisben, az Azure Service Busban vagy bármely helyszíni HA-fürtözési megoldásban.
Ahogy azt a diagramon is láthatja, a több API Gateway használatával több fejlesztői csapat is önálló lehet (ebben az esetben marketingfunkciók és vásárlási funkciók) a mikroszolgáltatásaik és saját kapcsolódó API-átjárók fejlesztésekor és üzembe helyezésekor.
Ha egyetlen monolitikus API-átjáróval rendelkezik, amely egyetlen pontot jelentene, amelyet több fejlesztői csapat is frissítene, ami az összes mikroszolgáltatást összekapcsolhatja az alkalmazás egyetlen részével.
A kialakításban sokkal tovább haladva néha egy finom szemcsés API Gateway a választott architektúrától függően egyetlen üzleti mikroszolgáltatásra is korlátozható. Ha az API Gateway határait az üzlet vagy a tartomány szabja meg, az segít a jobb tervezésben.
Az API Gateway-szint finom részletessége például különösen hasznos lehet a mikroszolgáltatásokon alapuló összetettebb felhasználói felületi alkalmazások esetében, mivel a részletes API Gateway fogalma hasonló a felhasználói felületi összetételű szolgáltatáshoz.
Az előző szakaszban részletesebben is bemutatjuk, hogyan hozhat létre összetett felhasználói felületet mikroszolgáltatások alapján.
Kulcsfontosságú szempont, hogy sok közepes és nagy méretű alkalmazás esetében az egyénileg létrehozott API Gateway-termék használata általában jó módszer, de nem egyetlen monolitikus aggregátorként vagy egyedi központi egyéni API Gatewayként, kivéve, ha az API Gateway több független konfigurációs területet tesz lehetővé a több fejlesztési csapat számára, amelyek autonóm mikroszolgáltatásokat hoznak létre.
Minta mikroszolgáltatások/tárolók az API-átjárókon keresztüli átirányításhoz
Az eShopOnContainers például körülbelül hat belső mikroszolgáltatás-típussal rendelkezik, amelyeket közzé kell tenni az API-átjárókon keresztül, ahogy az alábbi képen is látható.
6–29. ábra. Mikroszolgáltatási mappák az eShopOnContainers megoldásban a Visual Studióban
Az Identity Service-t illetően a tervezés során kimaradt az API Gateway útválasztásából, mivel ez az egyetlen keresztirányú probléma a rendszerben, bár az Ocelottal az átirányítási listák részeként is felvehető.
Ezek a szolgáltatások jelenleg ASP.NET Core Webes API-szolgáltatásokként vannak implementálva, ahogy a kódból is látható. Koncentráljunk az egyik mikroszolgáltatásra, például a katalógus mikroszolgáltatási kódjára.
6–30. ábra. Minta webes API-mikroszolgáltatás (katalógus mikroszolgáltatás)
Láthatja, hogy a Katalógus mikroszolgáltatás egy tipikus ASP.NET Core Web API-projekt, amely számos vezérlővel és metódussal rendelkezik, például az alábbi kódban.
[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();
}
A HTTP-kérés a mikroszolgáltatás-adatbázishoz hozzáférő C#-kódot és minden további szükséges műveletet futtat.
Ami a mikroszolgáltatás URL-címét illeti, amikor a tárolók a helyi fejlesztőszámítógépen (helyi Docker-gazdagépen) vannak üzembe helyezve, minden mikroszolgáltatás tárolója mindig rendelkezik egy belső porttal (általában a 80-as porttal) a dockerfile-ban, ahogyan az alábbi dockerfile esetében is:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
A kódban látható 80-os port belső a Docker-gazdagépen belül, így az ügyfélalkalmazások nem tudják elérni.
Az ügyfélalkalmazások csak a telepítéskor közzétett külső portokat érhetik el (ha vannak ilyenek).docker-compose
Ezeket a külső portokat nem szabad közzétenni éles környezetben való üzembe helyezéskor. Ezért érdemes az API Gatewayt használni, hogy elkerülje az ügyfélalkalmazások és a mikroszolgáltatások közötti közvetlen kommunikációt.
A fejlesztés során azonban közvetlenül szeretné elérni a mikroszolgáltatást/tárolót, és a Swaggeren keresztül futtatni. Ezért az eShopOnContainersben a külső portok akkor is meg vannak adva, ha az API Gateway vagy az ügyfélalkalmazások nem fogják használni őket.
Íme egy példa a docker-compose.override.yml
katalógus mikroszolgáltatás fájljára:
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).
Láthatja, hogy a docker-compose.override.yml konfigurációban a katalógustároló belső portja a 80-as port, a külső hozzáférés portja azonban 5101. Ezt a portot azonban az alkalmazás nem használhatja API Gateway használatakor, csak a katalógus mikroszolgáltatásának hibakeresésére, futtatására és tesztelésére.
Általában nem docker-compose használatával fog üzembe helyezni egy éles környezetben, mert a mikroszolgáltatásokhoz megfelelő üzemi üzembehelyezési környezet egy olyan vezénylő, mint a Kubernetes vagy a Service Fabric. Ezeken a környezeteken való üzembe helyezéskor különböző konfigurációs fájlokat használ, amelyekben nem fog közvetlenül közzétenni külső portot a mikroszolgáltatásokhoz, de mindig az API Gateway fordított proxyját fogja használni.
Futtassa a katalógus mikroszolgáltatását a helyi Docker-gazdagépen. Futtassa a Teljes eShopOnContainers-megoldást a Visual Studióból (a docker-compose fájlok összes szolgáltatását futtatja), vagy indítsa el a Katalógus mikroszolgáltatást a következő docker-compose paranccsal a CMD-ben vagy a PowerShellben a mappában, ahol a docker-compose.yml
rendszer elhelyezi azokat docker-compose.override.yml
.
docker-compose run --service-ports catalog-api
Ez a parancs csak a catalog-api szolgáltatástárolót és a docker-compose.yml megadott függőségeket futtatja. Ebben az esetben az SQL Server-tároló és a RabbitMQ-tároló.
Ezután közvetlenül elérheti a katalógus mikroszolgáltatást, és megtekintheti annak metódusait a Swagger felhasználói felületén keresztül, amely közvetlenül ezen a "külső" porton keresztül érhető el, ebben az esetben http://host.docker.internal:5101/swagger
:
6–31. ábra. A katalógus mikroszolgáltatásának tesztelése a Swagger felhasználói felületével
Ezen a ponton beállíthat egy töréspontot c#-kódban a Visual Studióban, tesztelheti a mikroszolgáltatást a Swagger felhasználói felületén közzétett metódusokkal, és végül mindent megtisztíthat a docker-compose down
paranccsal.
A mikroszolgáltatással– ebben az esetben az 5101 külső porton keresztül – folytatott közvetlen hozzáférésű kommunikáció azonban pontosan ezt szeretné elkerülni az alkalmazásban. Ezt elkerülheti az API Gateway (Ocelot, ebben az esetben) további közvetettségi szintjének beállításával. Így az ügyfélalkalmazás nem fog közvetlenül hozzáférni a mikroszolgáltatáshoz.
API-átjárók implementálása az Ocelottal
Az Ocelot alapvetően egy olyan köztes szoftverkészlet, amelyet egy adott sorrendben alkalmazhat.
Az Ocelot csak ASP.NET Core használatára lett tervezve. A csomag legújabb verziója a 18.0, amely a .NET 6-ot célozza, ezért nem alkalmas .NET-keretrendszer alkalmazásokhoz.
Az Ocelotot és annak függőségeit az ASP.NET Core-projektben az Ocelot NuGet-csomagjával telepítheti a Visual Studióból.
Install-Package Ocelot
Az eShopOnContainers api Gateway-implementációja egy egyszerű ASP.NET Core WebHost-projekt, és az Ocelot köztes szoftvere kezeli az API Gateway összes funkcióját, ahogyan az alábbi képen látható:
6–32. ábra. Az OcelotApiGw alapprojekt az eShopOnContainersben
Ez a ASP.NET Core WebHost-projekt két egyszerű fájlból áll: Program.cs
és Startup.cs
.
A Program.cs csak létre kell hoznia és konfigurálnia kell a tipikus ASP.NET Core BuildWebHostot.
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;
}
}
}
Az Ocelot fontos pontja az a configuration.json
fájl, amelyet a metóduson keresztül kell megadnia a AddJsonFile()
szerkesztőnek. Itt configuration.json
adhatja meg az ÖSSZES API Gateway ReRoutes-t, vagyis az adott portokkal rendelkező külső végpontokat és a korrelált belső végpontokat, amelyek általában különböző portokat használnak.
{
"ReRoutes": [],
"GlobalConfiguration": {}
}
A konfigurációnak két szakasza van. A ReRoutes és a GlobalConfiguration tömbje. A ReRoutes azok az objektumok, amelyek közlik az Ocelot-nak, hogyan kell kezelni egy felsőbb rétegbeli kérést. A globális konfiguráció lehetővé teszi a ReRoute-beállítások felülbírálását. Ez akkor hasznos, ha nem szeretne sok ReRoute-beállítást kezelni.
Íme egy egyszerűsített példa az eShopOnContainers egyik API-átjárójának ReRoute-konfigurációs fájljára .
{
"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"
}
}
Az Ocelot API Gateway fő funkciója a bejövő HTTP-kérések fogadása és továbbítása egy alárendelt szolgáltatásba, amely jelenleg egy másik HTTP-kérés. Az Ocelot az egyik kérés átirányítását egy másikhoz reRoute-ként írja le.
Összpontosítsunk például a fenti configuration.json egyik ReRoutes-re, a Basket mikroszolgáltatás konfigurációjára.
{
"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": []
}
}
A DownstreamPathTemplate, a Séma és a DownstreamHostAndPorts létrehozza azt a belső mikroszolgáltatás-URL-címet, amelybe a kérés továbbítva lesz.
A port a szolgáltatás által használt belső port. Tárolók használata esetén a port a dockerfile-ján van megadva.
Ez Host
egy szolgáltatásnév, amely a használt szolgáltatásnév felbontásától függ. Docker-compose használata esetén a szolgáltatások nevét a Docker-gazdagép adja meg, amely a docker-compose fájlokban megadott szolgáltatásneveket használja. Ha olyan vezénylőt használ, mint a Kubernetes vagy a Service Fabric, ezt a nevet az egyes vezénylők által megadott DNS- vagy névfeloldással kell feloldani.
A DownstreamHostAndPorts egy tömb, amely tartalmazza a kéréseket továbbítani kívánt alsóbb rétegbeli szolgáltatások gazdagépét és portját. Ez a konfiguráció általában csak egy bejegyzést tartalmaz, de előfordulhat, hogy terheléselosztási kéréseket szeretne használni az alsóbb rétegbeli szolgáltatásokhoz, és az Ocelot lehetővé teszi, hogy több bejegyzést adjon hozzá, majd válasszon ki egy terheléselosztót. De ha az Azure-t és bármely vezénylőt használ, akkor valószínűleg jobb ötlet a terheléselosztás a felhővel és a vezénylő infrastruktúrával.
Az UpstreamPathTemplate az az URL-cím, amellyel az Ocelot azonosítja, hogy melyik DownstreamPathTemplate-ot használja az ügyfél egy adott kéréséhez. Végül a UpstreamHttpMethodot használja, hogy az Ocelot különbséget tegyen a különböző kérések (GET, POST, PUT) között ugyanazon AZ URL-címen.
Ezen a ponton egyetlen Ocelot API Gateway (ASP.NET Core WebHost) lehet egy vagy több egyesített configuration.json fájl használatával, vagy a konfigurációt egy consul KV-tárolóban is tárolhatja.
Az architektúra és a tervezés szakaszaiban bemutatottak szerint azonban, ha valóban autonóm mikroszolgáltatásokat szeretne használni, jobb lehet, ha ezt az egyetlen monolitikus API Gatewayt több API Gatewayre és/vagy BFF-re (a Frontend háttérrendszerére) osztja fel. Ebből a célból nézzük meg, hogyan valósítható meg ez a megközelítés a Docker-tárolókkal.
Egyetlen Docker-tárolórendszerkép használata több különböző API Gateway/BFF-tárolótípus futtatásához
Az eShopOnContainersben egyetlen Docker-tárolórendszerképet használunk az Ocelot API Gateway használatával, de futtatáskor különböző szolgáltatásokat/tárolókat hozunk létre az API-Gateway/BFF egyes típusaihoz egy másik configuration.json fájl megadásával, egy Docker-kötet használatával, hogy az egyes szolgáltatásokhoz egy másik PC-mappát érhessen el.
6–33. ábra. Egyetlen Ocelot Docker-rendszerkép újrafelhasználása több API Gateway-típusban
Az eShopOnContainersben az "Általános Ocelot API Gateway Docker Image" az "OcelotApiGw" nevű projekttel és a docker-compose.yml fájlban megadott "eshop/ocelotapigw" képnévvel jön létre. Ezután a Dockerben való üzembe helyezéskor négy API-Gateway-tároló jön létre ugyanabból a Docker-rendszerképből, ahogyan az a docker-compose.yml fájl alábbi kivonatában látható.
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
Ezenkívül, amint az alábbi docker-compose.override.yml fájlban látható, az API Gateway-tárolók között az egyetlen különbség az Ocelot konfigurációs fájl, amely minden szolgáltatástároló esetében eltérő, és futásidőben van megadva egy Docker-köteten keresztül.
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
Az előző kód miatt, és ahogy az alábbi Visual Studio Explorerben is látható, az egyes üzleti/BFF API-átjárók definiálásához csak egy configuration.json fájl szükséges, mivel a négy API Gateway ugyanazon Docker-rendszerképen alapul.
6-34. ábra. Az egyes API Gateway/BFF Ocelottal való definiálásához csak egy konfigurációs fájl szükséges
Az API Gateway több API Gatewayre való felosztásával a mikroszolgáltatások különböző részhalmazaira összpontosító különböző fejlesztői csapatok önálló Ocelot-konfigurációs fájlok használatával kezelhetik saját API Gateway-jüket. Emellett ugyanazt az Ocelot Docker-lemezképet is újra felhasználhatják.
Most, ha az API-átjárókkal futtat eShopOnContainerst (a VS alapértelmezés szerint tartalmazza eShopOnContainers-ServicesAndWebApps.sln megoldás megnyitásakor vagy a "docker-compose up" futtatásakor), a következő mintaútvonalak lesznek végrehajtva.
Ha például a webshoppingapigw API Gateway által kiszolgált felső URL-címet http://host.docker.internal:5202/api/v1/c/catalog/items/2/
látogatja meg, ugyanazt az eredményt kapja a Docker-gazdagép belső alsóbb rétegbeli URL-címétől http://catalog-api/api/v1/2
, mint a következő böngészőben.
6–35. ábra. Mikroszolgáltatás elérése az API Gateway által megadott URL-címen keresztül
Tesztelési vagy hibakeresési okokból, ha a Katalógus Docker-tárolóhoz (csak a fejlesztői környezetben) szeretne közvetlenül hozzáférni anélkül, hogy áthalad az API Gatewayen, mivel a "catalog-api" a Docker-gazdagépen belüli DNS-feloldás (a docker-compose szolgáltatásnevek által kezelt szolgáltatásfelderítés), a tároló közvetlen elérésének egyetlen módja a docker-compose.override.yml közzétett külső porton keresztül történik, amely csak fejlesztési tesztekhez érhető el, például http://host.docker.internal:5101/api/v1/Catalog/items/1
a következő böngészőben.
6–36. ábra. Mikroszolgáltatásokhoz való közvetlen hozzáférés tesztelés céljából
Az alkalmazás azonban úgy van konfigurálva, hogy az api-átjárókon keresztül férhessen hozzá az összes mikroszolgáltatáshoz, nem pedig a közvetlen port "parancsikonjaival".
Az átjáró aggregációs mintája az eShopOnContainersben
A korábban bemutatottak szerint a kérések összesítésének rugalmas módja az egyéni szolgáltatások használata, kód alapján. A kérések összesítését az Ocelot Kérelem aggregáció funkciójával is implementálhatja, de lehet, hogy nem olyan rugalmas, mint amennyire szüksége van. Ezért az összesítés eShopOnContainersben való implementálásának kiválasztott módja egy explicit ASP.NET Core Web API-szolgáltatás minden egyes összesítőhöz.
Ennek a megközelítésnek megfelelően az API Gateway összeállítási diagramja a valóságban egy kicsit hosszabb, amikor figyelembe veszi azokat az összesítő szolgáltatásokat, amelyek nem jelennek meg a korábban bemutatott egyszerűsített globális architektúradiagramon.
Az alábbi ábrán azt is láthatja, hogyan működnek az összesítő szolgáltatások a kapcsolódó API-átjárókkal.
6–37. ábra. eShopOnContainers architektúra összesítő szolgáltatásokkal
Az alábbi képen látható "Vásárlás" üzleti területen további nagyítással láthatja, hogy az ügyfélalkalmazások és a mikroszolgáltatások közötti csevegés csökken az API-átjárók összesítő szolgáltatásainak használatakor.
6–38. ábra. Az Aggregator-szolgáltatások képének nagyítása
Megfigyelheti, hogy ha a diagram az API-átjárókból érkező lehetséges kéréseket jeleníti meg, az hogyan válik összetettké. Ha viszont az összesítő mintát használja, láthatja, hogy a kék nyilak hogyan egyszerűsítik az ügyfélalkalmazások szempontjából a kommunikációt. Ez a minta nem csak a csevegés és a késés csökkentésében segít a kommunikációban, hanem jelentősen javítja a felhasználói élményt a távoli alkalmazások (mobil- és SPA-alkalmazások) esetében is.
A "Marketing" üzleti terület és mikroszolgáltatások esetében ez egy egyszerű használati eset, így nem volt szükség aggregátorok használatára, de szükség esetén lehetséges is lehet.
Hitelesítés és engedélyezés az Ocelot API-átjárókban
Az Ocelot API-átjárókban a hitelesítési szolgáltatás( például egy ASP.NET Core Web API szolgáltatás) ülhet le az IdentityServer használatával, amely a hitelesítési jogkivonatot biztosítja, akár kívül, akár az API-átjárón belül.
Mivel az eShopOnContainers több, BFF és üzleti területek alapján határolt API-átjárót használ, az Identity/Auth szolgáltatás kimarad az API-átjárókból, amint az a következő ábrán sárga színnel van kiemelve.
6–39. ábra. Az identitásszolgáltatás pozíciója az eShopOnContainersben
Az Ocelot azonban támogatja az Identity/Auth mikroszolgáltatásnak az API-átjáró határain belüli ülését is, ahogyan a másik ábrán is látható.
6-40. ábra. Hitelesítés az Ocelotban
Ahogy az előző ábrán látható, amikor az Identitás mikroszolgáltatás az API-átjáró (AG) alatt található: 1) Az AG hitelesítési jogkivonatot kér az identitás mikroszolgáltatástól, 2) Az identitás mikroszolgáltatás jogkivonatot ad vissza az AG-nek, 3–4) AG-kéréseket a mikroszolgáltatásoktól az auth token használatával. Mivel az eShopOnContainers alkalmazás az API Gatewayt több BFF-re (előtérbeli háttérrendszerre) és üzleti területekre osztotta fel az API Gateway-eket, egy másik lehetőség egy további API Gateway létrehozása lett volna a horizontális problémák kezelésére. Ez a választás tisztességes lenne egy összetettebb mikroszolgáltatás-alapú architektúrában, több horizontális szempontú mikroszolgáltatással. Mivel az eShopOnContainersben csak egyetlen keresztirányú probléma van, úgy döntöttek, hogy az egyszerűség kedvéért csak az API Gateway területéről kezelik a biztonsági szolgáltatást.
Mindenesetre, ha az alkalmazás az API Gateway szintjén van védve, az Ocelot API Gateway hitelesítési modulja először meg lesz látogatva, amikor bármilyen biztonságos mikroszolgáltatást próbál használni. Ez átirányítja a HTTP-kérést, hogy látogasson el az identitás- vagy hitelesítési mikroszolgáltatáshoz a hozzáférési jogkivonat lekéréséhez, hogy megtekinthesse a védett szolgáltatásokat a access_token.
Az API Gateway szintjén bármely szolgáltatás hitelesítésével történő biztonságossá tételéhez az AuthenticationProviderKey beállításával kell beállítania a kapcsolódó beállításokat a configuration.json.
{
"DownstreamPathTemplate": "/api/{version}/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "basket-api",
"Port": 80
}
],
"UpstreamPathTemplate": "/api/{version}/b/{everything}",
"UpstreamHttpMethod": [],
"AuthenticationOptions": {
"AuthenticationProviderKey": "IdentityApiKey",
"AllowedScopes": []
}
}
Az Ocelot futtatásakor megtekinti a ReRoutes AuthenticationOptions.AuthenticationProviderKey elemet, és ellenőrzi, hogy van-e regisztrálva egy hitelesítésszolgáltató a megadott kulccsal. Ha nincs, akkor az Ocelot nem indul el. Ha van ilyen, akkor a ReRoute ezt a szolgáltatót fogja használni a végrehajtáskor.
Mivel az Ocelot WebHost konfigurálva van a authenticationProviderKey = "IdentityApiKey"
, amely hitelesítést igényel, amikor a szolgáltatás bármilyen hitelesítési jogkivonat nélküli kéréssel rendelkezik.
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" }
};
});
//...
}
}
}
Ezután meg kell adnia az [Engedélyezés] attribútummal való engedélyezést minden olyan erőforráson, amely a mikroszolgáltatásokhoz hasonlóan elérhető, például a következő Basket mikroszolgáltatás-vezérlőben.
namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
{
[Route("api/v1/[controller]")]
[Authorize]
public class BasketController : Controller
{
//...
}
}
A ValidAudience-ek, például a "kosár" korrelálnak az egyes mikroszolgáltatásokban meghatározott célközönséggel AddJwtBearer()
az indítási osztály ConfigureServices() osztályában, például az alábbi kódban.
// 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";
});
Ha megpróbál hozzáférni bármilyen biztonságos mikroszolgáltatáshoz, például a Basket mikroszolgáltatáshoz egy ReRoute URL-címmel az API Gateway(hez hasonló) http://host.docker.internal:5202/api/v1/b/basket/1
alapján, akkor a 401-es jogosulatlan értéket kapja, hacsak nem ad meg érvényes jogkivonatot. Ha viszont hitelesíti a ReRoute URL-címét, az Ocelot meghívja a hozzá társított alsóbb rétegbeli sémát (a belső mikroszolgáltatás URL-címét).
Engedélyezés az Ocelot ReRoutes szintjén. Az Ocelot támogatja a hitelesítés után kiértékelt jogcímalapú engedélyezést. Az engedélyezést útvonalszinten állíthatja be az alábbi sorokkal a ReRoute-konfigurációhoz.
"RouteClaimsRequirement": {
"UserType": "employee"
}
Ebben a példában az engedélyezési köztes szoftver meghívásakor az Ocelot megkeresi, hogy a felhasználónak van-e "UserType" jogcímtípusa a jogkivonatban, és hogy a jogcím értéke "alkalmazott"-e. Ha nem, akkor a felhasználó nem lesz engedélyezve, és a válasz 403-ra lesz tiltva.
A Kubernetes Bejövő forgalom és az Ocelot API-átjárók használata
A Kubernetes használatakor (például egy Azure Kubernetes Service-fürtben) általában az összes HTTP-kérést az Nginx alapján a Kubernetes Bejövő forgalom rétegen keresztül egyesíti.
A Kubernetesben, ha nem használ bejövő forgalmat, akkor a szolgáltatások és podok ip-címei csak a fürthálózat által irányíthatók.
Ha azonban bemeneti megközelítést használ, akkor az internet és a szolgáltatások (beleértve az API Gateway-eket is) között egy középső réteg lesz, amely fordított proxyként működik.
Definícióként a bejövő forgalom olyan szabályok gyűjteménye, amelyek lehetővé teszik a bejövő kapcsolatok számára a fürtszolgáltatások elérését. A bejövő forgalom úgy van konfigurálva, hogy külsőleg elérhető URL-címeket, terheléselosztási forgalmat, SSL-lezárásokat és egyebeket biztosítson. A felhasználók a bejövő forgalom kéréséhez az API-kiszolgálóra küldik a bejövő erőforrást.
Az eShopOnContainersben helyi fejlesztéskor és csak a fejlesztőgép docker-gazdagépként való használata esetén nem használ bejövő forgalmat, hanem csak a több API-átjárót.
A Kubernetesen alapuló "éles" környezetek megcélzásakor azonban az eShopOnContainers egy bejövő forgalmat használ az API-átjárók előtt. Így az ügyfelek továbbra is ugyanazt az alap URL-címet hívják, de a kérések több API-átjáróhoz vagy BFF-hez lesznek irányítva.
Az API-átjárók olyan előtér- vagy homlokzatok, amelyek csak a szolgáltatásokat használják, a webalkalmazásokat azonban nem, amelyek általában nem tartoznak a hatókörükbe. Emellett előfordulhat, hogy az API Gatewayek elrejtenek bizonyos belső mikroszolgáltatásokat.
A bejövő forgalom azonban csak átirányítja a HTTP-kéréseket, de nem próbál elrejteni semmilyen mikroszolgáltatást vagy webalkalmazást.
A kubernetesben a webalkalmazások előtt bejövő Nginx-szint, valamint számos Ocelot API Gateway /BFF ideális architektúra, ahogyan az alábbi ábrán is látható.
6-41. ábra. Az eShopOnContainers bejövő szintje a Kubernetesben való üzembe helyezéskor
A Kubernetes Bejövő forgalom fordított proxyként működik az alkalmazás felé irányuló összes forgalomhoz, beleértve a webalkalmazásokat is, amelyek nem tartoznak az Api-átjáró hatókörébe. Az eShopOnContainers Kubernetesben való üzembe helyezésekor csak néhány szolgáltatást vagy végpontot tesz elérhetővé bejövő forgalomon keresztül, alapvetően az URL-címek postfixjeinek alábbi listája:
/
az ügyfél SPA-webalkalmazáshoz/webmvc
az ügyfél MVC-webalkalmazásához/webstatus
az állapot-/állapotellenőrzéseket megjelenítő ügyfél-webalkalmazás esetében/webshoppingapigw
a webes BFF-hez és a vásárlási üzleti folyamatokhoz/webmarketingapigw
a webes BFF-hez és a marketing üzleti folyamatokhoz/mobileshoppingapigw
a mobil BFF-hez és a vásárlási üzleti folyamatokhoz/mobilemarketingapigw
a mobil BFF-hez és a marketing üzleti folyamatokhoz
A Kubernetesben való üzembe helyezéskor minden Ocelot API Gateway egy másik "configuration.json" fájlt használ az API-átjárókat futtató podokhoz. Ezek a "configuration.json" fájlok az "ocelot" nevű Kubernetes konfigurációs térkép alapján létrehozott kötet csatlakoztatásával (eredetileg a deploy.ps1 szkripttel) érhetők el. Minden tároló csatlakoztatja a kapcsolódó konfigurációs fájlt a tároló nevű /app/configuration
mappájába.
Az eShopOnContainers forráskódfájljaiban az eredeti "configuration.json" fájlok találhatók a k8s/ocelot/
mappában. Minden BFF/APIGatewayhez egy fájl tartozik.
További keresztvágási funkciók az Ocelot API Gatewayben
Az Ocelot API Gateway használata esetén a kutatásnak és a használatnak egyéb fontos funkciói is vannak, amelyeket az alábbi hivatkozások mutatnak be.
Szolgáltatásfelderítés az ügyféloldalon az Ocelot és az Eureka konzulral való integrálásával
https://ocelot.readthedocs.io/en/latest/features/servicediscovery.htmlGyorsítótárazás az API Gateway szintjén
https://ocelot.readthedocs.io/en/latest/features/caching.htmlNaplózás az API Gateway szintjén
https://ocelot.readthedocs.io/en/latest/features/logging.htmlSzolgáltatásminőség (újrapróbálkozók és megszakítók) az API Gateway szintjén
https://ocelot.readthedocs.io/en/latest/features/qualityofservice.htmlSebességkorlátozás
https://ocelot.readthedocs.io/en/latest/features/ratelimiting.htmlSwagger for Ocelot
https://github.com/Burgyn/MMLib.SwaggerForOcelot