Skip to main content

Exchanging SAML2 Bearer Tokens with OAuth2 in WSO2 API Cloud.


It's a common use case where enterprise applications that have SAML2 based SSO infrastructures sometimes need to consume OAuth-protected resources through APIs. However, these apps prefer to use the existing trust relationship with the IDP. Even if the OAuth authorization server is entirely different from the IDP. The API Cloud leverages this trust relationship by exchanging the SAML2.0 token to an OAuth token with the authorization server.

WSO2 API Cloud has an token API which is exposed to the users in order to create and renew user and application access tokens. The response of the Token API is a JSON message. You extract the token from the JSON and pass it with an HTTP Authorization header to access the API. In this example we will be using the SAML extension grant type to generate the tokens.

In this blog i will explain the steps on how you can successfully carry out the SAML to OAuth2 token exchange with the API Cloud. Let's take a look at how this can be achieved.

Pre requisite.

1. You need to make sure you have an account with the WSO2 Cloud. If you do not have an account then you first need to create one. You can find the steps here under 'How to create an Account with WSO2 Cloud'.

2. You also need to create a keystore and also the public certificate to sign the SAML tokens.

You also need to have a jks file which we will be using to sign the SAML tokens. You can find the command line command to create a jks file if you do not have one and also export its public certificate as shown below.

keytool -genkeypair -alias <alias> -keypass <name> -keysize 1024 -keystore <filename>.jks -storepass <storepass> -keyalg RSA
Now you will be having a jks file you can use to sign the SAML tokens. Next you need to create a public certificate which you need to add to API Cloud so they will trust these tokens. To get this file enter the below command. You can replace the word "shenavi" with anything you wish for your files 

keytool -exportcert -keystore shenavi.jks -alias shenavi -file shenavi.cert

Now that you have registered with the WSO2 Cloud and have a certificate we can start the required configurations on the API Cloud.

1. First Log into the API Cloud's management using the tenant aware user name. You can follow the link and find the steps how to log into the management console. 

2. After you log in you will be able to see in the Configure menu section a menu item named as 'Identity Providers'. Click on the 'Add' option. Then a configuration page will appear.


3. Specify a unique name for the identity provider. In my case i have named it according to my tenant name which is 'myDemoProvider'.

4.For the 'Identity Provider Public Certificate' field i will upload the public cert of my jks file i am using to sign the tokens with. (shenavi.cert).

5. Give the alias as "https://keymanager.api.cloud.wso2.com/oauth2/token"

6. Enable SAML2 Web SSO.

7. For the Service Provider Entity Id and the Identity Provider Entity Id I have specified as 'myDemo'. When generating the SAML token you need to use this as the entity id therefore depending on the entity id and service provider this value needs to change.

8. We need to specify the SSO url since it is a required field but we wont be needing this value so i will specify it as https://test.

9. Register the identity provider.


Now the API Manager end configurations are complete. Next we need to test if this scenario works as expected. For that we need a signed SAML token and also the client secret and client id from the API Cloud store of our tenant. Lets see how we can get these required items.

1. You can follow this blog and create a sample API with the API Cloud. After it is created you will be prompted with a message box where you need to select to 'go to the API store' option. Once you are in the API store go to the 'My Subscriptions' menu item. 

2. Click on the generate keys button where you will get the client id and secret.



3. Use this base64 encoder and encode the value in this format <consumer key:consumer secret>. Lets refer to this as the Authorization value.

4. In order to generate a SAML token you need to download this archive from here and extract it. Navigate inside that extracted folder and enter the below command in this format. You need to enter the same values you used when creating the jks file. This will create you with a signed SAML token.

java -jar SAML2AssertionCreator.jar <Identity_Provider_Entity_Id> <user_name> <recipient> <requested_audience> <Identity_Provider_JKS_file> <Identity_Provider_JKS_password> <Identity_Provider_certificate_alias> <private_key_password>

eg: java -jar SAML2AssertionCreator.jar myDemo shenavidemel.gmail.com@mydemo https://keymanager.api.cloud.wso2.com/oauth2/token https://keymanager.api.cloud.wso2.com/oauth2/token shenavi.jks test sample test

5. After you have received a SAML token we need to pass that value and call the token endpoint in order to get the OAuth2 token in exchange. You can use below command format to get this working.

curl -k -d "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=<Assertion_provided_by_client>&scope=PRODUCTION" -H "Authorization: Basic <Base64 encoded consumer key:consumer secret>, Content-Type: application/x-www-form-urlencoded" https://gateway.api.cloud.wso2.com/token?tenantDomain=<your_tenant_domain>

6. After executing this command you will be getting a access token similar to below.

{"scope":"default","token_type":"Bearer","expires_in":3600,"refresh_token":"99ffd146c6c76971bf012fc7","access_token":"70a2bfa0e3dc13b99d1a9fbab2"}

7. Now go back to the store's API console and invoke the API using this access token value for the Authorization.


You have successfully completed the token exchange from SAML to OAuth2. If you need any help or have any further questions please drop us an email at cloud@wso2.com where our Cloud team will be able to help you get it resolved.
References:

[1] http://shenavid.blogspot.com/2015/10/wso2-cloud-wso2-cloud-consists-of-two.html
[2] https://docs.wso2.com/display/APICloud/Token+API
[3] http://shenavid.blogspot.com/2015/10/creating-api-using-swagger.html
[4] https://docs.wso2.com/display/APICloud/Subscribe+to+and+Invoke+an+API
[5] https://docs.wso2.com/download/attachments/45944343/SAML2AssertionCreator.zip?version=1&modificationDate=1431389473000&api=v2
[6] https://docs.wso2.com/display/AM1100/Exchanging+SAML2+Bearer+Tokens+with+OAuth2+-+SAML+Extension+Grant+Type

Comments

Popular posts from this blog

Processing large payloads with the esb script mediator iteratively

Overview WSO2 ESB uses Rhino engine to execute JavaScripts. Rhino engine converts the script to a method inside a Java class. Therefore, when processing large JSON data volumes, the code length must be less than 65536 characters, since the Script mediator converts the payload into a Java object. However, you can use the following alternative options to process large JSON data volumes. The script mediator which is used in ESB is powered by the Rhino engine. Therefore, when processing large JSON data volumes, the code length must be less than 65536 characters which is a limitation in the script mediator being used in the esb versions less than 5.0.0. In ESB 5.0.0 there is a higher capability to process larger payloads using script mediator. In order to process such large payloads we can follow the below two approaches. 1. Replace the javascript tranformation logic using java code by writing a custom mediator. [1] 2. Break down the large payload and execute them as sections using

Exposing a SOAP service as a REST API

In this post i will be explaining how we can transform a SOAP based backend to receive requests in a restful manner through the WSO2 API Cloud. Steps. First log into the WSO2 Cloud and navigate to the API Cloud. In the API cloud select the option to add a new API. We will be creating an API to demonstrate an invocation to the backend soap service ws.cdyne.com/phoneverify/phoneverify.asmx?wsdl Give a name, context and version to the API and add a resource name with a GET Method. The resource name can be anything which you like since we will invoke the actual service usiing a custom sequence. Mention the URI template as indicated in the below screenshot. Next go to the implement tab. And select the endpoint type as HTTP/SOAP Endpoint and specify the endpoint as http://ws.cdyne.com/phoneverify/phoneverify.asmx. There is an important step we need to do here. We need to set the SOAP version for this request. In order to do that we need to select the advanced option for the e

Invoking external endpoints using the call mediator in wso2 api manager

Introduction In API Manager if you need to do any service chaining use cases the call mediator comes in handy. If you need to use the response received by invoking one endpoint and then use it to invoke another endpoint you can use the call mediator in API Manager. The call mediator behaves in a synchronous manner. Hence, mediation pauses after the service invocation and resumes from the next mediator in the sequence when the response is received. You can read more about the call mediator in the wso2 esb documentation [1] . In api manager 1.10.0 the call mediator works in the blocking mode. Prerequisite Before we can use the call mediator in API Manager 1.10.0 we need to make the following changes to some configs. We need to comment the jms transport sender in axis2_blocking_client.xml found in the location APIM_HOME/repository/conf/axis2. This will resolve the jms sender initialization issues.   <!--transportSender name="jms"                      class