API Connect version 5.x offers a feature to define an OAuth provider API that can be used to secure one or more APIs. This blog explains the sequential steps that can be followed to define an OAuth provider API and secure your APIs.

Set Up required for this exercise

  • IBM API Connect v5.x or later

First things first, what are we doing? Well, let’s list out what we need to do.

  1. Create the OAuth Provider API
    • We will use the public client type and the password grant type.
    • We will use the following authentication URL: https://httpbin.org/basic-auth/user/passwd (where username = user, password = passwd)
  2. Create an invoke API definition
    • We will define the base path as /api1
    • We will define a path named /users which will proxy to http://jsonplaceholder.typicode.com/users
  3. Create the Product which will contain both the OAuth Provider API and invoke API
  4. Publish the Product
  5. Create the developer application.
  6. Subscribe the developer application to the Product/Plan
  7. Invoke CuRL commands to perform the test

Let’s begin with the first thing on our list and that is to create the OAuth Provider API.

To create the OAuth API, follow these steps:

  1. Go to Drafts -> APIs
  2. Click on (+) Add and select OAuth 2.0 Provider API
  3. Under title type Public OAuth API, click add
  4. Fill out the following fields:
    • Base Path: Base Path: /public
    • Scopes (what invoke APIs we are securing)
      • Scope Name: /api1
      • Description: api1 using OAuth Password
    • Grants
      • Password
    • Authentication URL
      • example: https://httpbin.org/basic-auth/user/passwd
  5. Click save

That takes care of the OAuth Provider API. The next thing we need to do is create the invoke API that needs to be secured

Follow these steps:

  1. Go to Drafts -> APIs
  2. Click on (+) Add and select `API`
  3. Under title type `API1` and click add
  4. Fill in the following fields:
    • Base Path
      • Base Path: /api1
  5. Under Security Definitions, click the (+) sign, select OAuth, and fill in the following fields:
    • Name
      • public-oauth
    • Description
      • public oauth provider API
    • Flow
      • password
    • Token URL
      • https://$(catalog.host)/{Org Name}/{Catalog Name}/public/oauth2/token
        • e.g https://$(catalog.host)/tenantzero/sb/public/oauth2/token
  6. Under Security, toggle the public-oauth security definitions
  7. Under Paths, click the (+) sign, change the GET /path-1 to /users
  8. Click Assemble on the nav bar and select invoke
  9. Change the URL to http://jsonplaceholder.typicode.com/users
  10. Click Save

 

That should take care of the invoke API. Now, let’s create product that would contain both the invoke API and OAuth Provider API, publish it, subscribe to it, and then we will test it.

To create the Plan and publish, follow these steps:

  1. Go to Drafts -> Products.
  2. Click on (+) Add and select New Product
  3. Under title, type My Product 1
  4. Now, under APIs, click on the (+) sign and add the following APIs:
    •  Public OAuth API
    • API1
    • Click save.
  5. Stage the product to the Sandbox catalog
  6. Go to Dashboard -> Sandbox
  7. Under products, find My Product 1
  8. Click on and select publish
  9. Select publish (again)

 

Awesome! We are almost there. We still need to do one more thing before we can test.

We need to create the developer application  and subscribe that application to the My Product 1 default plan.

To do that, navigate to the portal, log in, and do the following:

  1. Click on Apps -> Register New Application
  2. Fill out the following fields:
    1. Title: My App 1
    2. Description: My Awesome Application!
    3. OAuth Redirect URI: https://localhost
  3. Take note of the client ID for our test later.
  4. Click on API Products -> My Product 1
  5. Subscribe

 

I think we are in good shape. Before we go into testing let’s highlight what we did.

  1. Created a public OAuth Provider API with a base path of /public whose grant type is password.
  2. Secured the API (/api1) with our created OAuth Provider API.
  3. Created a product containing both the OAuth Provider API and simple API and published it.
  4. Registered a developer application and subscribed it to the My Product 1` plan.

 

Now here comes the fun part.  In order to test our current OAuth setup (public, password), we need to do the following:

  1. Retrieve the access token via POST to the oauth /token endpoint.
  2. Using the access token, invoke the API GET /users endpoint.

Those two steps we will do so using CuRL commands. Got it?

 

 

Alright, let’s get the access token.   Run the following CuRL, substituting all values where <field-name> is shown.

curl -v -k -X POST -d ‘grant_type=password&scope=<secured-api-base-path->&username=<username>&password=<password>&client_id=<application-client-id>’ ‘https://<gateway-host>/<org>/<catalog>/public/oauth2/token

  • <secured-api-base-path-> : base path of the API we secured with OAuth, in this case it’s API1’s basepath /api1
  • <username> & <password> : this is the username and password for the Auth URL (https://httpbin.org/basic-auth/user/passwd) … it’s user/passwd
  • <application-client-id> : this is the client ID we got for registering our application (e.g:  f4d70ea2-00a5-4e30-bbb5-f0f2b515106b)
  • <gateway-host>, <org>, <catalog> : if you don’t have this information, you can go the catalog where you published you product -> settings -> endpoints and look for API endpoint.

Once you run that command, what you will get back is the access token, like so:

{ “token_type”:”bearer”, “access_token”:”AAEkZjRkNzBlYTItMDBhNS00ZTMwLWJiYjUtZjBmMmI1MTUxMDZiGofy90h_po5Y22y8PheTMLnCAGGMaYtAMD_k9L9h63Xijrq5WWvB5y1hvkGsuUIdGX2PffPWqAOYZw7apZqDfA”, “expires_in”:3600, “scope”:”/api1″, “refresh_token”:”AAG29K-OkFu3fPQ4w9vPcyMbIDj23kk3_r-BYrsWhOr_6QGt5-y8P0CcJ9rQEcA2zkLHu64lLFA6Wl9AwIRouQoeK6CwU49YF1fexH22c0lizA” }

Above is the access token, which will give us the authorization to invoke the  API.  What we need to do next is run our second CuRL command, again substituting all the values where <field-name> is shown:

curl -k -v -H “X-IBM-Client-Id: <client-id>” -H “Authorization: Bearer <access-token>” -X GET ‘https://<gateway-host>/<org>/<catalog>/api1/users’

  • <application-client-id> : similar to above this is the client ID we got for registering our application (e.g:  f4d70ea2-00a5-4e30-bbb5-f0f2b515106b)
  • <access-token> : the access token value
  • <gateway-host>, <org>, <catalog> : again, same as our last CuRL.

Tada! What you should see is the same output from this URL -> http://jsonplaceholder.typicode.com/users.

 

This blog post was written by both Mark Miranda and Sharath Srinivas.

12 comments on"Creating and Securing an API with an OAuth Provider API"

  1. Hi Mark, Thanks for this very informative article. I have been looking for ways to create Oauth provider that uses external authentication. However, when I am trying to create the Public Oauth provider as descibed in your step 1, I keep getting the error “client_id unauthorized”. I have correctly subscribed to this API and using the APP client id.
    I am using POSTMAN to test my API.
    I have tried passing client_id as query string or has header paramater and even tried disabling client id from security defination. But still keep getting …
    {
    “error”: “invalid_client”,
    “error_description”: “client_id unauthorized”
    }

    What could be the reason?

    • Ok, I was able to make it work. To fetch the token, I had to post the data as FormData while I was posting as header. It all works as explained now. Thanks again for this excellent article.

      • Great! glad you got it working and you’re welcome. =)

      • Hi,I face the same issue when I try get accessToken I get client_id unauthorized.I send the client_id,client_secret and grant type as formdata in the below format
        grant_type=”client_credentials”&client_id=”710e1f24-ee87-4f6f-9ab6-857d37330353″&client_secret=”H2vA1uC5bM0kN2gR3hH2fP1yW0qO6gQ5qG0mT3eE1gY0kH0oT6″

  2. I have a followup question. This https://httpbin.org/basic-auth/user/passwd is protected via basic authentication. However, in our case our URL is protected via oAuth 2.0. What changes should I make in step 1 in this case?

    Also http://jsonplaceholder.typicode.com/users is already publically accesible. How should we ensure that in real life scenario our actual API should be protected and only be accessible by API Connect proxy?

    • curl -v -k -X POST -d ‘grant_type=password&scope=&username=&password=&client_id=’ ‘https://///public/oauth2/token -H -H ‘Authorization: Bearer ‘

      I’ve not tried an example where my oAuth authentication URL is secured with oAuth 2.0, but my guess is that is how it would be done.

      As for your second question regarding securing the API. You could secure the API we are proxying to with basic authentication. And in the invoke policy, you could specify the username and password.

      Here’s more information from the IBM knowledge center regarding the invoke policy we are using in our oAuth example.

      http://www.ibm.com/support/knowledgecenter/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/rapim_cli_policies_invoke.html

  3. I’m thinking of using API Connect to front an app running on OpenWhisk. With OAuth2 implemented in API Connect (as described above), I’m assuming that the access_token will get to my code with every invocation. However, the token cannot be trusted without validation. How do I do that?

    For example:
    Client — invokes /oauth2/token and gets the access_token
    Client — invokes /myapp/foo hosted on APIC with the access_token
    APIC — invokes the /foo end point running on OpenWhisk
    OpenWhisk — the end point /foo needs to validate the access_token

  4. In this example, you left Identity Extraction set to ‘Default Form’ When I try this example, I get back the default form and not a token.

    • That’s interesting …

      Identity Extraction set to `Default Form` should not have affected our example above. You got form back from running the curl command?

      curl -v -k -X POST -d ‘grant_type=password&scope=&username=&password=&client_id=’ ‘https://///public/oauth2/token

  5. Can I integrate API Connect with external oAuth provider ? like Azure AD?

  6. KavithaTalamanchi May 09, 2017

    Hi ,
    We are trying to integrate IBM API Connect with external OAuth Provider , Azure AD. Does API Connect support this feature ?
    If yes could you please point me to configuration steps ? Also How to configure API connect to validate access token provided by Azure.

Join The Discussion

Your email address will not be published. Required fields are marked *