OrganizationABC is an API provider who has published an API which is having two operations such as sales order creation & purchase order creation. Another two different organizations (CompanyA & CompanyB) will be consuming this API where CompanyA is responsible for posting sales order to backend application whereas CompanyB is responsible for post purchase order to the backend application. So, CompanyA shouldn’t have access to the resource /PurchaseOrderCreation and similarly, CompanyB shouldn’t have access to /SalesOrderCreation. In this blog, we will be discussing one of the custom approaches to achieve this feature in SAP API Management.
Similarly, I have created another application for CompanyB and defined the Scope as a custom attribute:
<!-- this policy can be used to retrieve all details of an entity(application, API Product, company, company developer, consumer key and developer) -->
<AccessEntity async="true" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<!-- the name of the type of entity to be retrieved -->
<EntityType value="app"/>
<!-- The value that identifies the specific entity whose profile should be retrieved. The ref attribute identifies the variable that provides the source of the identifier.
The type identifies the EntityType populated by the referenced variable -->
<EntityIdentifier ref="client_id" type="consumerkey"/>
<!-- used when EntityIdentifier is not gaurenteed unique -->
</AccessEntity>
<!-- Extract content from the request or response messages, including headers, URI paths, JSON/XML payloads, form parameters, and query parameters -->
<ExtractVariables async="true" continueOnError="false" enabled="true" xmlns='http://www.sap.com/apimgmt'>
<!-- the source variable which should be parsed -->
<Source>AccessEntity.ExtractAtributes</Source>
<!-- Specifies the XML-formatted message from which the value of the variable will be extracted -->
<XMLPayload>
<!-- Specifies variable to which the extracted value will be assigned -->
<Variable name="scope" type="string">
<!-- Specifies the XPath defined for the variable -->
<XPath>/App/Attributes/Attribute[2]/Value</XPath>
</Variable>
</XMLPayload>
</ExtractVariables>
Add a JavaScript policy at the PreFlow(Incoming Request) of ProxyEndpoint to frame a combination of <API proxy name>-<API method>-<Resource Name> during API proxy message processing runtime and check if that includes into the variable which we have set in the previous policy. Based on this check, we will be setting another variable named “GrantAccess” which contains the value as true/false. JavaScript is as below:
var GrantAccess = ""
var scope = context.getVariable('scope')
var proxypathsuffix = context.getVariable('proxy.pathsuffix')
var proxyverb = context.getVariable('request.verb')
var proxyname = context.getVariable('apiproxy.name')
var APIDetails = proxyname + "-" + proxyverb + "-" + proxypathsuffix
var GrantAccess = scope.includes(APIDetails)
context.setVariable('GrantAccess', GrantAccess);
Add Raise Fault policy at PreFlow(Incoming Request) of ProxyEndpoint to raise a custom response message in case the "GrantAccess" variable value is false. Policy content would be as below:
Condition String: GrantAccess = 'false'
<RaiseFault async="true" continueOnError="false" enabled="true" xmlns="http://www.sap.com/apimgmt">
<!-- Defines the response message returned to the requesting client -->
<FaultResponse>
<Set>
<Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
{
"successful": false,
"status": 500,
"error": "Restricted resource access",
"Response": "You don't have access to the API resource which you are trying to access. Please contact the system administrator to define the scope."
}
</Payload>
<StatusCode>500</StatusCode>
<ReasonPhrase>Undefined Scope</ReasonPhrase>
</Set>
</FaultResponse>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
Using the Client ID & Client Secret of CompanyB and trying to access “/SalesOrderCreation” API resource.
Expected Outcome: This should throw an exception as CompanyB is responsible only for purchase order creation.
Using the Client ID & Client Secret of CompanyA and trying to access “/PurchaseOrderCreation” API resource.
Expected Outcome: This should throw an exception as CompanyA is responsible only for sales order creation.
In summary, exploring "API Resource Level Access Restriction in SAP API Management" has provided us with valuable insights and a deeper understanding of its significance in our lives. As we move forward, let us take these lessons to heart and apply them in our everyday experiences. I appreciate you taking the time to read this blog, and I invite you to share your thoughts and reflections in the comments below. Together, we can continue to learn and grow.
Happy Learning!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
7 | |
6 | |
5 | |
5 | |
5 | |
4 | |
4 | |
4 | |
3 | |
3 |