Granting different access tokens for each APIs in WSO2 APIM using OAuth2 Scopes

When you are using WSO2 APIM, application can subscribe for multiple APIs which are available in the API Store. End users can grant access tokens for the application. By default, these access tokens can be used to access all the APIs which are subscribed by the application. Simply, granted access token can be used to access any APIs by the application.

But, most of the scenario, end users needs to grant an API specific tokens. Say, there are two APIs in API store “/api/user/photos” and “api/user/claims”. Application has been subscribed for both two APIs. When end user is granted an access token , application can access both APIs.

So, how we can change this behavior ? How to generate API specific access token ?

By default, end user is granting an access token for default scope. It means that access token with default scope, can be used to access any API and there is no any scope based validations. If end user can grant an access token only for “/api/user/photos” API (“photos” scope) or “api/user/claims” API (“claims” scope), it would be great….
Let see how we can achieve this with small sample..
Step 1. Create “/api/user/photos” API and “api/user/claims” API using API publisher. In Manage selection, you can configure the scope values for API.
We are defining “photos” scope for the “/api/user/photos” API and attach it with POST and GET requests. Also, we are allowing to grant tokens for any user, “Internal/everyone” role has been selected. (There is no any role based access control here..)

api1

 

api2

 

api3

api4
Same as above, We are defining “claims” scope for the “/api/user/claims” API

api5

 

api6

Step 2. Create application in API store and subscribe both APIs for it.

 

Step 3. Granting an access token by defining the scope.

If end user is granting an access token for “/api/user/photos” API, application must send an OAuth2 request with “scope=photos”.

Here, i am using password grant type for granting access token, Sample curl command would be as follows.

 curl -k -u ClApUbWs6cIyzwpUMcJ_UorpmaUa:O1l2OKndPoeFhUOf4wxq3iClYEoa 
  -d "grant_type=password&username=asela&password=asela&scope=photos"
  -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

We can see the response as following

{"scope":"photos","token_type":"Bearer","expires_in":3300,
"refresh_token":"ad79c2788976bb53e78f88c3b509076",
"access_token":"3f77225fb0af550dca1fd3016186d7"}

 

If end user is granting an access token for “/api/user/claims” API, application must send a OAuth2 request with “scope=claims”.

Sample curl command

 curl -k -u ClApUbWs6cIyzwpUMcJ_UorpmaUa:O1l2OKndPoeFhUOf4wxq3iClYEoa 
   -d "grant_type=password&username=asela&password=asela&scope=claims" 
   -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

We can see the response as following

{"scope":"claims","token_type":"Bearer","expires_in":3300,
"refresh_token":"804a816b96e9eddd39b4a666cdbe5b48",
"access_token":"5a3196304ab9ff115faaf9c6a808f54"}

 

Step 4 (Optional). Lets grant an access token with default scope as well..
Sample curl command

curl -k -u ClApUbWs6cIyzwpUMcJ_UorpmaUa:O1l2OKndPoeFhUOf4wxq3iClYEoa 
   -d "grant_type=password&username=asela&password=asela" 
   -H "Content-Type: application/x-www-form-urlencoded" https://localhost:8243/token

You can see the response as following

{"scope":"default","token_type":"Bearer","expires_in":3299,
"refresh_token":"21579ec487b546e17faeb71c983215",
"access_token":"617ff96dd658ecd67a696dee5816c47"}

Step 5. Call APIs using access tokens

Now we can have three access tokens…

3f77225fb0af550dca1fd3016186d7 for scope “photos”   (/api/user/photos/  API)

5a3196304ab9ff115faaf9c6a808f54 for scope “claims”    (/api/user/claims/  API)

617ff96dd658ecd67a696dee5816c47 for default scope.
1. Call “/api/user/photos” with access token 3f77225fb0af550dca1fd3016186d7

Curl command

curl -k -H "Authorization :Bearer 3f77225fb0af550dca1fd3016186d7" http://localhost:8280/api/user/photos/1.0.0

Response would be  success.
2. Call “/api/user/photos” with access token 5a3196304ab9ff115faaf9c6a808f54

Error response as this access token is not granted to access above API.

<ams:fault xmlns:ams="http://wso2.org/apimanager/security">
<ams:code>900910</ams:code>
<ams:message>The access token does not allow you to access the requested resource</ams:message>
<ams:description>Access failure for API: /api/user/photos, version: 1.0.0 with key: 5a3196304ab9ff115faaf9c6a808f54</ams:description>
</ams:fault>

3. Call “/api/user/photos” with access token 617ff96dd658ecd67a696dee5816c47

Error response as this access token is not granted to access above API.

<ams:fault xmlns:ams="http://wso2.org/apimanager/security">
<ams:code>900910</ams:code>
<ams:message>The access token does not allow you to access the requested resource</ams:message>
<ams:description>Access failure for API: /api/user/photos, version: 1.0.0 with key: 617ff96dd658ecd67a696dee5816c47</ams:description>
</ams:fault>

4. Call “/api/user/claims” with access token 3f77225fb0af550dca1fd3016186d7

Error response as this access token is not granted to access above API.

5. Call “/api/user/claims” with access token 5a3196304ab9ff115faaf9c6a808f54

Response would be  success.

6. Call “/api/user/claims” with access token 617ff96dd658ecd67a696dee5816c47

Error response as this access token is not granted to access above API.

 

Thanks for reading…..!!!

Discuss this article on Stack Overflow

Leave a Reply

Your email address will not be published. Required fields are marked *