User quota for login based API

pierre
New Member

I would like to add user quota to an existing REST API that I do not control.

This API has some login based authorization in which users first call a login API function with login/password which returns a token in JSON response. This token is then used in other API calls as Authorization header.

Is it possible to use Apigee as a reverse proxy to add quota based on login name for this existing API?

1 1 96
1 REPLY 1

yes.

The quota policy has an Identifier element. This specifies the discriminator for quota counts.

<Quota name="##" type='flexi'>
  <!--
      To rate limit requests by a particular party, 
      such as a particular client app, or a particular
      user, specify an identifier that uniquely
      identifies the party or entity on behalf of which
      you wish to collect counts. To rate limit 
      requests irrespective of any client or user, 
      omit the identifier.
  -->
  <!-- <Identifier ref='client_id' /> -->
  <Distributed>true</Distributed>
  <Synchronous>false</Synchronous>
  <Interval>1</Interval>
  <TimeUnit>minute</TimeUnit>
  <Allow count='3' countRef='variable_containing_count'/>
</Quota>

If you specify "user_name" or some other context variable that holds something unique for the user, then you will get per-user quota buckets.

How is the login + password sent in to Apigee Edge (and to the existing REST API)? Suppose it is in a JSON payload like this:

{
  "user" : "Alice", 
  "password" : "VerySecret!"
}

If that's the case, then you need to extract the username from that payload into a custom variable and then use THAT as the Quota identifier. You could do it with a jsonPath in AssignMessage/AssignVariable.

First, this:

<AssignMessage name='AM-Extract-Username'>
  <AssignVariable>
    <Name>json_path_1</Name>
    <Value>$.user</Value>
  </AssignVariable>
  <AssignVariable>
    <Name>extracted</Name>
    <Value>BADDBEEF</Value>
    <Template>{jsonPath(json_path_1,request.content)}</Template>
  </AssignVariable>
</AssignMessage>

Then use the "extracted" context variable in the quota policy as I showed above.

If the username/password is passed in a form parameter, like this:

user=Alice&password=VerySecret!

...then it's even easier. Just use the variable name "request.formparam.user" in the Quota for the Identifier.

Consider the failure modes. Suppose I am a malicious hacker, and I try to login as "Alice" repeatedly. Enforcing a quota will lock out the real Alice from logging in. this may be what you want.