2016/01/29
29 Jan, 2016

[Tutorial] How to Convert OAuth to SAML with WSO2 Identity Server Conversion API

  • Awanthika Senarath
  • Software Engineer - WSO2
Archived Content
This article is provided for historical perspective only, and may not reflect current conditions. Please refer to relevant product page for more up-to-date product information and resources.

Table of contents

  • Introduction
  • Architectural overview
    • Architecture diagram
  • How it works
    • WSO2 IS configurations
      • Installing the API into WSO2 IS
      • Generating an OAuth token from WSO2 IS
    • Invoking the API
  • Conclusion
  • Appendix
    • Sample SAML response

Introduction

This article assumes that you have an understanding of SAML and OAuth token types and their usage. The focus of this article is to provide you with a guide to use the OAuth to SAML conversion API, with the WSO2 Identity Server (WSO2 IS). This API works as an endpoint. When you invoke it with an OAuth token it will respond with the corresponding SAML token. It takes two mandatory inputs

  1. Valid OAuth token
  2. Issuer for the SAML token (this issuer needs to be a registered service provider in WSO2 IS)

Currently in WSO2 we cannot invoke WSO2 IS via a REST call with an OAuth token to obtain the corresponding SAML token for a particular user in a given issuer. This API caters to that need. The API takes the third optional input as encoding, which enables the user to get a base64 encoded SAML response as the output.


Architectural overview

This REST API calls the WSO2 IS internal endpoints to generate the SAML token for the issuer specified by the OAuth token in the request. First, it will validate the received OAuth token. If it's valid, the user will be retrieved from it using an inbuilt endpoint in WSO2 IS. It will then build the SAML assertion by using the issuer specified in the request for the retrieved user. This assertion will be signed by WSO2 IS.

While building the SAML assertion the API makes a call to the WSO2 IS user store to retrieve the claims configured for the particular service provider. In that method the remote custom claims for the service provider, if present, are retrieved. Otherwise, the local claims configured for that service provider are used. You can configure the claims that are retrieved here by following the steps in the ‘WSO2 IS configurations’ section below. The output of the API will consist of a SAML response - a SAML assertion wrapped in an XML wrapper, which contains a few additional elements. See a sample SAML response in the appendix.

Architecture diagram

Figure 1


How it works

This section gives you a step-by-step guide on how to invoke the API to test its functionality. Download WSO2 IS 5.0 here and install the service pack. Start it in your local machine.


WSO2 IS configurations

Installing the API into WSO2 IS

  1. Clone the source-code from here. Build it using Maven and put the .war file into <WSO2IS_HOME>/repository/components/deployment/server/webapps (you don’t have to restart the server, you will see the .war file being deployed in the Carbon logs).
  2. Create a service provider in WSO2 IS. You can follow this tutorial to see how to configure a service provider in WSO2 IS.
  3. In the view that follows, click on the “InBound Authentication Configuration” section.
  4. Select “OAuth/OpenID Connect Configuration” and select “Configure” to allow this service provider to issue OAuth tokens.

    Figure 2

  5. Complete it according to the following view:

    Figure 3

  6. Select “SAML2 WEB SSO Configuration” to register a SAML issuer for the service provider. We will register the ubiquitous “travelocity” sample issuer for this for the sake of simplicity.
  7. Complete the configuration according to the following view:

    Figure 4

  8. Optionally you can configure claims for the service provider as shown below. This will be shown in the SAML response you receive.

    Figure 5

  9. Create a sample OAuth token from WSO2 IS for which we would generate the SAML token via the API.

Generating an OAuth token from WSO2 IS

A cURL command can be used to generate an OAuth token for an existing service provider in the WSO2 IS, this uses an existing endpoint in the WSO2IS to generate OAuth tokens.

  1. Go to the “OAuth/OpenID Connect Configuration” section in the service provider configuration and select the following fields:

    Figure 6

  2. Create a string by using the first field: second field as shown below:

    zL_G7xLXff0qMSsD6kETVEtW1roa:3RbF09EMCbUQQ8MW4QfJcJJo3Wc

  3. Then get the base64 encoded string for this as shown below (encoded from: https://www.base64encode.org/):

    ekxfRzd4TFhmZjBxTVNzRDZrRVRWRXRXMXJvYTozUmJGMDlFTUNiVVFROE1XNFFmSmNKSm8zV2M=

  4. Using the encoded string, generate the OAuth token from WSO2 IS with the following cURL command:

    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://<IP of the IS server>:9443/oauth2/token

This OAuth token can be used to invoke the API. Make sure that your OAuth token is still valid (not expired) when you call the endpoint.


Invoking the API

You can invoke the API once deployed in the WSO2 IS with the following cURL commands:

  • for encoded SAML curl -vk -X POST https://localhost:9443/oauth2saml/token -d 'token=${OAuthToken}&issuer=${Issuer}&encoding=base64'
  • for plain xml SAML curl -vk -X POST https://localhost:9443/oauth2saml/token -d 'token=${OAuthToken}&issuer=${Issuer}'

In each case you would be able to see the generated SAML response as the output.


Conclusion

Conversion from SAML to OAuth and vice versa is a common requirement these days as enterprise solutions are migrating towards OAuth more and need compatibility with their legacy systems that uses SAML tokens for authentication purposes. The API discussed in this tutorial allows you to do this by obtaining a SAML token for an OAuth token that is sent to the WSO2 IS via a REST call.


Appendix

Sample SAML response

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="https://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685">
  <saml:Issuer>https://idp.example.com/metadata.php</saml:Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
  </samlp:Status>
  <saml:Assertion xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xs="https://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z">
    <saml:Issuer>https://idp.example.com/metadata.php</saml:Issuer>
    <saml:Subject>
      <saml:NameID SPNameQualifier="https://sp.example.com/demo1/metadata.php" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID>
      <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="https://sp.example.com/demo1/index.php?acs" InResponseTo="ONELOGIN_4fee3b046395c4e751011e97f8900b5273d56685"/>
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z">
      <saml:AudienceRestriction>
        <saml:Audience>https://sp.example.com/demo1/metadata.php</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93">
      <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
      </saml:AuthnContext>
    </saml:AuthnStatement>
    <saml:AttributeStatement>
      <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue>
      </saml:Attribute>
      <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">[email protected]</saml:AttributeValue>
      </saml:Attribute>
      <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
        <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue>
        <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue>
      </saml:Attribute>
    </saml:AttributeStatement>
  </saml:Assertion>
</samlp:Response>

Source: https://www.samltool.com/generic_sso_res.php

 

About Author

  • Awanthika Senarath
  • Software Engineer
  • WSO2