Securing APIs using OAuth in API Connect – Video Tutorial

Share this:

Securing APIs using OAuth in APIConnect

Hi, I’m Krithika Prakash – SaaS Security architect at IBM APIConnect & Gateways product development team. As requested by many customers, some of whom I had the pleasure of meeting at IBM InterConnect conference recently, I’m making this video series on OAuth and APIConnect. The goal of this video is to get a basic working setup of OAuth provider API and test all possible grant types and client types using Postman application. Let’s get started.

System requirements

I have done this tutorial on Bluemix APIConnect Service at the time of APIC version 5060. It should work on any 5.x APIConnect platform. Other than an APIC service, all that you will need are the Chrome browser and the Postman application.

Confidential Client OAuth Provider API

Let’s first start with the configuration of APIConnect. Import the attached three APIs and the Product file.
Here let’s take a quick look at the confidential-client-oauth-provider API and the minimal changes I have done compared to the default provider API.
I have updated the base path to be “/confidential” and the client type is made “confidential”.
I have left the scopes as is, scope1 is what we will be using for testing.
I have updated the authentication URL to http://httpbin.org/basic-auth/kriti/kriti for a specific user. Any URL that will return a 200 OK for a given user should work.
I have enabled OAuth Introspection. We will be testing it.
Refresh tokens are enabled by default. We will be testing this also.
Also, I have removed the security definitions and requirements.
Everything else is left to the default values.

Public Client OAuth Provider API

public-client-oauth-provider.yaml is exactly the same as the confidential provider, except that the base path is “/public” and the client type is left with the default value of “public”.
So these are the two OAuth provider APIs.

API Secured using OAuth

As you can see, I have also included the auth-secured-api.yaml, This is not an OAuth provider API, but this API expects an access token with scope as “Scope1”. Take a quick look at the assembly of this API. Here I’m retrieving the oauth related context variables. This is to demonstrate to you that on successful validation of an access token, various Oauth parameters are available as context variable in the assembly.

Stage and publish the product to the catalog.

Create Application

Next create a client application, by going to. Dashboard -> Community -> Application -> Add. Copy the client id and client secret to a notepad. We will need this shortly in our postman application.
Subscribe to the catalog.
One thing to note here is that when applications are created here, they are assigned a default redirect uri of “https://localhost”.
So this completes the configuration of the APIConnect.

Get Gateway URL

One last thing we will need, before we can get to the Postman is the Gateway url where this API is enforced. One quick way of finding this is to go to the assembly section and invoke a test. You don’t have to specify any test parameters, but you can grab the gateway url from the debug window. Only copy the base path – up to the catalog name. Rest are hard coded in the postman collection.

Postman Application Settings

Now let’s move onto the Postman application.

Import the attached “OAuth-demo” collection. A few settings that you might want to do in the app:
enable interceptor.
In the settings tab,I have disabled the “automatically follow redirects” setting and also the disabled sending any additional headers.
Then create an environment.-> Manage environment. Add new environment. Add three parameters with these exact names as these are referenced in the collection that you have just imported.

copy and paste the values that you had copied in notepad for
client_id –
client_secret
url
One more thing that you will have to do is go to the chrome browser and hit this gateway url to accept the SSL certificate from the gateway.
Good to go.

Test Authorization code grant type

So, let’s first test the Authorization Code flow with confidential client. As you can see, the request makes use of the environment variables url and client id. Also note the redirect urid is set to “https://localhost” as I had mentioned earlier. The user name and password are set to values that will be authenticated successfully by the auth url configured in the API. The scope is scope1.
Hit send. The code is available in the Location response header. Copy and paste the code to the next request az-code-to-token. All other required parameters are pre-populated for you. hit send. There you go. You got the access token from the provider.

Test Implicit grant type

Next let’s try the implicit grant type. Response type is token, rest of the parameters are pretty much the same. Hit send. Here the access token is returned in the Location header as a fragment. Note that no refresh token is returned for implicit grant type.

Test Client Credentials grant type

Next, client credentials grant type. The client id and secret are specified in the post body and the access token is obtained. Again, no refresh token returned for this grant type also.

Test Password grant type

Next, the password grant type is straight forward. You specify both the client credentials and the resource owner credentials to the token endpoint. You get both access token and refresh token.

Test Refresh token

Finally, it is the refresh token grant type. Lets get the refresh token from any of the previous requests and paste it in the refresh token post body value here.
There you go, the token is refreshed.

Test Token introspection

I have also included the test for introspection endpoint. Simply copy the access token from one of the previous requests and send it to this endpoint. You can see the contents of the access token.

The public client folder contains the exact same set of requests, except that the client secret is removed appropriately and it gets sent to the /public base path Provider API.

Test Resource request

For the sake of completeness, let’s actually use the access token obtained to invoke the api that is proteced using OAuth. Copy any of the access token obtained to the Authorization Bearer header value here. As I explained earlier, this API is configured to return the values of the oauth context variables, and thats exactly what you see here in the response. They will come in handy when you develop more complex APIs.

Conclusion

That’s it.

If you get any one request working in this package, I’m sure you will get all the requests working in no time.

Use this as a sample or reference to build on more complex, customized OAuth provider APIs to suit your needs and requirements. I’ll see you in the next videos with some more customization of the OAuth Provider API – like redirecting or authenticating with external urls, customizing access tokens with metadata and other exciting security features in APIConnect. Stay tuned and thanks for watching !

Troubleshooting

Unable to find the GatewayURL from Assembly debug. Error: “No debug data was found for this API call”.
Solution: An alternative location would be to click explore, catalog to which the API was published, then click on one of the http requests. You can find the curl requests that contain the Gateway URL.

Unable to use refresh tokens. Error: “invalid_grant”
Grants are one time use only. Make sure that the same refresh token or authorization code are not used again.

HI Krithika. Could you please let me know, how could we implement the below scenario in API connect

1. Need to generate Oauth token. But the token will be generated in message broker and need to share that toke to end customer.
2. When ever end customer is trying to access service we need to validate that toke in message broker.
3. Planing to use the application flow to implement this requirement.

Great video and very informative! One correction: the authentication url should be https://httpbin.org/basic-auth/kriti/kriti if the API is using HTTPS . It doesn’t work using HTTP in our on-prem setup. Another point is the redirect-uri (https://localhost in the video) should match the application’s redirect url when the application was created at developer portal .

Is it possible to secure an API in IBM API Connect using a third party OAuth provider (for example google)? Theoretically, it is possible to set the Authorization URL in the API security scheme to point to the authorize url of google. However, it is not clear what happens afterwards with the client ids and client secrets, where the client registration will have to take place (API Connect portal or Google), how the billing information will be extracted etc.

Do you have some link on how this can be done or some definite answer that it cannot.

Hi Krithika,
This is Narendranath, I hope you are doing good,
I have a requirement,
We have a kubernetes cluster, it has 6 micro services, API connect configured.
we need to secure these by using ForgeRock OpenAM,
If you through some light on this it will be great for us.
Thank you.

thx for this. Just curious have you tried consuming this API via angular 4 form based login ? Issue is for me my http://hostname/oauth2/token works fine in postman but via angular form i keep getting { “error”:”invalid_client”, “error_description”:”client_id unauthorized” }

I have imported ‘public-client-oauth-provider_1.0.0.yaml’ and ‘oauth-secured-api_1.0.0.yaml’ followed the steps given in the demo. One thing I am not able to resolve is ‘SSL Certificate Hostname Mismatch (ssl_domain_invalid)’. Could you please suggest me some workaround for this issue.

I am able to resolve ‘SSL Certificate Hostname Mismatch’ error.
I am using ‘public-client-oauth-provider 1.0.0’ imported from your code ‘OAuth_Demo’. In my api proxy I am using my authorization url and token url as ‘https://api.eu.apiconnect.ibmcloud.com/veeraraghavendra254gmailcom-dev/sb/public/oauth2/authorize’ and ‘/token’ . I am testing the sample as you have explained- grant_type is ‘Auhtorization_code’ I have obtained code by hitting ‘/authorize’ url. I am calling ‘/token’ with this code and sending ‘client_id’ and ‘client_secret’. Error I am getting is ‘Invalid request’ .
I am sending code, client_id, client_secret, scope, grant_type.
Please correct me, if did any mistake here