Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
PLATÍ PRO: Všechny úrovně služby API Management
Zásady dostupné ve službě Azure API Management můžou provádět širokou škálu užitečných prací čistě na příchozím požadavku, odchozí odpovědi a základních konfiguračních informacích. Schopnost pracovat s externími službami ze zásad služby API Management ale nabízí spoustu dalších příležitostí.
V předchozích článcích jste zjistili, jak pracovat se službou Azure Event Hubs pro protokolování, monitorování a analýzu. Tento článek ukazuje zásady, které umožňují interakci s jakoukoli externí službou založenou na protokolu HTTP. Tyto zásady se dají použít k aktivaci vzdálených událostí nebo k načítání informací, které slouží k manipulaci s původním požadavkem a odpovědí nějakým způsobem.
Odeslat jednosměrnou žádost
Možná nejjednodušší externí interakce je styl požadavku typu fire-and-forget, který umožňuje externí službě být upozorněna na důležitou událost. Zásady choose toku řízení se dají použít k detekci jakéhokoli druhu podmínky, která vás zajímá. Pokud je podmínka splněná, můžete vytvořit externí požadavek HTTP pomocí zásady odesílání jednosměrných požadavků . Tento požadavek může být odeslán do systému zasílání zpráv, jako je Hipchat nebo Slack, nebo do e-mailového API, jako je SendGrid nebo MailChimp, anebo pro kritické případy podpory, jako je PagerDuty. Všechny tyto systémy zasílání zpráv mají jednoduchá rozhraní API HTTP, která je možné vyvolat.
Upozorňování pomocí Slacku
Následující příklad ukazuje, jak odeslat zprávu do chatovací místnosti Slack, pokud je stavový kód odpovědi HTTP větší nebo roven 500. Chyba rozsahu 500 značí problém s backendovým rozhraním API, který klient rozhraní API nedokáže sám vyřešit. Obvykle vyžaduje určitý druh zásahu v části API Management.
<choose>
<when condition="@(context.Response.StatusCode >= 500)">
<send-one-way-request mode="new">
<set-url>https://hooks.slack.com/services/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</set-url>
<set-method>POST</set-method>
<set-body>@{
return new JObject(
new JProperty("username","APIM Alert"),
new JProperty("icon_emoji", ":ghost:"),
new JProperty("text", String.Format("{0} {1}\nHost: {2}\n{3} {4}\n User: {5}",
context.Request.Method,
context.Request.Url.Path + context.Request.Url.QueryString,
context.Request.Url.Host,
context.Response.StatusCode,
context.Response.StatusReason,
context.User.Email
))
).ToString();
}</set-body>
</send-one-way-request>
</when>
</choose>
Slack má pojem příchozích webových háků. Když nakonfiguruje příchozí webhook, Slack vygeneruje speciální adresu URL, která umožňuje provést základní požadavek POST a předat zprávu do kanálu Slack. Text JSON, který vytvoříte, je založený na formátu definovaném slackem.
Je koncept "fire and forget" dostatečně dobrý?
Při použití přístupu „vystřel a zapomeň“ existují určité kompromisy ve stylu zadávání požadavků. Pokud z nějakého důvodu požadavek selže, selhání se nenahlásí. V takovém případě není složitost sekundárního systému hlášení chyb a dodatečné náklady na výkon způsobené čekáním na odpověď opodstatněná. V situacích, kdy je nezbytné zkontrolovat odpověď, je lepší volbou zásada odeslání požadavku .
Odeslat žádost
Tato send-request zásada umožňuje používat externí službu k provádění složitých funkcí zpracování a vracení dat do služby API Management, kterou je možné použít k dalšímu zpracování zásad.
Autorizace referenčních tokenů
Hlavní funkcí služby API Management je ochrana back-endových prostředků. Pokud autorizační server používaný vaším rozhraním API vytvoří v rámci toku OAuth2 webové tokeny JSON (JWT), jak to dělá Microsoft Entra ID , můžete k ověření platnosti tokenu použít validate-jwt zásadu nebo validate-azure-ad-token zásadu. Některé autorizační servery vytvářejí tzv . referenční tokeny , které se nedají ověřit bez zpětného volání na autorizační server.
Standardizovaná introspekce
V minulosti neexistoval žádný standardizovaný způsob ověřování referenčního tokenu s autorizačním serverem. IETF (Internet Engineering Task Force) však nedávno publikoval navrhovaný standard RFC 7662 , který definuje, jak může server prostředků ověřit platnost tokenu.
Extrahování tokenu
Prvním krokem je extrakce tokenu z autorizační hlavičky. Hodnota hlavičky by měla být naformátovaná schématem Bearer autorizace, jednou mezerou a potom autorizačním tokenem podle dokumentu RFC 6750. Bohužel existují případy, kdy je schéma autorizace vynecháno. Aby se při parsování tato vynechání zohlednila, služba API Management rozdělí hodnotu hlavičky podle mezer a vybere poslední řetězec z vráceného seznamu řetězců. Tato metoda poskytuje alternativní řešení pro špatně formátované autorizační hlavičky.
<set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param").Split(' ').Last())" />
Vytvoření žádosti o ověření
Jakmile má služba API Management autorizační token, může služba API Management provést požadavek na ověření tokenu. RFC 7662 nazývá tento proces introspekcí a vyžaduje, abyste odeslali POST formulář HTML do prostředku introspekce. Formulář HTML musí obsahovat alespoň jednu dvojici klíč/hodnota, kde klíčem je token. Tato žádost na autorizační server musí být také autentizována, aby se zajistilo, že škodliví klienti nebudou moci hledat platné tokeny.
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
<set-url>https://microsoft-apiappec990ad4c76641c6aea22f566efc5a4e.azurewebsites.net/introspection</set-url>
<set-method>POST</set-method>
<set-header name="Authorization" exists-action="override">
<value>basic dXNlcm5hbWU6cGFzc3dvcmQ=</value>
</set-header>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@($"token={(string)context.Variables["token"]}")</set-body>
</send-request>
Kontrola odpovědi
Atribut response-variable-name slouží k udělení přístupu k vrácené odpovědi. Název definovaný v této vlastnosti lze použít jako klíč do slovníku context.Variables pro přístup k objektu IResponse .
Z objektu odpovědi můžete načíst tělo a RFC 7622 uvádí, že služba API Management musí zajistit, že odpověď je objekt JSON, který obsahuje alespoň jednu vlastnost nazvanou active, která má hodnotu typu boolean. Pokud active je token pravdivý, považuje se za platný.
Pokud autorizační server neobsahuje "active" pole označující, jestli je token platný, použijte klientský nástroj HTTP, například curl k určení vlastností, které jsou nastaveny v platném tokenu. Pokud například platná odpověď tokenu obsahuje vlastnost s názvem "expires_in", zkontrolujte, zda tento název vlastnosti existuje v odpovědi autorizačního serveru tímto způsobem:
<when condition="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>().Property("expires_in") == null)">
Hlášení selhání
Pomocí zásady můžete <choose> zjistit, jestli je token neplatný a pokud ano, vrátit odpověď 401.
<choose>
<when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
<return-response response-variable-name="existing response variable">
<set-status code="401" reason="Unauthorized" />
<set-header name="WWW-Authenticate" exists-action="override">
<value>Bearer error="invalid_token"</value>
</set-header>
</return-response>
</when>
</choose>
Podle dokumentu RFC 6750, který popisuje, jak bearer se mají používat tokeny, vrátí služba API Management také hlavičku WWW-Authenticate s odpovědí 401. Www-Authenticate je určen k pokynu klientovi, jak vytvořit správně autorizovaný požadavek. Vzhledem k široké škále možných přístupů s architekturou OAuth2 je obtížné sdělit všechny potřebné informace. Naštěstí probíhá úsilí, které pomáhá klientům zjistit, jak správně autorizovat požadavky na server zdrojů.
Konečné řešení
Na konci získáte následující zásady:
<inbound>
<!-- Extract Token from Authorization header parameter -->
<set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param").Split(' ').Last())" />
<!-- Send request to Token Server to validate token (see RFC 7662) -->
<send-request mode="new" response-variable-name="tokenstate" timeout="20" ignore-error="true">
<set-url>https://microsoft-apiappec990ad4c76641c6aea22f566efc5a4e.azurewebsites.net/introspection</set-url>
<set-method>POST</set-method>
<set-header name="Authorization" exists-action="override">
<value>basic dXNlcm5hbWU6cGFzc3dvcmQ=</value>
</set-header>
<set-header name="Content-Type" exists-action="override">
<value>application/x-www-form-urlencoded</value>
</set-header>
<set-body>@($"token={(string)context.Variables["token"]}")</set-body>
</send-request>
<choose>
<!-- Check active property in response -->
<when condition="@((bool)((IResponse)context.Variables["tokenstate"]).Body.As<JObject>()["active"] == false)">
<!-- Return 401 Unauthorized with http-problem payload -->
<return-response response-variable-name="existing response variable">
<set-status code="401" reason="Unauthorized" />
<set-header name="WWW-Authenticate" exists-action="override">
<value>Bearer error="invalid_token"</value>
</set-header>
</return-response>
</when>
</choose>
<base />
</inbound>
Tento příklad je pouze jedním z mnoha, které ukazují, jak send-request se zásady dají použít k integraci užitečných externích služeb do procesu požadavků a odpovědí procházejících službou API Management.
Složení odpovědi
Zásady send-request se dají použít k vylepšení primárního požadavku na back-endový systém, jak jste viděli v předchozím příkladu, nebo ho můžete použít k úplnému nahrazení back-endového volání. Pomocí této techniky můžete snadno vytvořit složené prostředky, které se agregují z více různých systémů.
Vytvoření řídicího panelu
Někdy chcete mít možnost zveřejnit informace, které existují v několika back-endových systémech, například pro řízení řídicího panelu. Klíčové ukazatele výkonu (KPI) pocházejí ze všech různých back-endů, ale nechcete jim poskytovat přímý přístup. Přesto by bylo dobré, kdyby se všechny informace mohly načíst v jediné žádosti. Možná některé z informací v zázemí potřebují nejdříve trochu řezání, úprav a očištění! Schopnost ukládat složený prostředek do mezipaměti by byla užitečným způsobem, jak snížit zatížení backendu, protože víte, že uživatelé mají zvyk opakovaně stisknout klávesu F5, aby zjistili, zda se jejich neuspokojivé metriky nezmění.
Falšování zdroje
Prvním krokem k vytvoření prostředku řídicího panelu je konfigurace nové operace na webu Azure Portal. Tato zástupná operace slouží ke konfiguraci zásad složení pro sestavení dynamického prostředku.
Vytváření požadavků
Po vytvoření operace můžete nakonfigurovat zásady speciálně pro tuto operaci.
Prvním krokem je extrakce parametrů dotazu z příchozího požadavku, abyste je mohli předat do back-endu. V tomto příkladu řídicí panel zobrazuje informace na základě časového období, a proto má fromDate a toDate parametr. Můžete použít zásady set-variable k extrahování informací z adresy URL požadavku.
<set-variable name="fromDate" value="@(context.Request.Url.Query["fromDate"].Last())">
<set-variable name="toDate" value="@(context.Request.Url.Query["toDate"].Last())">
Jakmile budete mít tyto informace, můžete zadávat požadavky ke všem systémům na pozadí. Každý požadavek vytvoří novou adresu URL s informacemi o parametru a zavolá příslušný server a uloží odpověď do kontextové proměnné.
<send-request mode="new" response-variable-name="revenuedata" timeout="20" ignore-error="true">
<set-url>@($"https://accounting.acme.com/salesdata?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="materialdata" timeout="20" ignore-error="true">
<set-url>@($"https://inventory.acme.com/materiallevels?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="throughputdata" timeout="20" ignore-error="true">
<set-url>@($"https://production.acme.com/throughput?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="accidentdata" timeout="20" ignore-error="true">
<set-url>@($"https://production.acme.com/accidentdata?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")</set-url>
<set-method>GET</set-method>
</send-request>
SLUŽBA API Management tyto požadavky odesílá postupně.
Reagující
K vytvoření složené odpovědi můžete použít zásadu návratové odpovědi . Element set-body může použít výraz k vytvoření nového JObject se všemi reprezentacemi součástí vloženými jako vlastnosti.
<return-response response-variable-name="existing response variable">
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>
@(new JObject(new JProperty("revenuedata",((IResponse)context.Variables["revenuedata"]).Body.As<JObject>()),
new JProperty("materialdata",((IResponse)context.Variables["materialdata"]).Body.As<JObject>()),
new JProperty("throughputdata",((IResponse)context.Variables["throughputdata"]).Body.As<JObject>()),
new JProperty("accidentdata",((IResponse)context.Variables["accidentdata"]).Body.As<JObject>())
).ToString())
</set-body>
</return-response>
Úplná zásada vypadá takto:
<policies>
<inbound>
<set-variable name="fromDate" value="@(context.Request.Url.Query["fromDate"].Last())">
<set-variable name="toDate" value="@(context.Request.Url.Query["toDate"].Last())">
<send-request mode="new" response-variable-name="revenuedata" timeout="20" ignore-error="true">
<set-url>@($"https://accounting.acme.com/salesdata?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")"</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="materialdata" timeout="20" ignore-error="true">
<set-url>@($"https://inventory.acme.com/materiallevels?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")"</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="throughputdata" timeout="20" ignore-error="true">
<set-url>@($"https://production.acme.com/throughput?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")"</set-url>
<set-method>GET</set-method>
</send-request>
<send-request mode="new" response-variable-name="accidentdata" timeout="20" ignore-error="true">
<set-url>@($"https://production.acme.com/accidentdata?from={(string)context.Variables["fromDate"]}&to={(string)context.Variables["fromDate"]}")"</set-url>
<set-method>GET</set-method>
</send-request>
<return-response response-variable-name="existing response variable">
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>
@(new JObject(new JProperty("revenuedata",((IResponse)context.Variables["revenuedata"]).Body.As<JObject>()),
new JProperty("materialdata",((IResponse)context.Variables["materialdata"]).Body.As<JObject>()),
new JProperty("throughputdata",((IResponse)context.Variables["throughputdata"]).Body.As<JObject>()),
new JProperty("accidentdata",((IResponse)context.Variables["accidentdata"]).Body.As<JObject>())
).ToString())
</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
</policies>
Shrnutí
Služba Azure API Management poskytuje flexibilní zásady, které se dají selektivně použít na provoz HTTP a umožňují složení back-endových služeb. Bez ohledu na to, jestli chcete vylepšit bránu rozhraní API pomocí funkcí pro upozorňování, ověřování, validaci nebo vytvářet nové složené prostředky založené na několika backendových službách, send-request a související zásady otevírají svět možností.