stop global level policy execution at operation level - azure

This is in context of Azure API Management (APIM) Azure service. New UI changes in azure has changed behaviour of policy executions I believe.
I have one policy for jwt-validate set at global level for all APIs.
Recently I had to add new API which doesn't need JWT validation but certificate authentication.
So in APIM I created new API, product and added certificate authentication policy at product level.
When I run my API then JWT policy is also firing. How can I stop it from executing in this case. I removed but it stopped global + product level policy.
I want stop execution of global policy but I want product level policy to execute.
Please advise.

I had the same situation where I needed a specific API to skip a global policy that I had setup for JWT validation. The way that I made it work was by removing the <base /> tag from my API policies.
Of course, this removed all of my global policies not only the JWT-validator. But this was fine for my particular case.

This is not controlled by UI at all and wouldn't have been subject of recent updates. Policy chain is controlled with tag in policies. At operation level tag invokes API policy, at API it invokes Product, at product - global. If you remove from policy document chain will be broken and base policy invocation will not happen. So if for certain product you do not want global policy be invoked for every call - just remove from product policy.

Related

Azure API Management, single API accept AAD or subscription key

Is it possible to have a single API in APIM that either accepts AAD token or subscription, based on what product it belongs to?
Default, this does not work, since unchecking "require subscription" on API-level will override setting product to require subscription.
So, I see two solutions.. create two APIs in APIM and place them in separate products (same backend), or write a custom policy. Is there a way to check context.Subscription.Key and match with the product subscriptions?
Should be possible by adding your API to two products:
One with subscription requirement enabled
Another without subscription requirement enabled, but with validate-jwt policy added at product level to require AAD token

deploying azure apim policy in prod during business hours

i wanted to apply some apim policy to do jwt validation for a specific url.
can i apply this policy during live hours ?
When we hit save in apim policy editor does it anyway will block incoming requests and error ?
please advise.
thanks !
From APIM service itself there would be no problems or downtime. Some seconds after you press save new policy will be enforced and new requests will be processed accordingly.
It's a separate question if the policy is configured correctly and if it will cause any service degradation (for example, some requests may result in 401 response because wrong claim is specified in validate-jwt). This is something you need to ensure yourself.
See about APIM support for revisions: https://learn.microsoft.com/en-us/azure/api-management/api-management-get-started-revise-api?tabs=azure-portal It may help you to test things safely in production.

Azure API Management - How to execute product policy when product does not require subscription?

I have a product published that does not requires a subscription. The 4 APIs that compose it also does not. How can I define policies on a product level?
Such policies seem to work only when both the APIs AND the product require subscription AND the request is made using the product subscription key.
Prerequisites:
API subscription switched off:
Product subscription switched off:
Product added to API:
Product has policies defined, example:
If above points are true, just call your API without Ocp-Apim-Subscription-Key header and APIM will automatically execute API and attached product policies. If you provide Ocp-Apim-Subscription-Key with correct value, like for example administrator subscription key, APIM will only execute API policies.
To reduce the frustration it is important to understand policy order execution. Read the whole article here but in short the order is:
Global scope
Product scope
API scope
Operation scope
One last thing, if non subscription product is attached to non subscription API and its policies are executed automatically, you may wonder what happens if we add second open product to the API? Policies from which product will be executed? Turns out, this is not possible (what makes sense). Attempting to add second open product will result in following error:

How can I implement user permissions on operations in Azure API Management?

I have created a .NET Core 2.0 API and published it to Azure. I have an API Management (APIM) instance fronting that API and doing all the wonderful things that it does. However, there is one thing I cannot seem to wrap my head around or find any documentation for. Authorization on operations. (Not to be confused with authentication, which I have working very well).
My API is a simple RESTful service with CRUD actions. Let's take a read operation for example:
GET /api/owner/{ownerid}/thing/{thingid}
In this case, what I want to be able to do is to grant users permissions to READ THINGS within a specific OWNER. The same user may not have read permissions with a different owner. If the user has permissions, 200 OK; otherwise, 403 Forbidden.
Leaving this completely carte blanche, what are some suggestions for implementing this? I assume an inbound policy for each operation within APIM is where the action will take place? If so, how?
Update 1
I was informed of the possibility of using the same validate-jwt policy at the individual operation levels to append to the validate-jwt policy at the root. The idea is that the root policy validates that the user is authenticated while the operation policy checks for specific claims. This appears to work well, but is that the correct method, or just a hack?
Update 2
For the validate-jwt option to work, the permission model would need to align well with roles and groups; otherwise, it's just as much work as setting up your own custom database wherein at least you benefit from your own rules. In the end, I put the permissions in an Azure Storage Account table (any database will do) and used a send-request (with appropriate caching) to gather permissions based on the current operation and user. It works well, but "feels wrong". I am happy to share details to anyone who wants. In the meantime, I'll leave this open for now in case someone has a better idea.
Ultimately the only way to do so is by using policies at operation level. you can use validate-jwt to check for specific claims, you can check some other credentials that are passed to you as a part of request. Or you can use send-request to call some other service and ask for user permissions. In APIM itself there is no place to store any user related data besides some basic info, thus it is required for such authorization information to come from outside of APIM.
In the end it appears that there is no built-in solution. Rolling your own permission model and then validating it yourself is the way to go.
However...
This can still be done in APIM. As I mentioned in my second update, I was able to make a custom solution work. The way it was done was to use an inbound policy at the "all operations" level to retrieve permissions. (A caching mechanism was used so as not to retrieve the permissions on every single call.) Then, each operation determines if the user has permission to that specific operation based on the parameters that were passed in. (That is also cached.)
The result is that the root API has no authentication or authorization built-in, but APIM does and the appropriate behavior is observed.
Still, the preference would be an RBAC approach. For example, imagine the individual operations being seen as services as in this role definition:
{
"Name": "{rolename}",
"Id": "{roleid}",
"IsCustom": true,
"Description": "{roledescription}",
"Actions": [
"GET {myapi}/owner/{ownerid}/*",
"POST {myapi}/owner/{ownerid}/*",
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/{subscriptionid}"
]
}
If that were possible, we could create roles, assign them to users/groups at the subscription level, then have the claims automatically passed to APIM where they can be evaluated like any other claim.

Azure B2C custom attribute/claim added to existing user directory throws error on sign in

I have a custom policy which adds a custom value, HoldingId, to new users who sign up (using these docs) as the value is passed to the policy via the token (along with verified_email).
I was hoping to not need to create a custom policy for sign in, so used the Azure Portal UI to create the custom attribute against the b2c-extensions-app application (and am using the respective client and object ids to line it up with the custom policy), and using the Portal have added this custom attribute to the sign up/sign in policy claims.
Using the Graph API, I have been able to successfully confirm that the custom value is saving against newly signed up users (returning as extension_[AppId]_HoldingId), and these new users are able to sign in subsequently without issue using the built in sign in/sign up policy.
However, any users which already existed in the directory are no longer able to sign in. Unfortunately, because it's a built-in policy, I'm not sure of a way to dig into the logs a-la App Insights to see what's going on.
My suspicion is that because these existing users don't have this custom attribute against them, the built-in sign up/sign in policy is attempting to get this value and failing.
Is it possible to get the built-in policies to ignore this attribute on users who don't have this attribute set, or will I need to create a custom policy to handle this scenario with a default value?
For context, the HoldingId is not required for existing users (application needs to be backwards compatible). This is also my first venture into B2C, so I'm still learning many of these concepts.

Resources