One of the common questions that customers often ask is how they can enforce centralized policies for their APIs on Azure. The requirements can be as simple as caching data to complex as Single Sign On (SSO). I laid out technical blueprint for a customer that required SSO integration for their APIs (especially the public ones that are exposed to vendors and third parties) using Azure API Management. This offered a simplified architecture and design for APIs, where API developers don’t need to worry about building the cross-cutting requirements like Authentication (and authorization) in their APIs. Before I proceed further, I would like to point to following diagram on the policy scopes supported by Azure API Management. It is important to note the levels and where the policy is getting implemented.
Ref: https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-policies
Here is what was proposed as solution:
At global policies level
The common URL logging, redirection (based on secured vs unsecured URL) and validations were done at this level.
At Product Level
Separate Products were defined for Common Authorization APIs, and specific API based on Business Units(BU) and divisions.
Overall Request flow
- The global policies kicked off as soon as the API Management URL was accessed to access an API.
- Global policies checked whether the authorization header is present or not (for secured Urls) and redirected it to Common Authorization API (if Auth header is invalid or not present), encoding the original URL request and passing it as request parameter (forward url).
- Common Authorization API, created a unique-id(UUID) for the request (will become clear in few steps) and stored the forward-url against the unique-id in the cache associated with the API Management.
- Calls the third party SSO with username-password (passed as request params, over secure HTTPS channel) and registered client credentials along with the unique-id.
- Upon failure, redirect to error url.
- Upon success, load the forward url from cache using the unique-id (this helped avoid the URL length limitations during SSO call).
- Set the Authorization header with the received token from the SSO call and redirect the request to the forward url.
- The product level policies will then trigger and do the product specific authorization based on the roles fetched from the authorization token.
In some cases, additional roles were coming from the product Database, those roles were fetched (and cached) at the product level and added to existing roles to perform API specific authorization.
The above flow can also be tweaked to store roles in cache if the SSO system is not being used to store roles or roles are stored in AD/AAD or database and third party SSO is being used for authentication purposes.
Overall the centralized policy enforcement point helped the customer as well as API developers to focus on building functional APIs rather than building different authentication/authorization solutions for their APIs or themselves integrating with SSO provider. The solution also ensured that SSO client credentials were accessed only in centralized APIs and not across applications thus substantially decreasing chances of credential leaks.
So what do you think of the solution?