Oauth2.0 Implementation using GoLang and WSO2 API Manager

Krishni Andradi
WSO2 Solution Architecture Team Blog
8 min readJul 7, 2019

WSO2 API Manager?

WSO2 API Manager is a fully open source product which provides web interfaces for developers to easily develop, deploy and monitor their APIs. and API consumers to subscribe, discover and consume those APIs.

I chose the WSO2 API manager as a better tool for this tutorial because

  • It is open source: you can download and install it free from here
  • Can deploy a sample within seconds. Even you can develop and deploy your APIs in minutes.
  • Uses Oauth2.0 specification
  • Descriptive documentation, and full of knowledge sources over the internet.

Deploying a sample API in WSO2 API Manager

I hope now you have already installed the WSO2 API Manager and started WSO2 API manager server. And I assume that you have not published any API

Now open up a browser and go to the below URL: https://localhost:9443/publisher/

Login to the publisher using credentials Username: admin and Password: admin

Now it will show you this page and will ask to walk you through the interactive tutorial. Don’t fall for it :) Press close button in the right upper corner.

Then it will give you this page.

Now you can deploy the sample API by pressing “Deploy Sample API” button.

Yessss. You are done with deploying a sample API.

Now let's go to the WSO2 API store and discover our API and subscribe it, and make it consumable.

Open up another browser, or a tab in the same browser and go to the below URL: https://localhost:9443/store/

Now even without login in users can see the available APIs in store. You can discover the APIs you want. But to use them, you need to login, create an application and subscribe to your API.

Go to Applications from the menu in the upper left corner

Log in using credentials Username: admin and Password: admin

Now create an application by clicking the “Add Application” link and filling required details as below.

Now go to the APIs from the menu, and click on the PizzaShackAPI. This is the sample API we deployed.

Now in the right upper corner, select the application which we created and subscribed to it. (If you need to know what this tier means please refer documentation, these things are not relevant to us for now)

Now you have Created an application and subscribe to the APIs using that. Now we want to know our client credentials for our application.

Go to Applications from the menu, click on “PizzaApp” application, and go to Production Keys tab.

In this tutorial, I am going to use Oauth2, authorization code grant type. To do that we need a callback URL (I am going to give http://localhost:3000/callback for now)and enable following grant types.

  • Client credentials
  • Refresh token (not a must, for Oauth code grant type, but will need to regenerate access token when it is expired)
  • Code (will not be enabled, before providing callback URL, so specify call back URL first and then tick this)

Click on “Generate Keys” now. And now you will get client Id and client secret. which we will use later.

Understanding OAuth2 authorization code flow

Oauth2 is an industry standard protocol for authorization. It has many grant types namely AuthCode, Implicit, Password and so on. You have to choose a grant type depending on your use case.

I used auth code grant type because when we are using Auth code grant type, we are introducing a middle layer using redirect URL, which will obtain the auth code and use it to get the access token. that will confirm more security.

In oauth2.0 authorization code grant type, we first call authorization endpoint to get the authorization code. Then we call token endpoint, and exchange authorization code to an access token.

So in summary following are the two calls

  1. Endpoint: http://localhost:9443/authorize

HTTP method: GET

client id, redirect(callback) URL and response type should be given as path variables. Here response type should be “code”, Client id is the value we got after creating APIM application and generating tokens. Redirect URL is the URL you gave in the APIM application before generating tokens. (If you provide callback URL after generating tokens, click “Update” to let the APIM system update the callback URL)

Actually, this needs to be a browser-based call. So if you are calling this from your client application, you can set URL in the browser window

Ex. https://localhost:8243/authorize?client_id=GJH9OI6b8vmck43wleSvq_KxX58a&redirect_uri=http://localhost:3000/callback&response_type=code

When we execute this we will get an authorization code to the callback URL ve specified.

2. Endpoint: http://localhost:9443/token

HTTP method: POST

Here clientID, clientSecret, code, grant type, redirect URL need to specified as x-url-encoded values in the message body.

ClientID, ClientSecret are the values generated from APIM after generating access tokens, the code is the authorization code generated from the previous step, redirect URL is the same as in the first step. and grant type is “authorization_code”

Ex.

Now we will receive the access code in the response so that we can use it to access any resource of the application until our access token expires.

You will also receive refresh token and access token expiry time along with the access token response. So now you can use this refresh token to generate new access token when the access token is expired.

For this call, you have to change the grant_type to “refresh_token” and provide refresh token as a parameter instead of giving the code.

Ex.

Understanding the process flow

As I said, Our client application has two parts, The browser-based UI component and GOLang client who handles browser information.

So In our case, we are going to get a client id and client secret from browser as form inputs, and then within the GO client application, we get those input credentials and generate the authorization endpoint URL along with path parameters. And then set that URL to the window URL in the browser. So the browser will initiate the call to auth endpoint.

So when a browser sends that GET request, it will automatically redirect to APIM login page before providing the authorization code. If APIM login failed you won't get an authorization code.

In the APIM, we have specified a callback URL. It is the URL to which APIM sends the authorization code. So the callback URL must be an endpoint exposed from GO client.

So whenever that callback endpoint is called, GO client will retrieve authorization code and sends a POST request to get the access token.

Now within GO application, we have the access token, whenever a resource access request comes from the browser-based UI, we can send a relevant HTTP call to APIM along with the access token we have.

But there can be a situation, we send the resource access request to APIM, along with access token, but in response, we get to know our access token is expired. But we can not let browser-based UI to know that. Now, what GO client application do is regenerating an access token using the refresh token it has. to do this we again have to send a request to token endpoint to get an access token. There instead of sending authorization code as input, we send refresh token.

Now when a new access token is granted, we can send the resource access request again to APIM.

Since UI does not aware of this, expired token and new token generating situation, the user may feel a very smooth flow.

Lets code it using GO !!!!!

First, we are creating a main function which can handle all the path requests and expose them via localhost.

Here I have up my server at localhost:3000

So if someone clicks on http://localhost:3000/ it will execute the function named home. There I have specified to show welcome page if the user is already logged in, else to show the login page. So when the user goes to the login page and enters client id, client secret and press on the Login button, now it will call http://localhost:3000/login which will then call loginM function.

the loginM function receives client id and client secret and then set the URL of the window to the token endpoint URL with path variables.

Above we have retrieved config info such as URLs, from a configurations file.

Now when we send the request to the authorization endpoint, we will receive our authorization code to callback URL. In our case, it is http://localhost:3000/callback, which will call the callback function.

Within callback function, we parse authentication code and exchange it to access token by sending a POST request to the token endpoint.

When we get the access code, the login process is completed, So that UI needs to be redirected to welcome page.

In the welcome page, we have links to access resources.

Now let's say the user wants to request for the menu. this get menu button is in the welcome page. and upon click, it will send a request to http://localhost:3000/menu which will call the getMenu function. Now go, client users, previous access token generated and sends that request to APIM. Upon retrieval of data, it will set them in the UI.

Here in case of the token is expired, GO client will receive a specific error in getting menu resource response, and that is captured, and refreshed token and send GET menu request again.

Conclusion

If you want to see the full code please visit: https://andradikla@bitbucket.org/andradikla/goconsumerproject.git

I hope you would have understood how to

  • Deploy sample API in WSO2 APIM
  • Oauth2, auth-code-based grant type flow
  • Building GO client application.

You can view a screencast of this application from here

Thank You

--

--