This article will give you an example on how you manage / restrict access to your API resources by verb and or the full basepath of the API.
Background:
To start this article off I would like to explain some of the common reasons for using this approach.
Common reasons to restrict by verb or base-path:
How It Works OOTB:
API Products currently look at a couple of things to validate if the request has access to a particular resource. Products then looks at the API Proxies that are associated and the API resource paths, these paths only compare the path suffix of the URI (everything after the base-path).
How to Extend OOTB Functionality:
There is a variable that if it exists it will be used instead of the proxy.pathsuffix to do the comparisons, that variable is flow.resource.name. So to extend the functionality we have to change the value of this variable before we validate our key or token.
Here is an example of some javascript to add both basepath and pathsuffix into the flow.resource.name variable
try{ context.setVariable('flow.resource.name','/'+ context.getVariable('request.verb')+ context.getVariable('proxy.basepath')+ context.getVariable('proxy.pathsuffix') ); }catch(e){ throw 'Error in Javascript'; }
And in our product we then can add Resources that look like this:
Or if you want to use wildcards you can do something that looks like this
Note: That you have to use a URL like format to make this work seamlessly
Extra Note: You can use multiple * wildcards but you can't mix * and ** wildcards
This is not a very RESTful design since you are including the Verb in the resource URL.
There ought to be a way to restrict/allow the Verb in the Product by resource URL.
The external path is still restful the /Verb is only adding to a variable which you are checking during the key or token validation
@Kurt Kanaskie Just to add to Steve's response:
GET /v1/restricted/basepath/resource2
would still be the request, we are just hacking the variable used to check to:
/GET/v1/restricted/basepath/resource2
No verb in the URL.
One thing to note is - this javascript (policy) should be attached in your bundle before your API Key Validation or Access Token Validation policy, for this to take effect.
Very interesting! @Carlos Eberhardt, I know you'll be interested to see this!
This seems to introduce an unintended vulnerability. It causes Verify-Api-Key policies to validate strictly against the product's resource path (ignoring the product's API proxies). This means I can have a developer app for an unrelated product (in the same org and environment) and as long as the unrelated product has a valid resource path (eg. /**), it will succeed the original Verify-Api-Key policy.
@Edward Yes, I am observing the same behavior. While this is a bug, as long as your resource paths are restrictive enough, then the API proxies of the Product become less important. The workaround would be to list every API proxy basepath as a resource path.
As a side note, there is also a missing check for the environment name. While there's a workaround for access tokens (i.e., check for the environment the access token was minted in against the environment for the resource call), there is no apparent solution for API key validation since there is only 1 call.