Kong — Oauth 2.0 Plugin

faren
4 min readJul 24, 2018

--

Kong as API Gateway support for configurable plugin, to get what is Kong and basic tutorial to install and setup KONG you could go to this article.

Now we through how to setup Oauth2 to our Kong, but before that it is required to through previous tutorial.

Please make sure you have installed and setup KONG, and it’s up and running. You should have this:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
272841a859d2 node_kong “npm start” 3 days ago Up 15 hours 10000/tcp node_kong
2bd5d4b0126b kong:latest “/docker-entrypoint.…” 3 days ago Up 15 hours 0.0.0.0:9000->8000/tcp, 0.0.0.0:9001->8001/tcp, 0.0.0.0:9443->8443/tcp, 0.0.0.0:9444->8444/tcp kong
92877820c824 postgres:9.6 “docker-entrypoint.s…” 3 days ago Up 15 hours 0.0.0.0:5555->5432/tcp kong-database

and we could access the API through KONG (localhost with port 9000):

GET: localhost:9000/api/v1/customers

Headers: Host:api.ct.id
Respond:
[
{
“id”: 5,
“first_name”: “Dodol”,
“last_name”: “Dargombez”
},
{
“id”: 6,
“first_name”: “Nyongot”,
“last_name”: “Gonzales”
}
]

So we already have KONG as API gateway connected to upstream service as own API/service to get customers. Now we go through to try plugin that can be as sidecar on API-gateway.

To make it easier if you have not done yet, please download file kong.postman_collection.json on github NodeJS-API-KONG (https://github.com/faren/NodeJS-API-KONG), and import it to postman.

We are going to explore the expanded folder postman above.

Enabling the plugin on a service

For this example, we have a service api-v1-customers. Hit the GET API KONG services:

GET: localhost:9001/services/

Respond:
{
“next”: null,
“data”: [
{
“host”: “172.19.0.4”,
“created_at”: 1531989815,
“connect_timeout”: 60000,
“id”: “d28c20e4–94d3–4c3b-9a0d-688ac8dbf213”,
“protocol”: “http”,
“name”: “api-v1-customers”,
“read_timeout”: 60000,
“port”: 10000,
“path”: null,
“updated_at”: 1531989815,
“retries”: 5,
“write_timeout”: 60000
}
]}

So, we enable this service to Oauth2 plugin by hit API method POST for add service to plugin:

POST: localhost:9001/services/api-v1-customers/plugins

Headers: Content-Type:application/json
Body:
{
“name”: “oauth2”,
“config.scopes”: [“read”, “write”],
“config.mandatory_scope”: true,
“config.enable_password_grant”: true,
“config.accept_http_if_already_terminated”: true,
“config.token_expiration”: 180,
“config.global_credentials”: true
}
Respond:
{
“created_at”: 1532406761000,
“config”: {
“refresh_token_ttl”: 1209600,
“scopes”: [
“read”,
“write”
],
“mandatory_scope”: true,
“enable_client_credentials”: false,
“accept_http_if_already_terminated”: true,
“token_expiration”: 180,
“enable_implicit_grant”: false,
“global_credentials”: true,
“anonymous”: “”,
“enable_password_grant”: true,
“hide_credentials”: false,
“enable_authorization_code”: false,
“provision_key”: “kl3bUfe32WBcppmYFr1aZtXxzrBTL18l”,
“auth_header_name”: “authorization”
},
“id”: “4f1dbb44-bb51–49b3–80d5-b0a5ac4f7caf”,
“enabled”: true,
“service_id”: “eb422ef1–65a3–4654-a75f-41a8132d7861”,
“name”: “oauth2”
}

Create a consumer

After enable plugin to specific service on this case service customers, now time to add a consumer who can access the API. You need to associate a credential to an existing Consumer object.

POST: localhost:9001/consumers

Headers: Content-Type:application/json
Body:
{
“username”: “oneone@gmail.com”,
“custom_id”: “11”
}
Respond:
{
“custom_id”: “11”,
“created_at”: 1532416069,
“username”: “oneone@gmail.com”,
“id”: “6db1dfe5–47f2–455b-8fb0-d935017efcb3”
}

Create an application

Then you can finally provision new Oauth2 credential (also called :OAuth applications”) by making the following hit API POST, as follow:

POST: localhost:9001/consumers/oneone@gmail.com/oauth2

Headers: Content-Type:application/json
Body:
{
“name”: “APP 11”,
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“redirect_uri”: “http://localhost:9800/cb"
}
Respond:
{
“client_id”: “CLIENT_ID_11”,
“created_at”: 1532419699000,
“id”: “06acbdce-08f5–40fd-95f5–52cdad2b6d06”,
“redirect_uri”: [
“http://localhost:9800/cb"
],
“name”: “APP 11”,
“client_secret”: “CLIENT_SECRET_11”,
“consumer_id”: “6db1dfe5–47f2–455b-8fb0-d935017efcb3”
}

Once we have activated service “api-v1-customer” Oauth2, we could not access the API without Authorisation, let’s try again hit API customer:

GET: localhost:9000/api/v1/customers

Headers: Host:api.ct.id
Respond:
{
“error_description”: “The access token is missing”,
“error”: “invalid_request”
}

Request and Refresh Token

We have add consumer and create application for specific consumer (ex: oneone@gmail.com) to OAuth plugin service api-v1-customer. Now we need to simulate to get token and refresh token as part of OAuth 2.0 Flows to access API that has been protected Oauth2.

POST: https://localhost:9443/api/v1/customers/oauth2/token (warning: please make sure it’s https, you can set ignore it from postman on setting, SSL certificate verification set to OFF)

Headers: Content-Type:application/json
Host:api.ct.id
Body:
{
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“grant_type”: “password”,
“provision_key”: “kl3bUfe32WBcppmYFr1aZtXxzrBTL18l”,
“authenticated_userid”: “oneone@gmail.com”,
“scope”: “read”
}
Respond:
{
“refresh_token”: “halEdslDD61bTvMxUGbPbu75DxdKmWdP”,
“token_type”: “bearer”,
“access_token”: “UYSLDGIZI8yIotLryGRp93jvF1YsYdHB”,
“expires_in”: 180
}

When we enable OAuth2 plugin to api-v1-customer service, we set token expired for 180 seconds. So after 180 seconds, the token is expired, and need to refresh token, by:

POST: https://localhost:9443/api/v1/customers/oauth2/token (warning: please make sure it’s https, you can set ignore it from postman on setting, SSL certificate verification set to OFF)

Headers: Content-Type:application/json
Host:api.ct.id
Body:
{
“grant_type”: “refresh_token”,
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“refresh_token”: “halEdslDD61bTvMxUGbPbu75DxdKmWdP”
}
Respond:
{
“refresh_token”: “YEtNrtkKXw0KoRahZttDC43YgPPcpOfm”,
“token_type”: “bearer”,
“access_token”: “FTthUuOiTU1o2m4F8DUaWDsacbm3Fbam”,
“expires_in”: 180
}

So now, we have token and we could put on header key — Authorization: bearer token

GET: localhost:9000/api/v1/customers

Headers: Host:api.ct.id
Authorization:bearer UYSLDGIZI8yIotLryGRp93jvF1YsYdHB
Respond:
[
{
“id”: 5,
“first_name”: “Dodol”,
“last_name”: “Dargombez”
},
{
“id”: 6,
“first_name”: “Nyongot”,
“last_name”: “Gonzales”
}
]

Conclusion

Plugin Oauth2 is one of the common authorisations that used nowadays. Kong has provided this plugin and manage it by API for community edition. However to get more understanding on Oauth 2.0 Flows, you need to understand the concept itself, please read more about this on https://docs.konghq.com/plugins/oauth2-authentication

--

--

faren

Enthusiastic Person, Startup Life, Tech Person, be first adopter, be a forward looking.