JWT authentication using Kong with Kubernetes on Azure

When we try Microservices architecture, you need to handle authentication among the services.  JWT is one of the solutions for this. Kong can handle this problem very well. It works on a lot of environment.

It works on Kubernetes as well.  I'll share with you step by step.

I tried to configure JWT authentication using Kong and Kubernetes on Azure.

1. Prerequisite

You need to provision the k8s cluster on Azure. Also, you need to enable kubectl for operating the cluster.
You can see the following instruction

/ja-jp/azure/container-service/container-service-kubernetes-walkthrough

You can create/configure a kubernetes cluster on Azure just four commands.

2. Deploy Kong on Kubernetes

Installing Kong on Kubernetes is quite easy.  I just follow this instruction.
https://github.com/Mashape/kong-dist-kubernetes

You need to clone the repo and deploy using YAML file of kubernetes.

 $ git clone git@github.com:Mashape/kong-dist-kubernetes.git
$ cd kong-dist-kubernetes

You can choose PostgreSQL or Cassandra for the Storage.

 kubectl create -f postgres.yaml

Then you can deploy Kong for kubernetes.

 kubectl create -f kong_<postgres|cassandra>.yaml

You can see the Service ports.
kong-admin is the server for configuring kong. kong-proxy is a proxy

 
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-admin 10.0.51.177 13.78.125.36 8001:31642/TCP 2d
kong-proxy 10.0.125.138 13.78.124.101 8000:31512/TCP,8443:32257/TCP 2d
kubernetes 10.0.0.1 <none> 443/TCP 2d
postgres 10.0.233.146 <none> 5432/TCP 2d

Now you are ready to use Kong.

NOTE: As you can see, this template has a problem. This configuration reveals the kube-admin IP address. Then everyone who knows the address can operate the API. https://github.com/Mashape/kong-dist-kubernetes/blob/master/kong_postgres.yaml

You can customize this template. Just remove the Load Balancer setting from kong-admin. For example, You can ssh tunnel to configure the cluster instead.

3. Setting up the JWT token using Kong

3.1. Setting up the target service

If you already have the target service, it would be nice, however, if you don't have it,You need to create a service. One of the most easiest way is to use the mockbin.org. Just push `Create Bin` button then you get a "mock" service.


3.2. Proxy config

All you need is to post to the kong-admin api. I'll configure JWT token authentication.
I use POSTMAN for this purpose.

proxyconfig

Just post the endopoint of kong-admin api. This rest-api call creates a service for the target.
I create a mock service using mockbin.org. The mock service url is `https://mockbin.org/bin/dc62c9c5-b6eb-4e81-b1a4-0aeb197e3f24`. When you access https://{kong-proxy}:{port}/{uris} e.g. https://13.78.124.101:8000/jwt/ppkey, it proxys request to the mock service.


3.4. Configure the plugin

You need to configure to enable the jwt plugin

configureplugin
3.5. Create a consumer

createaconsumer

3.6. Generate Public/Private Keys

Generate Public/private key using ssh-keygen. Kong JWT plugin requires a private key and the public key with PEM format.

 
$ ssh-keygen -t rsa -b 4096 -C "{Your e-mail address}"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ushio/.ssh/id_rsa): ./jwtrs256.key
 
$ openssl rsa -in jwtrs256.key -pubout -out jwtrs256.key.pem

3.6. Create JWT credential

createjwtcredential

3.6. Craft JWT

Create the token. Kong doesn't have this functionality. I wrote a token generatorusing node.js.

 
var jwt = require('jsonwebtoken')
const fs = require('fs')
var cert = fs.readFileSync('./jwtrs256.key')
var token = jwt.sign({iss:'oauth-server',exp: Math.floor(Date.now() /1000) + (60 * 60)}, cert, {algorithm: 'RS256' })
console.log(token)

Once you execute this program, you can get a jwt token.

3.8. Send a request

When you use this JWT token, you can use it with a parameter or, Authentication header.You can choose the method.

Before adding the token, you can't see the website.

unauthorized

Parameter

Once you pass the jwt token by the jwt parameter, which you created at 3.7 Craft JWT, you can see it.

authorized

Authentication header

You can do the same thing with Authorization header like below

authorizedwithheader

Conclusion

Kong enable us to use JWT authentication on Kubernetes. It is easy to use however, the original template have a security problem. Don't expose the kong-admin endpoint to the outside of the cluster. For example, you can use ssh tunneling.

Also, my customer said that you need to issue the token for every api. If you use a bunch of Microservices, it might not be a convenient. The customer said that they customize the jwt plugin for share the token among the group of the apis.

Anyway, JWT is a very important technology for Microservices, however you can use kong for this purpose.


Resource

 

Kong
https://github.com/Mashape/kong

Kong + kubernetes deployment

https://github.com/Mashape/kong-dist-kubernetes

Kong Plugin JWT
https://getkong.org/plugins/jwt/

Mockbin
https://mockbin.org/

POSTMAN
https://www.getpostman.com/

Kong ことはじめ (Japanese)
https://qiita.com/AkihiroTakamura/items/f3dbcace4a9e6ca982a1