Monday, May 29, 2017

Configure Single Sign On (SSO) for a Web App Using WSO2 Identity Cloud and Consume APIs Published in WSO2 API Cloud Using JWT Bearer Grant Type

WSO2 Cloud provides comprehensive set of cloud solutions, This includes; Identity Cloud, API Cloud, Integration Cloud and Device Cloud. Identity Cloud provides security while API Cloud provides API Management solution (In near future identity Cloud is going to provide full set of IAM solutions, where at the moment (May 2017) it has only supports Single Sign On). In real world scenarios, application security and API security goes hand in hand where most of the time these web apps need to consume secured APIs.

In this post, we  are going to  look at how we can configure security for a web app with WSO2 Identity Cloud and that application needs to consume some OAuth protected APIs published in WSO2 API Cloud.

If you need to configure SSO for a application with WSO2 identity Cloud, you need to configure a service provider in Identity Cloud representing your application. Document https://docs.wso2.com/display/IdentityCloud/Tutorials explains the services provider configuration options in detail. If you are configuring SSO for a your own application (not a pre-defined app like Salesfoce, AWS etc), there are two main options provided, that you can select. Those are "Agent based SSO" and "Proxy based SSO". Post xxxxx explains what these two options are and when to choose which option, in detail.

Here, we are going to use Proxy based SSO option and configure SSO for a java web application. Once user is authenticated to access the application,   Identity Cloud sends a signed JSON Wen Token (JWT token) to the backend application. This JWT token can be used with JWT bearer grant type to get an access token from API Cloud to consume APIs publish there.

Before that, what is JWT bearer grant type;
JWT bearer grant type provides a way for client application to request an access token from OAuth server, using an existing proof of authentication in the form of a signed claims which was done by different Identity Provider. In our case, Identity Cloud is the JWT token provider while API Cloud is the one provide OAuth acess tokens.

Step 1: Configure Service Provider in Identity Cloud


i. Login to Identity Cloud admin portal : https://identity.cloud.wso2.com/admin
ii. Add New Application (Note: Select the "Proxy" as app type)





iii. Go to user-portal of tenant. (I'm using wso2org as the tenant, hence my user-portal is https://identity.cloud.wso2.com/user-portal/t/wso2org). This will list the application there and if you click on it, you can invoke it.  Note that application URL is not the real endpoint URL of application that used to invoke it. This is because, since we used "Proxy" option, Identity Cloud acts as a proxy for this app and gives a proxy URL (also called as gateway URL).




You need to block the direct app invocations using firewall rule or nginx rule to make sure, all users can access application only through Identity Gateway with the provided proxy URL. Following diagram explains what really happens there.





That's all we have to do to get SSO configured for your web application with Identity Cloud using proxy option. In summary, you login to Identity Cloud admin portal, register a new application (service provider) there by providing your web app endpoint url and provide a new url context to get gateway url constructed. Gateway do the SAML authentication part on behalf of application. 

Step 2 : Use JWT Token sends by Identity Cloud to backend and get a access token from API Cloud to invoke APIs


Backend web app needs to consume some APIs published in API Cloud. But the user authentication for web app happened from Identity Cloud, how can it get a access token from API Cloud ? We can use JWT Bearer Grant type for that, since Identity Cloud gives a JWT token after user authentication (for proxy type).

This JWT token should contains API Cloud as an audience, if it need to be consumed by API Cloud. 

i. Edit the service provider (application) which was registered in Identity Cloud and add API Cloud's key manager endpoint as an audience. 

Service provider configuring UI provided in Identity Cloud admin portal does not have option to add audiences for proxy type apps (which should be fixed in UI). Until that we need to login to the carbon management console of Identity Cloud and configure it.  
NOTE : Carbon mgt UIs of WSO2 Cloud are not exposed to everyone. You need to contact wso2 cloud support by filling form https://cloudmgt.cloud.wso2.com/cloudmgt/site/pages/contact-us.jag  to get carbon mgt UI access. 

In the Carbon UI, navigate to Main -> Service Providers -> List -> Click Edit of Service provider that you created.  Inbound Authentication configuration -> SAML -> Audience URLs  -> Add "https://keymanager.api.cloudstaging.wso2.com/oauth2/token" as audience and update the SP. Refer following image.




ii. Configure Identity Cloud as a trusted IdP in API Cloud.

API Cloud should trust Identity Cloud as a trusted IdP, if it needs to issue an access token using JWT token issued by Identity Cloud.  We need to login to Carbon UI of API Cloud's Key Manager and configure Identity Cloud as a trusted IdP. 
NOTE : You need to contact wso2 cloud support by filling form https://cloudmgt.cloud.wso2.com/cloudmgt/site/pages/contact-us.jag  to get carbon mgt UI access of API Cloud's Key Manager. 

Navigate to Main -> Identity Providers -> Add -> Give the IdP details and Save

Identity Provider Name : wso2.org/products/appm

Identity Provider Public Certificate : Need to upload your tenant's public certificate here. You can get this by login to the admin portal of Identity Cloud and Click on "Download IdP Metadata" option provided in application listing page. This metadata file contains public certificate as a one metadata. You can copy and save certificate into a separate file and upload here.

Refer following image for add IdP.



Following images shows how you can download tenant's public certificate from Identity Cloud to upload above.



Downloaded metadata file will looks something similar following. Copy the certificate into a separate file and upload.



We are done with all configurations.

Step 3 : How to read the value of JWT Token and use it to request access token from API Cloud ?


JWT Token is sent to the backend in the header of "X-JWT-Assertion". Backend application can read the value of this header to get the JWT token.

Following image shows a sample JWT token printed by backend application by reading "X-JWT-Assertion" header.



Then backend application can use this JWT token and call to API Cloud token endpoint to get an access token using JWT bearer grant type. Before that you can copy this JWT token and use curl or some other REST client and test it. 

curl -i -X POST -H "Authorization:Basic <YOUR_Base64Encoded(ConcumerKey:ClientSecreat)>" -k 
-d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<YOUR_JWT_TOKEN_HERE>' 
-H 'Content-Type: application/x-www-form-urlencoded' https://gateway.api.cloud.wso2.com:443/token

This should provide you a oauth access token from API Cloud.

That's it !

Reference to sample web application code: https://github.com/dinusha-dilrukshi/wso2-integration-scenarios
This sample web app contains whole scenario described in this post. Try it too.

No comments:

Post a Comment