【问题标题】:Apigee - how to restrict resource in product via verbApigee - 如何通过动词限制产品中的资源
【发布时间】:2014-09-16 20:01:26
【问题描述】:

我希望限制对我的 RESTful API 中某些方法的访问。为了简单起见,我试图通过产品来做到这一点,允许访问资源 /athletes*,但我没有看到任何更好的控制方式,即我希望只允许 GET 请求而不是 POST 和 DELETE。是否有在产品的自定义资源路径部分中表达这一点的语法,或者我是否需要通过条件流来处理它,例如检查产品名称以查看他们是否可以访问?

【问题讨论】:

    标签: apigee


    【解决方案1】:

    我用 Scopes 来做这件事,但最后我不得不做一点小事。这假设您至少为 access_tokens 使用了 client_credentials 授权(VerifyAPIKey 策略不直接支持范围)。

    首先为 /v1/content(基本路径 /v1,路径后缀 /content)创建一个 API 代理。然后创建两个资源。

    <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>
    

    然后创建一个具有 CONTENT-READ 和 CONTENT-WRITE 范围的产品,如下所示:

    现在,您可以创建仅包含 CONTENT-READ 的第二个产品以将某些应用程序限制为只读,或者您可以生成具有如下范围的 access_token:

    <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>
    

    使用两个产品可能更容易实施应用级别,但传递范围也让用户是一个三足 Oauth 添加限制。无论如何,当您生成 access_token 时,策略将创建一个名为“范围”的 Apigee 变量,其中将包含您在生成 access_token 时包含的范围。如果您在生成 access_token 时未指定范围,您将从包含在范围变量中的产品中获取所有范围,如下所示:

     scope: CONTENT-READ CONTENT-WRITE
    

    它只是一个长字符串,用空格分隔。而且似乎没有一种简单的方法可以将其放入流的条件中,因此我添加了一个 RegEx 策略来检查允许的范围是否在范围变量中,如下所示:

    <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>
    

    如果 CONTENT-WRITE 不在范围字符串中,则正则表达式返回 true。如果正则表达式返回 true,那么它会引发错误并停止处理,因此应用程序不会进入 POST。

    让我知道这是否有意义(只需几个步骤...)

    【讨论】:

    • 事实证明,另一种选择是添加两个验证访问令牌策略 - 一个在条件流上,其范围填充到特定限制,另一个在 Preflow 上,以便您可以限制对全局策略和授权用户的访问获取配额值集(开发者 ID 和产品配额值)。
    【解决方案2】:

    在 API 代理页面(不是产品页面)上,您可以添加资源。其中,您可以指明您允许的方法(或请求动词)。这与基于请求动词在流程上使用条件相同。例如,如果您将&lt;Condition&gt;(request.verb = &amp;quot;POST&amp;quot;)&lt;/Condition&gt; 添加到您的捆绑包中的 API 流,这意味着 特定流将仅在您的请求动词为 POST 时执行。该包的基本路径的所有其他动词都将被忽略。

    这样,您的 API 包只允许特定的请求动词。

    【讨论】:

    • 你是说两个不同的产品引用了两个不同的 POST 和 GET api 代理,对吧 Alex?
    • 否,1 个产品和 1 个 API。如果 API 调用未根据请求谓词条件进入流,则不执行任何策略。这是 OP 的目标。
    【解决方案3】:

    如果您尝试使用 API 产品对资源 + 动词进行精细控制,您可以将 API 代理代码中的变量 flow.resource.name 设置为:

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

    这会给你留下像/GET/products/1234-567 这样的东西。变量 flow.resource.name 是在使用 VerifyAPIKey 策略时针对 API 产品配置的 API 资源路径进行验证的变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      相关资源
      最近更新 更多