Showing posts with label APIM. Show all posts
Showing posts with label APIM. Show all posts

Tuesday, February 7, 2017

How to convert a json/xml payload in to a backend accepts form data payload in APIM

Imagine you have a scenario, where a user sens a json or xml payload via client eventhough the backend accepts only formdata. So you need to find a method to change the payload during the mediation without editing the API synapse configuration manualy.

E.g.,

{
"userid": "123abc",
"name": "Ushani",
"address ": "Colombo"
}
in to

userid=123sbc&name=ushani&address=Colombo


You can simply achieve this by adding a custom mediation extension in to in flow since the default available mediation extensions do not support it.

In order to do this you have change the Content Type in to  application/x-www-form-urlencoded.

Sample mediation extension :


<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="formdataconvert"> 
      <property name="messageType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING"/> 
   <log level="full"/>
</sequence>

How to perform an action based on a JWT claim value in APIM 2.0

To achieve this, We can use custom mediation extensions in APIM 2.0. For more details on Custom mediation, please have a look at this document [1].
When you write your custom sequence, below I have given the synapse source and explanation. In this example, we are going to do our action based on the claim value enduser as an example.

1. First we have set the X-JWT-Assertion header value in to a property named authheader.

 <property name="authheader" expression="get-property('transport','X-JWT-Assertion')" scope="default" type="STRING" description="get X-JWT-Assertion header"/>

Sample X-JWT-Assertion is as below :

X-JWT-Assertion = eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImFfamhOdXMyMUtWdW9GeDY1TG1rVzJPX2wxMCJ9.eyJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbnRpZXIiOiJVbmxpbWl0ZWQiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9rZXl0eXBlIjoiUFJPRFVDVElPTiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3ZlcnNpb24iOiIxLjAuMCIsImlzcyI6IndzbzIub3JnXC9wcm9kdWN0c1wvYW0iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbm5hbWUiOiJEZWZhdWx0QXBwbGljYXRpb24iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9lbmR1c2VyIjoiYWRtaW5AY2FyYm9uLnN1cGVyIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvZW5kdXNlclRlbmFudElkIjoiLTEyMzQiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9zdWJzY3JpYmVyIjoiYWRtaW4iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC90aWVyIjoiVW5saW1pdGVkIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBwbGljYXRpb25pZCI6IjEiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC91c2VydHlwZSI6IkFQUExJQ0FUSU9OIiwiZXhwIjoxNDg2NDU5NTg3LCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcGljb250ZXh0IjoiXC9qd3RkZWNhcGlcLzEuMC4wIn0=.FE2luGlWKZKZBVjsx7beA4WVlLFJSoHNGgJKm56maK7qddleEzTi/QhDAdyC47dW+RgkaJZLSgdvM6ROyW890io7QCOqjJZg7KnlB54qh2DBoBmAnYbmFZAC08nxnAGpeiy6W4YkYMWlJNW+lw5D3b3I4NOhyhsIStA9ec9TSQA=


2. Then we have used a script mediator to split and decode our value from the authheader.

        var temp_auth = mc.getProperty('authheader').trim();
                var val = new Array();
                val= temp_auth.split("\\.");

By the above javascript, we have split the value we get by "." I have highlighted it by Yellow color. 
Grean colored value has got our JWT claims.

3.  Then we access the 2nd value as val[1] and decode it using Base64.
                
                var auth=val[1];
            var jsonStr = Packages.java.lang.String(Packages.org.apache.axiom.om.util.Base64.decode(auth), "UTF-8");

If you decode the particular value using a base64, you wil be able to see the below value.

eyJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbnRpZXIiOiJVbmxpbWl0ZWQiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9rZXl0eXBlIjoiUFJPRFVDVElPTiIsImh0dHA6XC9cL3dzbzIub3JnXC9jbGFpbXNcL3ZlcnNpb24iOiIxLjAuMCIsImlzcyI6IndzbzIub3JnXC9wcm9kdWN0c1wvYW0iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcHBsaWNhdGlvbm5hbWUiOiJEZWZhdWx0QXBwbGljYXRpb24iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9lbmR1c2VyIjoiYWRtaW5AY2FyYm9uLnN1cGVyIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvZW5kdXNlclRlbmFudElkIjoiLTEyMzQiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9zdWJzY3JpYmVyIjoiYWRtaW4iLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC90aWVyIjoiVW5saW1pdGVkIiwiaHR0cDpcL1wvd3NvMi5vcmdcL2NsYWltc1wvYXBwbGljYXRpb25pZCI6IjEiLCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC91c2VydHlwZSI6IkFQUExJQ0FUSU9OIiwiZXhwIjoxNDg2NDU5NTg3LCJodHRwOlwvXC93c28yLm9yZ1wvY2xhaW1zXC9hcGljb250ZXh0IjoiXC9qd3RkZWNhcGlcLzEuMC4wIn0=

{"http:\/\/wso2.org\/claims\/applicationtier":"Unlimited",
"http:\/\/wso2.org\/claims\/keytype":"PRODUCTION",
"http:\/\/wso2.org\/claims\/version":"1.0.0",
"iss":"wso2.org\/products\/am",
"http:\/\/wso2.org\/claims\/applicationname":"DefaultApplication",
"http:\/\/wso2.org\/claims\/enduser":"admin@carbon.super",
"http:\/\/wso2.org\/claims\/enduserTenantId":"-1234",
"http:\/\/wso2.org\/claims\/subscriber":"admin",
"http:\/\/wso2.org\/claims\/tier":"Unlimited",
"http:\/\/wso2.org\/claims\/applicationid":"1",
"http:\/\/wso2.org\/claims\/usertype":"APPLICATION",
"exp":1486459587,
"http:\/\/wso2.org\/claims\/apicontext":"\/jwtapi\/1.0.0"}


4. Since we get the claims values with an escape character, we need to replace the "/" with a blank.

This is the actual value we get :  "http:\/\/wso2.org\/claims\/enduser":"admin@carbon.super",

Replace function :   jsonStr=jsonStr.replace("\\", "");

After Replace : "http://wso2.org/claims/enduser":"admin@carbon.super",

5. Then if we need to perform our acceptation and rejection based on enduser value as we have decided,  we should split the enduser value by the below claim. You can use any claim value from the above.

                        var tempStr = new Array();
                tempStr= jsonStr.split('http://wso2.org/claims/enduser\":\"');


6. We have split it in to 2 values. So the rest of the value after the enduser claim which is in tempStr[1], we split again to retrieve only the enduser value which is admin@carbon.super



Value needs to be split :

admin@carbon.super",


                var decoded = new Array();
                decoded = tempStr[1].split("\"");

7. To access the enduser value in our synapse level, we need to set the decoded enduser value in to message context as below by setting it as a property. I have set it as username.

setProperty(String key, Object value)
Set a custom (local) property with the given name on the message instance 
 
mc.setProperty("username",decoded[0]);

8. Then use a filter mediator to perform action based on the username. In here, I have logged a message if the username = admin@carbon.super and dropped the request if it is another user. For more information on Filter mediator, please have a look at this [2]

<?xml version="1.0" encoding="UTF-8"?> <filter source="get-property('username')" regex="admin@carbon.super"> <then> <log level="custom"> <property name="accept" value="Accept the message" /> </log> </then> <else> <drop /> </else> </filter>

9. I have uploaded my custom mediation extension via publisher as given in the below screen. You have to republish the API once you save it, if it is already published. 



So my complete mediation extension is as below :



<sequence xmlns="http://ws.apache.org/ns/synapse" name="JWTDec">
    <log level="custom">
      <property name="X-JWT-Assertion" expression="get-property('transport','X-JWT-Assertion')"/>
    </log>
  <property name="authheader" expression="get-property('transport','X-JWT-Assertion')" scope="default" type="STRING" description="get X-JWT-Assertion header"/>
            <script language="js" description="extract username">
  var temp_auth = mc.getProperty('authheader').trim();
                var val = new Array();
                val= temp_auth.split("\\.");
                var auth=val[1];
                var jsonStr = Packages.java.lang.String(Packages.org.apache.axiom.om.util.Base64.decode(auth), "UTF-8");
                jsonStr=jsonStr.replace("\\", "");
                var tempStr = new Array();
                tempStr= jsonStr.split('http://wso2.org/claims/enduser\":\"');
                var decoded = new Array();
                decoded = tempStr[1].split("\"");
  mc.setProperty("username",decoded[0]);
  </script>
   
         <log level="custom">
       <property name="username" expression="get-property('username')"/>
     </log> 

                <filter source="get-property('username')" regex="admin@carbon.super">
                     <then>
                    <log level="custom">
                      <property name="accept" value="Accept the message"/>
                    </log>
                 </then>
                 <else>
                   <drop/>
                 </else>
               </filter>

        
</sequence>


Sunday, January 29, 2017

How to send custom header in soap message when invoking an API in APIM 2.0 without using a client

Introduction :

WSO2 APIM has 2 methods of securing backend. Basic Auth and Digest Auth. So if the backend expects a security like WSSE security Username Authentication, there should be a method to apply security header. 

Possible method is to send the particular authentication credentials via a client. But it is clear that the secured backend credentials cannot be shared with API subscribers when they expose the backend via WSO2 APIM endpoint. So the best thing is to customize the soap message in this scenario in the middle of the mediation. 

This can be achieved via a mediation logic which can be done via a custom mediation handler or  mediation extension

If you do not want to restart the server, best thing is to use a mediation extension which you can also upload via UI, in WSO2 API Manager publisher. 

One more important thing is, configuring these credentials as you can easily change at anypoint.
This is achieved by adding them as a registry property


Below explains a sample Mediation extension written to achieve this.

The client user name and password are encapsulated in a WS-Security <wsse:UsernameToken>. When the Enterprise Gateway receives this token, it can perform one of the following tasks, depending on the requirements:

-Ensure that the timestamp on the token is still valid
-Authenticate the user name against a repository
-Authenticate the user name and password against a repository

The given extension is to enrich this soap request to achieve the 3rd task.

This extension is written to inject username token in the message mediation, when client invokes an API in APIM 2.0 which has a SOAP endpoint which is secured using WS-Security and requires User Name Token header to appear on the SOAP headers.

This is done using Enrich mediator and payload mediator. 
Enrich mediator is used to remove the existing soap header by copying the soap body.
Payload mediator constructs the soap header with username token tag and security header.
Username and password is taken from a registry resource property by an expression.


Pre-Requisites  :


1. Add username and password as properties in registry under resources _system/config/users

username : <username>
password : <password>


Steps : 

1. In this scenario API should be created as api with version 1.0.0 by admin user.

Mediation Extension named as : admin--api:v1.0.0--In



<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="admin--api:v1.0.0--In"> 
   <enrich>
      <source type="body" clone="true"/>
      <target type="property" property="ORIGINAL_BODY"/>
   </enrich> 
   <payloadFactory media-type="xml">
      <format>
         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                           xmlns:abc="http://localhost/testapi">
            <soapenv:Header>
               <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                              xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                              soapenv:mustUnderstand="1">
                  <wsse:UsernameToken>
                     <wsse:Username>$1</wsse:Username>
                     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">$2</wsse:Password>
                  </wsse:UsernameToken>
               </wsse:Security>
            </soapenv:Header>
            <soapenv:Body/>
         </soapenv:Envelope>
      </format>
           <args>
<arg expression="get-property('registry','conf:/users@username')"/>
<arg expression="get-property('registry','conf:/users@password')"/>
</args>
           </payloadFactory>
   <enrich>
      <source type="property" clone="true" property="ORIGINAL_BODY"/>
      <target type="body"/>
   </enrich>
   <log level="full"/>
</sequence>


2. Mediation extension is uploaded during the api creation in publisher in flow.

3. Invoke API endpoint with authorization bearer token provided by WSO2 APIM via SOAP UI.

Reference :

[1] https://docs.oracle.com/cd/E21455_01/common/tutorials/authn_ws_user.html
[2] http://geethwrites.blogspot.com/2014/01/wso2-esb-removing-full-soap-header.html
[3] http://isharapremadasa.blogspot.com/2014/08/wso2-esb-how-to-read-local-entries-and.html

Wednesday, June 1, 2016

Scenarios to Understand Subscription Tier Throttling in WSO2 API Manager 2.0


  • With the new throttling implementation, the subscription level tier quota will define the limit that particular application can access that API 

  • So basically the throttling tier policy is configured for subscription level tier by : appId + apiName + version. 
  • This can be defined as per request count or bandwidth. 
  • If application is used by 1000 users and subscribe to a 50000 Req/Min tier, then all the subscribed 1000 users can invoke maximum of 50000 Request per minute since it does not consider the user identification in subscription level tier policy.
  • With the previous throttling implementation any application user could access limit of 50000 Req/Min. 

  • When configuring Subscription level tier, Burst/rate limiting is also introduced to control the maximum requests that can be sent by a particular subscriber for a given period.
  • So if the burst limit is configured as 1000 Request/s, each user will be able to send only 1000 requests per second as maximum until it reaches 50000 requests for that minute.
  • If there are 10 application users using subscribed using 10 different applications, each user get 50000 requests with the limitation of sending burst requests 1000 per second.


Scenario 1 – Different users using same application using their user tokens


Throttle out an API by a subscription tier when few users from same tenant invoke a particular API subscribed via the same application when quota limit is 'request count' and when there is no burst limit


Preconditions:

1. API Manager should be up and running and user1 and user2 should be signed up with subscriber permission.
2. A subscription tier should be created as below.
  • Tier Name : Silver
  • Request Count : 2000
  • Unit Time : 1 minute
  • Burst Control (Rate Limiting) : 0
  • Stop on Quota Reach : Not selected
  • Billing Plan : Free or Commercial
  • Custom Attributes : None
  • Permissions : not defined
3. API 1 should have been been created and published as below by a publisher,
  • Subscription Tiers : Silver
  • GET resource level Tier : Unlimited is set
4. A developer subscribe to the API1
  • Application created with an Unlimited Tier. app1
  • Subscribe using application with Silver
5. Generate production keys for the particular application app1 and retrieve consumer key and secret.
6. User1 and User2 should generate their user tokens using the consumer key and secret generated in the above step.
User1 using app1 :

User1 Token = curl -k -d "grant_type=password&username=<Username>
&password=<Password>" -H "Authorization: Basic <app1_Token>" 
https://192.168.124.1:8243/token
 
 
User2 using app1 :

User2 Token = curl -k -d "grant_type=password&username=<Username>
&password=<Password>" -H "Authorization: Basic <app1_Token>" 
https://192.168.124.1:8243/token
 
 
Authorization: Basic <app1_token> =
<Base64encode(consumerkey:consumer secret of app1)>

Step Expected Result
User 1 and User 2 invoke the GET resource as below within a minute using their user token
  • User1 : 900 using user1 token
  • User2 : 1101 using user2 token
User who exceeds the 2000th request should be notified as throttled out.


Scenario 2 : Same user using different applications using their user tokens



Throttle out an API by a subscription tier when the same user invokes a particular API subscribed via different applications when quota limit is 'request count' and when there is no burst limit.



Preconditions:

1. API Manager should be up and running and user1 should be signed up with subscriber permission.
2. A subscription tier should be created as below.
  • Tier Name : Silver
  • Request Count : 2000
  • Unit Time : 1 minute
  • Burst Control (Rate Limiting) : 0
  • Stop on Quota Reach : Not selected
  • Billing Plan : Free or Commercial
  • Custom Attributes : None
  • Permissions : not defined
3. API 1 should have been been created and published as below by a publisher,
  • Subscription Tiers : Silver
  • GET resource level Tier : Unlimited is set
4. A developer subscribe to the API1 
  • 2 Applications created with an Unlimited Tier. app1 and app2
  • Subscribe API1 using applications (app1 and app2) with Silver
5. Generate production keys for the paticular applications app1 and app2 and retrieve consumer key and secret.
6. User1 should generate the user tokens using the consumer key and secret generated in the above step for both apps

User1 using app1 :

User1 Token1 = curl -k -d "grant_type=password&username=<Username>&password=<Password>"
 -H "Authorization: Basic <app1_Token>" https://192.168.124.1:8243/token
 
 
User1 using app2 :

User1 Token2 = curl -k -d "grant_type=password&username=<Username>&password=<Password>"
 -H "Authorization: Basic <app2_Token>" https://192.168.124.1:8243/token
 
 
Authorization: Basic <app1_token>
= <Base64encode(consumerkey:consumer secret of app1)>

Authorization: Basic <app2_token>
 = <Base64encode(consumerkey:consumer secret of app2)>


Step Expected Result
User 1 invoke the GET resource as below within a minute using
user token1 and token2

  • 900 requests using user1 token1
  • 1101 requests using user1 token2
User will be able to invoke successfully all the requests
User 1 invokes the GET resource as below within a minute using their user token1 and token2

  • 2000 using user1 token1 
  • 2001 using user1 token2
When user1 invokes the 2001st request using token2, will be notified as throttled out while other requests will be successful.



Scenario 3 : Different users via different applications using their user tokens


Throttle out an API by a subscription tier when few users from same tenant invoke a particular API subscribed via different applications when quota limit is request count and when there is no burst limit.

Preconditions:

1. API Manager should be up and running and user1 and user2 should be signed up with subscriber permission.
2. A subscription tier should be created as below.
  • Tier Name : Silver
  • Request Count : 2000
  • Unit Time : 1 minute
  • Burst Control (Rate Limiting) : 0
  • Stop on Quota Reach : Not selected
  • Billing Plan : Free or Commercial
  • Custom Attributes : None
  • Permissions : not defined
3. API 1 should have been been created and published as below by a publisher,
  • Subscription Tiers : Silver
  • GET resource level Tier : Unlimited is set
4. A developer subscribe to the API1
  • Application 1 and application 2 created with an Unlimited Tier. app1 and app2
  • Subscribe using applications with Silver
5. Generate production keys for the paticular applications app1 and app2 for 2 different users and retrieve consumer key and secret.
6. User1 and User2 should generate their user tokens using the consumer key and secret generated in the above step.

User 1 using app1 :

User token 1 = curl -k -d "grant_type=password&username=user1&password=user1" 
-H "Authorization: Basic <app1_Token>" https://192.168.124.1:8243/token
 
 
User 2 using app2 :

User token 2 = curl -k -d "grant_type=password&username=user2&password=user2" 
-H "Authorization: Basic <app2_Token>" https://192.168.124.1:8243/token


Authorization: Basic <app1_Token>
 = <Base64encode(consumerkey:consumer secret of app1)>

Authorization: Basic <app2_Token>
= <Base64encode(consumerkey:consumer secret of app2)>

Step Expected Result
User 1 and User 2 invoke the GET resource as below within a minute using their user token

  • User1 : 900 using user1 token 
  • User2 : 1101 using user2 token
Both users will be able to invoke successfully.
User 1 and User 2 invoke the GET resource as below within a minute using their user tokens

  • User1 : 2000 using user1 token 
  • User2 : 2000 using user2 token
Both users will be able to invoke successfully.
User 1 and User 2 invoke the GET resource as below within a minute using their user tokens

  • User1 : 2001 requests using user1 token 
  • User2 : 2001 requests using user2 token
Both users will be notified as throttled out.



Scenario 4 : Different users via same application using test access token


Throttle out an API by a subscription tier when few users from same tenant invoke a paticular API subscribed via the same application and test access token (grant_type = client credentials) when quota limit is 'request count' and when there is no burst limit



Preconditions :
1. API Manager should be up and running and user1 and user2 should be signed up with subscriber permission.
2. A subscription tier should be created as below.
  • Tier Name : Silver
  • Request Count : 2000
  • Unit Time : 1 minute
  • Burst Control (Rate Limiting) : 0
  • Stop on Quota Reach : Not selected
  • Billing Plan : Free or Commercial
  • Custom Attributes : None
  • Permissions : not defined
3. API 1 should have been been created and published as below by a publisher,
  • Subscription Tiers : Silver
  • GET resource level Tier : Unlimited is set
4. A developer subscribe to the API1 
  • Application created with an Unlimited Tier. app1
  • Subscribe using application with Silver
5. Generate production keys for the paticular application app1 and retrieve test access token.
6. Test access token can be retrieved via below command.

Developer generates an access token using app1 :

Test Access Token = curl -k -d "grant_type=client_credentials
-H "Authorization: Basic <app1_Token>" https://192.168.124.1:8243/token

Authorization: Basic <app1_token>
 = <Base64encode(consumerkey:consumer secret of app1)>

Step Expected Result
User 1 and User 2 invoke the GET resource as below within a minute using the same test access token generated

  • User1 : 900 requests using test access token 
  • User2 : 1100 requests using test access token
Both users will be able to invoke successfully.
User 1 and User 2 invoke the GET resource as below within a minute using the same test access token

  • User1 : 900 using test access token 
  • User2 : 1101 using test access token
User who exceeds the 2000th request should be notified as throttled out.

Scenario 5: Different users via same application via user token when the burst limit is configured


Throttle out an API by a subscription tier when few users from same tenant invoke a particular API subscribed via same applications when quota limit is request count and when there is a burst limit configured.

Preconditions :

1. API Manager should be up and running and user1 and user2 should be signed up with subscriber permission.
2. A subscription tier should be created as below.
  • Tier Name : Silver
  • Request Count : 2000
  • Unit Time : 1 hour
  • Burst Control (Rate Limiting) : 100 Request/m
  • Stop on Quota Reach : Not selected
  • Billing Plan : Free or Commercial
  • Custom Attributes : None
  • Permissions : not defined
3. API 1 should have been been created and published as below by a publisher,
  • Subscription Tiers : Silver
  • GET resource level Tier : Unlimited is set
4. A developer subscribe to the API1 
  • Application 1 created with an Unlimited Tier. app1
  • Subscribe using applications with Silver
5. Generate production keys for the particular applications app1 and app2 for 2 different users and retrieve consumer key and secret.
6. User1 and User2 should generate their user tokens using the consumer key and secret generated in the above step.

User 1 using app1 :

User token 1 = curl -k -d "grant_type=password&username=user1&password=user1" 
-H "Authorization: Basic <app1_Token>" https://192.168.124.1:8243/token
 
 
User 2 using app1 :

User token 2 = curl -k -d "grant_type=password&username=user2&password=user2" 
-H "Authorization: Basic <app1_Token>" https://192.168.124.1:8243/token

Authorization: Basic <app1_Token>
 = <Base64encode(consumerkey:consumer secret of app1)>

Step Expected Result
User1 invoke with 100 requests (a burst) within a minute using their user token User should be able to invoke successfully
User 1 try to send a request within the same minute in step 2. User1 will be notified as you have exceeded your quota until the next minute
User 2 invoke with 100 requests (a burst) within the same minute in step 2 using user2's user token. User 2 will be able to invoke successfully.
User 2 invokes again within the same minute in step 2 using user2's user token User should be notified as exceeded quota until the next minute.
User 1 and User 2 invoke the GET resource as below within an hour with below requests sticking to burst limit. (100 requests/m)

  • User1 : 1000 requests using user1 token 
  • User2 : 1001 requests using user2 token
User who exceeds the throttling limit by sending the 2001st request will be notified as throttled out until the next hour since it is configured as 2000 req/hr.

Until that all the requests will be successfully invoked sticking to the burst limit.

Monday, May 30, 2016

Difference in API and User Level Advance Resource throttling in WSO2 API Manager 2.0

From WSO2 API Manager 2.0 throttling implementation onward 2 different throttling levels have been introduced in Resource Level throttling.

When you login to admin dashboard you can see Advance resource throttling tier configurations under throttle policies section as given in the below screenshot.




When you add a resource tier, you can select either API or resource level as below.


API Level Resource Tier


For API level policy, it is the shared quota of all applications that invoke the API.
if someone selects API Level policy then selecting resource level policy will be disabled.

So as an example if there are 2 users subscribe to the same api, the request count or bandwidth  defined to the API is applicable for both users as a shared quota. So if you have defined 10000 requests per minute both users can share that amount.

User Level Resource Tier

For User level policy, it is the quota assigned to each application that will invoke the API.
So the quota is assigned for single user who can access the particular API from multiple applications. Simply when it's user level, throttle key will be associate with user name.

So as an example if you have selected user level, and when there are 2 users subscribed to the same API, the defined count in tier will be assigned to each user. So if you have defined 10000 requests per minute, both users get 10000 requests /1 minute per each as a total of 20000 requests.

Thursday, February 20, 2014

OAuth Authorization grant type behaviour with WSO2 API Manager (APIM)

For more information on OAUTH2 refer this presentation.

Authorization Grant types :

There are 4 Authorization grant types in OAuth.

How is this interpreted in APIM?

    * Authorization code
    * Implicit
    * Resource owner password credentials
    * Client credentials



(Resource :  WSO2 OAuth 2.0 The Path to Heaven from Hell presentation)


In the following types Resource owner does not grant the authorization.
    * Resource owner password credentials 
    * Client credentials

There for Step B and C (Authorization grant) will be omitted when there is a high degree of trust between client and resource owner. So the user will be able to receive the access token without the Authorization grant.

But Authorization grant is being used during the other 2 types which are,
  * Authorization code
  * Implicit.

If you use CURL or Advance rest cient, this step will not be visible since the authorization server must return a 302 redirection back to the client with an Location header pointing to the URL of user consent page. So you have to use an app which will return 302 redirection.

That is whay when we use a command like below, we just get the access token at once.

E.g.,

curl -v -k -X POST -H "Authorization: Basic MmdTYmc5NlBIc3hQcWZHT2lZWW1oSm9va2k4YTo0bEREM2M3TmNSWWZtaEZDZGlhVVdoQ3NEbE1h" -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -d "grant_type=password&username=admin&password=admin" http://localhost:8280/token/


This is explained in [1] and [2]

[1] http://charithaka.blogspot.com/2013/07/oauth-20-grant-types-with-wso2-api.html
[2] http://charithaka.blogspot.com/2013/07/oauth-20-grant-types-with-wso2-api_16.html