简体   繁体   中英

Apigee - how to restrict resource in product via verb

I wish to restrict access to certain methods in my RESTful API. I am trying to do this via products for simplicity allowing access to the resource /athletes* but I don't see a way of any finer control ie I wish to only allow GET requests and not POST and DELETE. Is there a syntax for expressing this in the custom resource path section of a product or do I need to handle this via a conditional flow eg to check for the product name to see if they can access?

I do this with Scopes but I had to do one little kludge at the end. This assumes you're using at least client_credentials grants for access_tokens (VerifyAPIKey policy doesn't directly support Scopes).

First create an API Proxy for, say, /v1/content (base path /v1, path suffix /content). Then create two resources.

<Flows>
    <Flow name="Content Read">
        <Description/>
        <Request>
            <Step>
                <FaultRules/>
                <Name>RegEx-Check-Scope-READ-Content</Name>
            </Step>
        </Request>
        <Response />
        <Condition>(proxy.pathsuffix MatchesPath &quot;/content&quot;) and (request.verb = &quot;GET&quot;)</Condition>
    </Flow>
    <Flow name="Content Create">
        <Description/>
        <Request>
            <Step>
                <FaultRules/>
                <Name>RegEx-Check-Scope-POST-Content</Name>
            </Step>
        </Request>
        <Response />
        <Condition>(proxy.pathsuffix MatchesPath &quot;/content&quot;) and (request.verb = &quot;POST&quot;)</Condition>
    </Flow>

Then create a product with scopes for CONTENT-READ and CONTENT-WRITE something like this:

在此处输入图片说明

Now, you could either create a second product with only CONTENT-READ to restrict some apps to Read only or you could generate your access_token with scopes like this:

<OAuthV2 name="GenerateAccessTokenClient">
  <Operation>GenerateAccessToken</Operation>
  <ExpiresIn>3600000</ExpiresIn>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GrantType>request.formparam.grant_type</GrantType>
  <Scope>request.formparam.scope</Scope>
  <GenerateResponse/>
</OAuthV2>

Probably easier to enforce the App level using two products, but passing scopes also let the User is a 3-legged Oauth add restrictions. Regardless, when you generated the access_token the policy will create an Apigee variable called "scope" which will include the scopes you included when you generated the access_token. If you don't specify scopes when you generate the access_token you will get ALL scopes from the product included in the scopes variable like this:

 scope: CONTENT-READ CONTENT-WRITE

It's just one long string, separated by spaces. And there didn't seem to be an easy way to put this into the Condition for the flow, so I added a RegEx policy to check if the allowed scope is in the scope variable, like this:

<RegularExpressionProtection async="false" continueOnError="false" enabled="true" name="RegEx-Check-Scope-POST-Content">
    <DisplayName>RegEx Check Scope POST-Content</DisplayName>
    <FaultRules/>
    <Properties/>
    <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>>
    <Variable name="scope">
      <Pattern>^((?!CONTENT-WRITE).)*$</Pattern>
    </Variable>
    <Source>request</Source>
</RegularExpressionProtection>

Where the regex returns true if CONTENT-WRITE is not in the scope string. And if the regex returns true, then it raises a fault and stops processing so the App doesn't get to POST.

Let me know if that makes sense (it's a few steps...)

On the API proxies page (not the Product page), you can add resources. Therein, you can indicate the method (or request verb) you allow. This is the same as using conditions on your Flows based on the request verb. For instance, if you add <Condition>(request.verb = &quot;POST&quot;)</Condition> to your API flow in your bundle, that means that particular flow will execute only when your request verb is POST. All other verbs for the base path of that bundle will be ignored.

This way, you only allow specific request verbs for your API bundle.

If you're trying to have fine control of resource + verb using API Products, you can set the variable flow.resource.name within the API proxy code to be:

"/" + request.verb + "/" + proxy.pathsuffix

This will leave you with something like /GET/products/1234-567 . The variable flow.resource.name is the one that's validated against the API Resource Paths configured for the API products, when using the VerifyAPIKey policy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM