[Article] How to Use OAuth 2.0 Scopes to Provide Role-Based Authorization to APIs Exposed via WSO2 API Manager
By Nadeesha Gamage
- 2 Dec, 2015
|WSO2 API Manager||1.9.1|
Modern organizations are moving towards an API-driven business model where it exposes many of its internal business capabilities to both internal and external users in the form of APIs. Many organizations started with publicly available business capabilities shared over APIs for consumption. As this quickly gained popularity, organizations looked at exposing more valuable information that is not always available freely as APIs. Many organizations see APIs as a way to improve its indirect revenue by delivering more services via APIs while others look at generating direct revenue from the exposed APIs. Given this landscape, securing APIs becomes extremely important to ensure only authorized users can access them. Access to APIs by unauthorized users can not only hurt revenue, but can also impact competitiveness and the long-term existence of an organization. Authorization becomes very complex as each API and its resources would have different access restrictions that need to be implemented. WSO2 API Manager provides the capability to secure APIs that are exposed through the API manager. It also enables capability to provide fine-grained access control to exposed APIs based on user roles. There are two separate ways of providing fine-grained access control:
- Using OAuth 2.0 scopes
- Integrating with a XACML entitlement server
In this article, we will discuss in detail how OAuth 2.0 scopes can be used to provide role-based authorization to APIs exposed via the API manager.
What are OAuth 2.0 Scopes?
OAuth 2.0 is the defacto standard for managing distributed web authorization. Authorization is done based on an access token that needs to be used to access a resource. This access token has a scope, which defines what the access token can do and what resources it can access. It can also include other parameters like the type of users that can access a resource.
How WSO2 API Manager Can Provide Role-Based Access to Exposed APIs
WSO2 API Manager provides the capability to enforce role-based access control to APIs that are exposed via the API manager. This capability is not limited to a given API; role-based access can be defined for resources within the APIs as well as the HTTP verbs that can be invoked in a given API. Let’s consider the following example -
You may have an API that needs to be exposed based on the requirements given below:
Based on the requirement, a single API should be exposed to add or retrieve student and staff information. Each member type (staff or student) is identified from the resource path. The operation (GET or POST) that needs to be performed is distinguished by the HTTP verb. Even though there are only two member types and two different operations that need to be performed on them, there will still be a different access requirements that are unique to each member and operation. These types of requirements need the implementation of a fine-grained access control mechanism. This mechanism should ensure that it provides an organization with maximum flexibility while making sure that unauthorized users are not allowed to access resources.
Let’s see how this scenario can be handled using the WSO2 API Manager. We will start by creating the required roles to access the API. For this, we will be using the internal user-store. If you want to use your existing user store you have the option of integrating with an external LDAP or a JDBC-based user store. You can follow the documentation in the following links   on creating a user and the required roles in WSO2 API Manager. Please create the following users and respective roles for these users. When creating roles in the API manager, you don’t have to define any permission as we don’t intend to use these credentials to login to the API manager.
After creating the users and the respective roles, let’s publish an API to the API manager. If you need information on getting started with WSO2 API Manager please refer to the following link . Let’s login to the API Publisher and start creating an API. Make sure that you provide URL patterns that reflect your actual backend API in the API definition section. The URL patterns should be created as shown below:
|HTTP Verb||URL Pattern|
Given below is a screenshot that shows how these URL patterns are created in the API manager.
Once you have added all the required information, go to the next step in the API creation process.
In this step, provide the backend URL of the production and the sandbox endpoints as given below (sandbox URL is not mandatory).
Once you have entered this information, go to the next step in the API creation process.
Select an applicable throttling tier along with the transports that need to be allowed for this API. Once this is done, you can move on to create scopes for this API. You can do this by clicking on the ‘Add scopes’ button available in the resources section as shown below.
Let’s add 4 scopes as given below:
|Scope Key||Scope Name||Roles||Description|
|Get_student||Get Student Info||staff,college_admin||Get Student information|
|Get_staff||Get Staff Info||Staff,student, college_admin||Get Staff information|
|Add_staff||Add Staff Info||college_admin||Add Staff information|
|Add_student||Add Student Info||college_admin||Add Student information|
Once the scopes are added, you can associate it to different HTTP verbs and resource paths; you can do this by selecting the ‘+Scope’ option available in-line with each resource path. Select the related scope from the dropdown that appears and click on the blue button to add the scope as shown below.
Add scopes to all 4 resource types and click on the ‘Save & Publish’ button to publish the API to the API Store.
The API is now available in the API Store and can be subscribed from the store. Let’s login to the API Store and subscribe to this API. In order to test this API you will need to generate an access token using an OAuth 2.0 grant type. A grant type other than ‘Client Credentials grant’ can be used for this (client credentials grant cannot be used as the token is issued for the application rather than the application user). For this, let’s use the password grant type. Let’s generate an access token using the following curl command. Make sure that you add the correct scope name to generate the token.
curl -k -d "grant_type=password&username=<USER>&password=<PASSWORD>&scope=<SCOPE_Name>" -H "Authorization: Basic <Base 64 encoded consumer_key:consumer_secret>, Content-Type: application/x-www-form-urlencoded" https://<IP>:8243/token
When the above curl command is executed you would receive an ‘Access Token’ and a ‘Refresh Token’ to access the resource. Use the ‘Access Token’ to invoke the API. You would be able to access only the permitted resources using a generated access token. For example, if you generate an access token by including the ‘Get_staff’ scope you will only be able to get staff information from the API.
The above scenario works well to access resources with the same scope. For example, all resources that have ‘Get_staff’ scope can be accessed using this token. However, when you need to access another resource that requires a different scope you will need to generate a new access token with this new scope. In order to avoid this, you can generate an access token for multiple scopes at the same time. Given below is the curl command for this.
curl -k -d "grant_type=password&username=<USER>&password=<PASSWORD>&scope=<SCOPE> <SCOPE>" -H "Authorization: Basic <Base 64 encoded consumer_key:consumer_secret>, Content-Type: application/x-www-form-urlencoded" https://<IP>:8243/token
As you could see multiple scopes can be provided with spaces as a delimiter to generate a token associated for all mentioned scopes. For example in the case of an ‘admin_user’, a token can be generated with Get_student, Get_staff, Add_student and Add_staff which gives him the privilege of performing all the operations associated to the above scopes using a single access token.
How All This Fits Into Your Application
OAuth 2.0 is mainly used to provide brokered authorization to resources where a resource owner provides authority for an application to access a given resource. WSO2 API Manager users the same mechanism to provide the capability for applications to access backend APIs using the same principles of OAuth 2.0. Here, the difference is that the user who’s accessing the resources is not the resource owner. Hence, the application only becomes a proxy for the user to access a given resource via the API manager. This flow can be depicted in the diagram below.
An application developer would subscribe to an API in the WSO2 API Manager. The developer would be provided with a consumer key and a consumer secret that needs to be embedded in the application to generate the required access token before invoking the backend service. This way, whenever a user needs to access an API, the application would use its consumer key and the consumer secret along with the scope and the user’s credentials to generate an access token. The API manager would allow applications to generate access tokens for any valid user. However, the API manager would validate the access token of each API invocation against the scope that it was issued to and whether the user has the authority to access that particular resource.
This article looked at how OAuth 2.0 scopes can be used to control access to APIs that are exposed via the API manager. APIs can be secured in a very fine grain manner where you will have control of the APIs, its resources, as well as which user can invoke what type of HTTP operation for a given API. This type of capability allows an organization to expose APIs more freely and ensure all users can benefit from the exposed APIs.