Onboarding : Azure API Performance and secure backend

Topices

  • Key concepts
    • API Management Components
  • Improve performance by API Management caching
  • Configure caching policy in API Management
  • Caching possibilities
  • Authentication possibilities
  • Expose multiple Azure Function apps as a consistent
  • Azure Front Door

Related topices

Key concepts

  • Azure API Management
  • API
  • API definition
  • API Gateway (APIM component)
    • Accepts API calls and routes them to the backend.
    • Verifies API keys, JWT tokens, certificates, and other credentials.
    • Enforces usage quotas and rate limits.
    • Transforms your API on the fly without code modifications.
    • Caches backend responses where set up.
    • Logs call metadata for analytics purposes.
  • Cache
  • Policies
  • Redis cache
  • Front Door
API Management Components
API gateway

The API gateway is the endpoint that:

  • Accepts API calls and routes them to the backend.
  • Verifies API keys, JWT tokens, certificates, and other credentials.
  • Enforces usage quotas and rate limits.
  • Transforms your API on the fly without code modifications.
  • Caches backend responses where set up.
  • Logs call metadata for analytics purposes.
Azure portal

The Azure portal is the administrative interface where you set up your API program. You can also use it to:

  • Define or import API schema.
  • Package APIs into products.
  • Set up policies such as quotas or transformations on the APIs.
  • Get insights from analytics.
  • Manage users.
Developer portal

The Developer portal serves as the main web presence for developers. From here they can:

  • Read API documentation.
  • Try out an API via the interactive console.
  • Create an account and subscribe to get API keys.
  • Access analytics on their own usage.

Source: https://docs.microsoft.com/en-us/learn/modules/control-authentication-with-apim/1a-understand-apim

Improve performance by API Management caching

Scenario: Suppose you are a developer for a board game company. A product line produced by your company has recently become popular. The volume of requests from your retail partners to your inventory API is growing quickly: much faster than the rate that your inventory actually changes. You’d like your API to respond to requests rapidly without incurring load on your API. You use Azure API Management to host your API. You’re considering using an API Management policy to cache compiled responses to requests. 

  • Api management for changing the behaviore of the api without changing the code
    • policy for set limit
    • for changing response format
    • check mandetory headers
    • authenticared caller / enforce security requirements
    • certificate verification
    • has XML format
    • policies section
      • inbount
      • backend
      • outbount
      • on-error
    • policy scopes
      • global
      • api
      • operation
      • product
  • it exposes apis of a company for the api customers
  • it is used for api inventory
<policies>
    <inbound>
        <base />
 # it means first the policy of the higher level is applied
        <check-header name="Authorization" failed-check-httpcode="401" failed-check-error-message="Not authorized" ignore-case="false">
        </check-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <json-to-xml apply="always" consider-accept-header="false" parse-date="false" />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
  • policies for
    • restricting access e.g. Check Http Header, Limit call rate by subscription, Limit call rate by key, Restrict caller Ips, Policies for Authentication, Cross domain policies, Transformation policies
  • Cross domain policies
    • Cross domain requests are considered a security threat and denied by browsers and APIs
    • Cross-Origin Resource Sharing (CORS), use the CORS policy
    • Some AJAX code, which runs on the browser, uses JSON with padding to make cross-domain calls securely. Use the JSONP policy to permit clients to use this technique
  • Caching policies
    • better performance for caching the compiled responses
  • Advanced policies
    • apply a policy only when the response passes a specific test, use the Control flow policy
    • Use the Forward request policy to forward a request to a backend server
    • To control what happens when an action fails, use the Retry policy
    • The Send one-way request policy can send a request to a URL without waiting for a response
    • If you want to store a value for use in a later calculation or test, use the Set variable policy to persist a value in a named variable

Source : https://docs.microsoft.com/en-us/learn/modules/improve-api-performance-with-apim-caching-policy/1-introduction

Configure caching policy in API Management

  • using a cache of compiled responses
<policies>
    <inbound>
        <base />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" must-revalidate="true" caching-type="internal" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <cache-store duration="60" />
        <base />
    </outbound>
    </on-error>
        <base />
    </on-error>
</policies>
  • store individual values in the cache, instead of a complete response
  • with an identifying key
  • Retrieve the value from the cache by using the cache-lookup-value policy
  • want to remove a value before it expires, use the cache-remove-value policy
<policies>
    <inbound>
        <cache-lookup-value key="12345"
            default-value="$0.00"
            variable-name="boardPrice"
            caching-type="internal" />
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <cache-store-value key="12345"
            value="$3.60"
            duration="3600"
            caching-type="internal" />
        <base />
    </outbound>
    </on-error>
        <base />
    </on-error>
</policies>
  • we can use vary-by tags/attributes in cache-lookup-value policy.
    • vary-by-query-parameter (tag): if all users have to see same price/result for a specific product, then we have to set vary-by-query-parameter to partnumber. APIM groups the requests based on partnumber.
    • vary-by-developer (attribute): becase vary-by-developer=”false”, APIM understands that different subscriptions key doesn’t alter the response. if this attribute is true, APIM serves a response from the cache only if it was originally requested with the same subscription key.
    • If a header can make a significant difference to a response, use the <vary-by-header> tag
<policies>
    <inbound>
        <base />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" must-revalidate="true" caching-type="internal">
            <vary-by-query-parameter>partnumber</vary-by-query-parameter>
        </cache-lookup>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <cache-store duration="60" />
        <base />
    </outbound>
    </on-error>
        <base />
    </on-error>
</policies>

Source: https://docs.microsoft.com/en-us/learn/modules/improve-api-performance-with-apim-caching-policy/4-configure-a-caching-policy

Caching possibilities

  • Internal Cache -> API Management
  • External Cache -> Azure Cache for Redis service

Why using external cache

  • you want to avoid the cache being cleared when the API Management service is updated.
  • you want to have greater control over the cache configuration than the internal cache allows
  • You want to cache more data than can be store in the internal cache.
  • if you use apim with consumption pricing tier, then you have to use external cache. because this pricing tier follows the serverless designprincipal and we should use it with serverless web apis, and it has no internal cache.

Example:

# Create a Redis cache

Source

Authentication possibilities

  • OAuth 2.0
  • API keys / subscriptions (query string / header parameter)
    • The default header name is Ocp-Apim-Subscription-Key, and the default query string is subscription-key.
  • client certificate

Scenario: Suppose you work for a meteorological company, which has an API that customers use to access weather data for forecasts and research. There is proprietary information in this data, and you would like to ensure that only paying customers have access. You want to use Azure API Management to properly secure this API from unauthorized use.

Scenario: Businesses are extending their operations as a digital platform by creating new channels, finding new customers, and driving deeper engagement with existing ones. APIM provides the core competencies to ensure a successful API program through developer engagement, business insights, analytics, security, and protection. You can use APIM to take any backend and launch a full-fledged API program based on it.

Use Subscription key to secure access to an API

  • Azure api management service helps to expose the apis
  • developers musr subscrib the api / product (these are two different scope)
    • used to secure the api / product with a subscription key / API key
    • preventing denial of service attacks (DoS) by using throttling
    • or using advanced security policies like JSON Web Token (JWT) validation
  • Enabling independent software vendor (ISV) partner ecosystems by offering fast partner onboarding through the developer portal
  • we can define who can access api through the api gateway (only customers who have subscribed to your service can access the API and use your forecast data, by issuing subscription keys)
# how you can pass a key in the request header using curl
curl --header "Ocp-Apim-Subscription-Key: <key string>" https://<apim gateway>.azure-api.net/api/path

# example curl command that passes a key in the URL as a query string
curl https://<apim gateway>.azure-api.net/api/path?subscription-key=<key string>

# If the key is not passed in the header, or as a query string in the URL, you'll get a 401 Access Denied response from the API gateway.

# call without subscription key
curl -X GET https://[Name Of Gateway].azure-api.net/api/Weather/53/-1
# output
{ "statusCode": 401, "message": "Access denied due to missing subscription key. Make sure to include subscription key when making requests to an API." }

# call with subscription key as header
curl -X GET https://[Name Of Gateway].azure-api.net/api/Weather/53/-1 \
  -H 'Ocp-Apim-Subscription-Key: [Subscription Key]'

# output : {"mainOutlook":{"temperature":32,"humidity":34},"wind":{"speed":11,"direction":239.0},"date":"2019-05-16T00:00:00+00:00","latitude":53.0,"longitude":-1.0}

Use client certificates to secure access to an API

  • used to provide TLS mutual authentication between the client and the API gateway
  • allow only requests with certificates containing a specific thumbprint (through inbound policies)
  • TLS client authentication, the API Management gateway can inspect the certificate contained within the client request for the following properties
PropertyReason
Certificate Authority (CA)Only allow certificates signed by a particular CA
ThumbprintAllow certificates containing a specified thumbprint
SubjectOnly allow certificates with a specified subject
Expiration DateOnly allow certificates that have not expired
  • two common ways to verify a certificate
    • Check who issued the certificate. If the issuer was a certificate authority that you trust, you can use the certificate. You can configure the trusted certificate authorities in the Azure portal to automate this process.
    • If the certificate is issued by the partner, verify that it came from them. For example, if they deliver the certificate in person, you can be sure of its authenticity. These are known as self-signed certificates.
  • apim consumption tier
    • this tier is for serverless APIs e.g. azure functions
    • in this tier for using client certificate must explicitly enable it APIM Instance > custom domains > Request Client Certificate: Yes
    • this step is not necessary in other tiers

check thumbnail of a client certificate in policies

# Every client certificate includes a thumbprint, which is a hash, calculated from other certificate properties

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Thumbprint != "desired-thumbprint")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

Check the thumbprint against certificates uploaded to API Management

n the previous example, only one thumbprint would work so only one certificate would be validated. Usually, each customer or partner company would pass a different certificate with a different thumbprint. To support this scenario, obtain the certificates from your partners and use the Client certificates page in the Azure portal to upload them to the API Management resource. Then add this code to your policy:

<choose>
    <when condition="@(context.Request.Certificate == null || !context.Request.Certificate.Verify()  || !context.Deployment.Certificates.Any(c => c.Value.Thumbprint == context.Request.Certificate.Thumbprint))" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>

Check the issuer and subject of a client certificate

<choose>
    <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Issuer != "trusted-issuer" || context.Request.Certificate.SubjectName.Name != "expected-subject-name")" >
        <return-response>
            <set-status code="403" reason="Invalid client certificate" />
        </return-response>
    </when>
</choose>
Create Self-Signed Certificate [Source] and use in APIM
# create a private key and certificate
pwd='Pa$$w0rd'
pfxFilePath='selfsigncert.pfx'
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out selfsigncert.crt -subj /CN=localhost

# convert the certificate to PEM format
openssl pkcs12 -export -out $pfxFilePath -inkey privateKey.key -in selfsigncert.crt -password pass:$pwd
openssl pkcs12 -in selfsigncert.pfx -out selfsigncert.pem -nodes

# When you are prompted for a password, type Pa$$w0rd and then press Enter.

# Get the thumbprint for the certificate
Fingerprint="$(openssl x509 -in selfsigncert.pem -noout -fingerprint)"
Fingerprint="${Fingerprint//:}"
echo ${Fingerprint#*=}

# output is hexadecimal string without any accompanying text and no colons
  1. create the self-signed certificate
  2. apim > custom domains > Request client certificates: yes
  3. configure the inbound policy on any scope as follows
<inbound>
    <choose>
        <when condition="@(context.Request.Certificate == null || context.Request.Certificate.Thumbprint != "desired-thumbprint")" >
            <return-response>
                <set-status code="403" reason="Invalid client certificate" />
            </return-response>
        </when>
    </choose>
    <base />
</inbound>

4. call an operation

curl -X GET https://[api-gateway-name].azure-api.net/api/Weather/53/-1 \
  -H 'Ocp-Apim-Subscription-Key: [Subscription Key]'

# output : return a 403 Client certificate error, and no data will be returned.

then test this

curl -X GET https://[gateway-name].azure-api.net/api/Weather/53/-1 \
  -H 'Ocp-Apim-Subscription-Key: [subscription-key]' \
  --cert-type pem \
  --cert selfsigncert.pem

# output: {"mainOutlook":{"temperature":32,"humidity":34},"wind":{"speed":11,"direction":239.0},"date":"2019-05-16T00:00:00+00:00","latitude":53.0,"longitude":-1.0}

Source

Expose multiple Azure Function apps as a consistent API by using APIM

Combine multiple Azure Functions apps into a unified interface by importing them into a single Azure API Management instance.

Scenario: Suppose you work for an online store with a successful and busy web site. Your developers have written the business logic for the site as microservices in the form of Azure Functions. Now, you want to enable partners to interact with your online store from their own code by creating a web API that they can call over HTTP. You want to find an easy way to assemble your functions into a single API.

In your online store, you have implemented each part of the application as a microservice – one for the product details, one for order details, and so on. A separate team manages each microservice and each team uses continuous development and delivery to update and deploy their code on a regular basis. You want to find a way to assemble these microservices into a single product and then manage that product centrally.

  • use Azure Functions and Azure API Management to build complete APIs with a microservices architecture
  • Microservices has become a popular approach to the architecture of distributed applications
  • we can develop distributed systems with serverless architecture e.g. azure function
  • servreless architecture uses stateless computing resources
  • azure function
    • enables serverless architecture
    • we can use NuGet or Node Package Manager (NPM) for development
    • authenticate users with OAuth
    • you can select a template for how you want to trigger your code
clone the functions project,
git clone https://github.com/MicrosoftDocs/mslearn-apim-and-functions.git ~/OnlineStoreFuncs

cd ~/OnlineStoreFuncs
bash setup.sh


after the azure functions are created then we can add them to apim

Source : https://docs.microsoft.com/en-us/learn/modules/build-serverless-api-with-functions-api-management/

Azure Front Door

  • secure entry point for delivering global performant hyperscale apps
  • for application acceleration at microsoft’s edge
  • ooo

Source: https://www.e-apostolidis.gr/microsoft/azure/deliver-your-app-at-global-scale-with-security-resiliency-with-azure-front-doo/


Let the light of your talent lighten your road to success.

Parisa Moosavinezhad


Published by parisamoosavinezhad

- Software Engineer - Software Architect - Software and database specialist - Cloud solution architect

One thought on “Onboarding : Azure API Performance and secure backend

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: