Invoking APIs using a Web App with OAuth2 and use of JWT - WSO2 API Manager
In this post I am to share my experience and understandings using WSO2 API Manager(API-M) for a very common and useful scenario in the industry.
In brief following is the flow.
An API is exposed for app developers to be used under the control of API Manager (which adds access control for the API). Then app developers make their apps consuming those APIs. After development and testing is completed they make it available for end users at App store. The end users can then get registered in the store and use the apps with own credentials. The app will provide the desired services calling the APIs it has subscribed to.
The above scenario is well demonstrated in WSO2 API-M with the pizza shack example explained in the documentation at [1].
For clarity I will be including the steps in brief. For detailed steps we can refer documentation at [1].
API Developer Role
- We deploy the back-end services related to 'pizza ordering' in WSO2-Application server or any other desired application server. (Download the code from API-M samples svn, build using Maven3 and deploy it in WSO2 AS. If we check the WADL, we can check the resources it exposes. Note the endpoint URL.)
- Then we publishes these services as APIs in WSO2 API-M Publisher, so that they will be available in API-M Store (Login to API-M Publisher, in default pack https://localhost:9443/publisher and publish the APIs as guided in the sample doc. We should make sure the production endpoint URL matches with what we observed in the first step).
App Developer Role
- Now here comes an App developer who wish to develop an App to order Pizza. He/she can register this App in store and get subscribed to these APIs that are required for development of application. So this APP developer will be consuming the services exposed by the APIs published by the previous developer. The code for the pizza ordering sample web app can be downloaded from svn as well.
- At subscription he/she gets consumer secret and consumer key which are then used to request OAuth tokens to access the APIs (In this example we use user name and password which is required in grant type 'password'. There are several other possible grant types as well, if we don't want to send password).
- Developer embeds the consumer key and consumer secret into the Pizza ordering application (In most of the cases in web.xml).
<context-param> <param-name>consumerKey</param-name> <param-value>FyfSK4RNHqGETmnNkaI87hIoNFQa</param-value> </context-param> <context-param> <param-name>consumerSecret</param-name> <param-value>1NFr7jb8JBA3IFa6gkjoN_PoYAca</param-value> </context-param>
At this point we can check how the token works with a simple curl command as follows. Provide the access token taken from above UI.
curl -k -H "Authorization: Bearer <access_token>" https://localhost:8245/pizzashack/menu/1.0.0
which will return the menu details for pizza orering as follows,
[{"price":"13.99","icon":"/images/6.png","description":"Grilled white chicken, hickory-smoked bacon and fresh sliced onions in barbeque sauce","name":"BBQ Chicken Bacon"},{"price":"24.99","icon":"......................:"/images/5.png","description":"Rich and creamy blend of spinach and garlic Parmesan with Alfredo sauce","name":"Spinach Alfredo"},{"price":"15.99","icon":"/images/4.png","description":"Six cheese blend of mozzarella, Parmesan, Romano, Asiago and Fontina","name":"Tuscan Six Cheese"}]
Since we have already seen the access token we can use it here. But when an end user comes and tries to order pizzas he/she is not seen these. Also this token is related with USER_TYPE: APPLICATION which has more privileges than an end user, so we can't anyway let the user use it. So what is happening underneath is generating a separate token for end users, using the embedded consumer key/secret and end user entered credentials(if password grant type is used) which will be related with USER_TYPE: APPLICATION_USER.
End User
So here comes the end user who get registered in the App Store.
Then end users can use the application to order pizzas online, entering their credentials in the application at http://localhost/pizzashack.
The API-M sitting in the middle act as the Authorization server in the scenario, managing the usage of the exposed APIs.
So where does the JWT assertion comes into play?
JWT assertion is a format used to send the details of the end user who invoked the API. Just as a SAML assertion would carry user claims JWT also carries user claims in JSON notation. We can find more details on this at [2]. This is used to pass those details to the back-end service which might require them for monitoring or some other purpose. The default JWT token will be as follows.
{ "iss":"wso2.org/products/am", "exp":1391029971429, "http://wso2.org/claims/subscriber":"admin", "http://wso2.org/claims/applicationid":"1", "http://wso2.org/claims/applicationname":"DefaultApplication", "http://wso2.org/claims/applicationtier":"Unlimited", "http://wso2.org/claims/apicontext":"/pizzashack/menu", "http://wso2.org/claims/version":"1.0.0", "http://wso2.org/claims/tier":"Bronze", "http://wso2.org/claims/keytype":"PRODUCTION", "http://wso2.org/claims/usertype":"APPLICATION", "http://wso2.org/claims/enduser":"admin", "http://wso2.org/claims/enduserTenantId":"-1234" }
Cheers!
Ref: