Megosztás a következőn keresztül:


Külső szolgáltatások használata az Azure API Management szolgáltatásból

A KÖVETKEZŐRE VONATKOZIK: Minden API Management-szint

Az Azure API Management szolgáltatásban elérhető szabályzatok számos hasznos munkát végezhetnek pusztán a bejövő kérés, a kimenő válasz és az alapvető konfigurációs információk alapján. Az API Management-szabályzatok külső szolgáltatásaival való interakció azonban sokkal több lehetőséget kínál.

Korábban már láthatta, hogyan használhatja az Azure Event Hub szolgáltatást naplózás, monitorozás és elemzés céljából. Ez a cikk olyan szabályzatokat mutat be, amelyek lehetővé teszik bármely külső HTTP-alapú szolgáltatás használatát. Ezek a szabályzatok használhatók távoli események aktiválására vagy az eredeti kérés és válasz valamilyen módon történő módosítására szolgáló információk lekérésére.

Egyirányú kérés küldése

Lehetséges, hogy a legegyszerűbb külső interakció a tűz-és felejtési stílus kérés, amely lehetővé teszi, hogy egy külső szolgáltatás értesítést valamilyen fontos esemény. A vezérlési folyamat szabályzatával choose bármilyen feltételt észlelhet, amely érdekli. Ha a feltétel teljesül, külső HTTP-kérést is kezdeményezhet az egyirányú küldési szabályzat használatával. Ez lehet egy olyan üzenetkezelő rendszer kérése, mint a Hipchat vagy a Slack, vagy egy levelezési API, például a SendGrid vagy a MailChimp, vagy a PagerDutyhoz hasonló kritikus támogatási incidensek. Ezen üzenetkezelési rendszerek mindegyike egyszerű HTTP API-kkal rendelkezik, amelyek meghívhatók.

Riasztás a Slacktel

Az alábbi példa bemutatja, hogyan küldhet üzenetet egy Slack-csevegőszobának, ha a HTTP-válasz állapotkódja nagyobb vagy egyenlő 500-nál. Az 500 tartományhiba azt a problémát jelzi a háttér API-val kapcsolatban, amelyet az API ügyfele nem tud megoldani. Általában valamilyen beavatkozást igényel az API Management részen.

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

A Slack a bejövő webes horgok fogalmával rendelkezik. Bejövő webes horog konfigurálásakor a Slack létrehoz egy speciális URL-címet, amely lehetővé teszi egy egyszerű POST-kérés végrehajtását és egy üzenet továbbítását a Slack-csatornába. A létrehozott JSON-törzs a Slack által meghatározott formátumon alapul.

Slack Web Hook

A tűz és a felejtés elég jó?

Vannak bizonyos kompromisszumok használata esetén tűz-és felejtés stílusú kérés. Ha valamilyen okból a kérés meghiúsul, akkor a rendszer nem jelenti a hibát. Ebben a konkrét helyzetben a másodlagos hibajelentési rendszer összetettsége és a válaszra való várakozás további teljesítményköltsége nem indokolt. Azokban a forgatókönyvekben, ahol elengedhetetlen a válasz ellenőrzése, akkor a küldési-kérési szabályzat jobb megoldás.

Küldési kérelem

A send-request szabályzat lehetővé teszi, hogy külső szolgáltatás használatával összetett feldolgozási függvényeket hajtson végre, és adatokat adjon vissza az API management szolgáltatásnak, amely további szabályzatfeldolgozáshoz használható.

Referencia-jogkivonatok engedélyezése

Az API Management egyik fő funkciója a háttérerőforrások védelme. Ha az API által használt engedélyezési kiszolgáló JWT-jogkivonatokat hoz létre az OAuth2-folyamat részeként, ahogyan a Microsoft Entra ID is teszi, akkor a validate-jwt szabályzat vagy validate-azure-ad-token szabályzat használatával ellenőrizheti a jogkivonat érvényességét. Egyes engedélyezési kiszolgálók referencia-jogkivonatokat hoznak létre , amelyek nem ellenőrizhetők az engedélyezési kiszolgálóra való visszahívás nélkül.

Standardizált bevezető

A múltban nem volt szabványosított módszer egy referencia-jogkivonat hitelesítésére egy engedélyezési kiszolgálóval. Az IETF azonban közzétett egy nemrég javasolt standard RFC 7662-et , amely meghatározza, hogy egy erőforrás-kiszolgáló hogyan ellenőrizheti egy jogkivonat érvényességét.

A jogkivonat kinyerése

Az első lépés a jogkivonat kinyerése az Engedélyezés fejlécből. A fejléc értékét az Bearer engedélyezési sémával, egyetlen szóközzel, majd az engedélyezési jogkivonattal kell formázni az RFC 6750 szerint. Sajnos vannak olyan esetek, amikor az engedélyezési sémát kihagyják. Ennek az elemzés során történő figyelembe vételéhez az API Management felosztja a fejléc értékét egy szóközre, és kiválasztja az utolsó sztringet a visszaadott sztringtömbből. Ez kerülő megoldást kínál a hibásan formázott engedélyezési fejlécekhez.

<set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param").Split(' ').Last())" />

Az érvényesítési kérelem végrehajtása

Ha az API Management rendelkezik az engedélyezési jogkivonattal, az API Management kérheti a jogkivonat érvényesítését. Az RFC 7662 meghívja ezt a folyamatot, és egy HTML-űrlapot igényel POST az introspection erőforráshoz. A HTML-űrlapnak tartalmaznia kell legalább egy kulcsot/értékpárt a kulccsal token. Az engedélyezési kiszolgáló felé irányuló kérést is hitelesíteni kell, hogy a rosszindulatú ügyfelek ne férhessenek hozzá az érvényes jogkivonatokhoz.

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

A válasz ellenőrzése

Az response-variable-name attribútum a visszaadott válasz elérésére szolgál. A tulajdonságban definiált név kulcsként használható a szótárban az context.Variables IResponse objektum eléréséhez.

A válaszobjektumból lekérheti a törzset, és az RFC 7622 tájékoztatja az API Managementet, hogy a válasznak JSON-objektumnak kell lennie, és tartalmaznia kell legalább egy logikai értéket tartalmazó active tulajdonságot. Ha active igaz, akkor a jogkivonat érvényesnek minősül.

Ha az engedélyezési kiszolgáló nem tartalmazza az "aktív" mezőt, amely jelzi, hogy a jogkivonat érvényes-e, használjon egy olyan eszközt, mint a Postman, amely meghatározza, hogy milyen tulajdonságok vannak beállítva egy érvényes jogkivonatban. Ha például egy érvényes jogkivonat-válasz tartalmaz egy "expires_in" nevű tulajdonságot, ellenőrizze, hogy ez a tulajdonságnév létezik-e az engedélyezési kiszolgáló válaszában így:

<when condition="@(((IResponse)context.Variables["tokenstate"]).Body.As<JObject>().Property("expires_in") == null)">

Jelentéskészítési hiba

Szabályzat használatával <choose> észlelheti, hogy a jogkivonat érvénytelen-e, és ha igen, 401-et ad vissza.

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

A jogkivonatok használatát leíró bearer RFC 6750 szerint az API Management a WWW-Authenticate 401-es válaszú fejlécet is visszaadja. A WWW-Authenticate utasítást ad az ügyfélnek egy megfelelően engedélyezett kérés összeállítására. Az OAuth2 keretrendszerrel lehetséges megközelítések széles választéka miatt nehéz minden szükséges információt közölni. Szerencsére vannak folyamatban lévő erőfeszítések annak érdekében, hogy az ügyfelek felfedezzék, hogyan engedélyezhetik megfelelően az erőforrás-kiszolgálóra irányuló kéréseket.

Végső megoldás

A végén a következő szabályzat jelenik meg:

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

Ez csak egy a számos példa közül, hogy a send-request szabályzat hogyan integrálható hasznos külső szolgáltatásokba az API Management szolgáltatáson keresztül áramló kérések és válaszok folyamatába.

Válaszösszeállítás

A send-request szabályzat használható a háttérrendszerre irányuló elsődleges kérések továbbfejlesztésére, ahogy az előző példában is láthatta, vagy a háttérhívás teljes cseréjeként is használható. Ezzel a technikával egyszerűen létrehozhat összetett erőforrásokat, amelyek több különböző rendszerből vannak összesítve.

Irányítópult létrehozása

Előfordulhat, hogy több háttérrendszerben található információkat szeretne elérhetővé tenni, például egy irányítópult vezetéséhez. A KPI-k minden különböző háttérrendszerből származnak, de ön inkább nem szeretne közvetlen hozzáférést biztosítani hozzájuk, és jó lenne, ha minden információt egyetlen kérelemben lehetne lekérni. Talán néhány háttérinformációhoz előbb szeletelésre, diktálásra és egy kis fertőtlenítésre van szükség! Az összetett erőforrás gyorsítótárazása hasznos lehet a háttérbetöltés csökkentéséhez, mivel tudja, hogy a felhasználók szokása szerint az F5-kulcsot kalapálják annak érdekében, hogy kiderüljön, megváltozhatnak-e az alulteljesítő metrikáik.

Az erőforrás elhalványulása

Az irányítópult-erőforrás létrehozásának első lépése egy új művelet konfigurálása az Azure Portalon. Ez egy helyőrző művelet, amellyel konfigurálható egy összeállítási szabályzat a dinamikus erőforrás létrehozásához.

Irányítópult-művelet

A kérések végrehajtása

A művelet létrehozása után konfigurálhat egy szabályzatot kifejezetten ehhez a művelethez.

Képernyőkép a Szabályzat hatókörének képernyőről.

Az első lépés a lekérdezési paraméterek kinyerése a bejövő kérelemből, hogy továbbíthassa őket a háttérrendszernek. Ebben a példában az irányítópult egy adott időszakon alapuló információkat jelenít meg, ezért rendelkezik egy és toDate egy fromDate paraméterrel. A szabályzat segítségével set-variable kinyerheti az adatokat a kérelem URL-címéből.

<set-variable name="fromDate" value="@(context.Request.Url.Query["fromDate"].Last())">
<set-variable name="toDate" value="@(context.Request.Url.Query["toDate"].Last())">

Miután megkapta ezeket az információkat, kéréseket intézhet az összes háttérrendszerhez. Minden kérés létrehoz egy új URL-címet a paraméteradatokkal, meghívja a megfelelő kiszolgálót, és egy környezeti változóban tárolja a választ.

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

Az API Management egymás után küldi el ezeket a kéréseket.

Válaszol

Az összetett válasz létrehozásához használhatja a visszatérési-válasz szabályzatot. Az set-body elem egy kifejezéssel létrehozhat egy újat JObject , amely az összes összetevő-ábrázolás tulajdonságként van beágyazva.

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

A teljes szabályzat a következőképpen néz ki:

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

Összegzés

Az Azure API Management szolgáltatás rugalmas szabályzatokat biztosít, amelyek szelektíven alkalmazhatók a HTTP-forgalomra, és lehetővé teszik a háttérszolgáltatások összetételét. Akár riasztási funkciókkal, ellenőrzéssel, érvényesítési képességekkel szeretné továbbfejleszteni az API-átjárót, akár több háttérszolgáltatáson alapuló új összetett erőforrásokat szeretne létrehozni, a send-request kapcsolódó szabályzatok a lehetőségek világát nyitják meg.