Introduction to Azure API management (part 2)

My first blog post about Azure API management service (Introduction to Azure API management (part 1)) contained the basics of API management. What it is about and how to configure it. In this post I want to describe how to configure basic Azure Active Directory authentication and have glimpse into policies.

Configure Azure Active Directory authentication

The configuration of the Azure Active Directory authentication is useful if you want to give people in your AAD access to APIs in the API management service. You can also configure a group in your AAD that have automatically unlimited access to your APIs. The configuration is available in the publisher portal where you can also configure authentication via Facebook, Google or others:

20161004_01_security

After selecting the Azure Active Directory we have to enter cliend id, client secret and allowed tenants. There is also a “Redirect URL” which is the sign in URL for our AAD application that we will create:

20161004_02_security

So let’s copy the “Redirect URL” and let’s jump into the AAD configuration in the Azure portal. Go to “App registrations” and add a new application:

20161004_03_aadappregistration

The application must be a multi-tenant application. This can be configured in the “Properties”. If you don’t configure it as multi-tenant, users will end up in an endless sign-in loop when they try to log in.

20161004_04_multitenant

The required permissions for the app are “Read directory data” for the application and “Sign in and read user profile” as delegated permissions:

20161004_05_adpermissions

The final step is to create a client secret. Go to application configuration in AAD and to “Keys”. Create a new key and press “save”. After pressing save you’ll see the key:

20161004_06_adclientidsecret

Copy and paste Client Id and Client Secret into the API management configuration and set the allowed tenants. Those are all tenants that are allowed to access the API management. A tenant is for example “mytenant.onmicrosoft.com”:

20161004_07_apimgmtsecurityconfig

The next step is to sign in with the admin user. Sign in with a global admin user and accept the permission request. It is required to do it with an admin because the admin accepts the permission request for the whole company:

20161004_08_adminconsent

After that, the users in your AAD should be able to sign in, browse the APIs and subscribe to products. The first sign in also creates the managed application in the local directory. Clicking on the link (or navigating through “Enterprise Applications”) allows to configure if users from AAD must be assigned to the application or not (and of course to assign them):

20161004_11_managedapplication

If you want to globally restrict the access to the developer portal to only registered users, set the “Redirect anonymous users to sign-in page” flag in the identities tab. This setting is AAD independent:

20161004_09_restrictaccess

Error: AADSTS90093 – application requires permission

If you try to sign in with a non admin user, then you’ll probably receive the following error:
AADSTS90093: This application requires application permissions to another application. Consent for application permissions can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization’s administrators.

20161004_10_signinerror

This error occurs if the permissions (application and delegated permissions) for the application are insufficient. Check if you set the permissions for API management application to “Read directory data” and “Sign in and read user profile” as delegated permission.

If the error still occurs you probably faced a bug in Azure. This bug is described here: http://stackoverflow.com/questions/29791557/why-azure-ad-fails-to-login-non-admins-in-multi-tenant-scenario

To fix it, open a new incognito (private) window, go to your sign in page, click on “Sign in with Azure Active Directory”. At the following page, add the query string “&prompt=admin_consent” at the end of the URL, so it looks like: https://login.microsoftonline.com/common/oauth2/authorize?client_id={…}&prompt=admin_consent
Sign in with your global admin and accept the permission request. After that, try to sign in again with a non-admin user.

Policies in API Management

You maybe noticed that there are already some products available in the API management service. There is one unlimited service with no restrictions and a “Starter” product. The “Starter” product has a limitation of 5 calls per user per minute. What if we want to change the limit or create our own product? Then we need some knowledge about policies!

The policies are very well described in the Azure documentation (https://azure.microsoft.com/en-us/documentation/articles/api-management-howto-policies/). That’s why I’ll keep it short in that blog post. It’s just important to know what are policies and what to do with them.

Policies are a possibility to change the behavior of an API. They can be applied to the request (inbound), before the request goes to the backend (backend), the response (outbound) or if an error occurs (on-error). The available scopes are global, product, API and operation. Some samples for policies are:

  • Authenticate with basic http/client certificate
  • Check HTTP Header (e.g. for JWT Token validation)
  • Convert from JSON to XML and vice versa
  • Allow/configure CORS
  • Find and replace string in body
  • Forward requests to backend
  • Limit call rate per minute per user/subscription/key
  • Log to EventHub
  • Read/Write cache
  • Restrict access to some specific IPs
  • Return response
  • Send request to a service
  • Modify the response (body, header, …)

…and others. A full list is available at https://azure.microsoft.com/en-us/documentation/articles/api-management-policy-reference/

Let’s check the existing policies for our “Starter” product:

20161004_12_policies

We can see the following policy:

<inbound>
    <rate-limit calls="5" renewal-period="60" />
    <quota calls="100" renewal-period="604800" />
    <base />
</inbound>

So there is a limit of 5 calls per 60 seconds and a quota of 100 calls per week. The “base” element means that higher policies should be executed. In this case, the scope is “product” and the higher scope is “global”. So at first there is the rate limitation, then the quota limitation and none of the limits is violated, it executes the global policies.

What happens if the rate-limit is violated?

We can easily try that with a simple Powershell script:

$baseurl = "https://codehollowtestapi.azure-api.net/simpleapi/"
$ext = "api/Values"
$subscriptionKey = "{subscriptionKey}"
 
for ($i = 0;$i -lt 100; $i++) {
    Invoke-WebRequest -Uri ($baseurl + $ext) -Headers @{"Ocp-Apim-Subscription-Key"="$subscriptionKey"}
    Write-Progress -Activity "calling webservice..." -PercentComplete $i -Status "$i% complete"
}

The API returns 5 successful responses and after that it gives us status code 429 – “Rate limit is exceeded. Try again in 60 seconds”.

20161004_13_policyviolation

So that was a quick introduction to the API management. I plan to write additional blog posts about how to easily secure the “hidden” API in the background or how to re-import an API.

Additional information

Categories:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *

About
about armin

Armin Reiter
Blockchain/Web3, IT-Security & Azure
Vienna, Austria

Reiter ITS Logo

Cryptix Logo

Legal information