The purpose of this post is to explain how we can secure APIs using APISIX API Gateway and Keycloak.
We are going to use Keycloak for authentication and authorization as an identity provider.
The Key Takeaways
This approach is that the application doesn’t have to handle authentication and authorization for APIs since it’s managed by API Gateway.
Also since it’s cloud native API Gateway, we can manage and use it, the same way Kubernetes artifacts manage and use.
With this kind of a platform, we can deploy applications developed in any programming language since the platform itself manages non-functional features that need to be there, such as security.
https://i.stack.imgur.com/qaogh.png
To get an idea about Keycloak RBAC, please see the diagram below.
.
https://images.app.goo.gl/g9oixvSgQ9virLBf8
This post is inspired by the example below but I had to fix some of the configurations since it’s already outdated.
https://www.youtube.com/watch?v=xjDQ9Gm234c
You can find the customized repo from below location
https://github.com/dhanuka84/apisix-summit-material
Please note that you have to replace 192.168.59.106 with minikube ip in your minikube cluster.
Steps for setting up the platform
Install minikube addons
In this local setup we are using minikube. Now we need to install a few addons related to our poc.
Run this command to install three add-ons.
minikube addons enable storage-provisioner default-storageclass ingress ingress-dns
Install metalLB load balancer
Please follow the below reference to install metalLB load balancer for minikube.
https://kubebyexample.com/learning-paths/metallb/install
Load application images to minikube
docker pull docker.io/jpgouin/front-app:1.0-rc4
docker pull jpgouin/app-go-api:1.0-rc1
minikube image load docker.io/jpgouin/front-app:1.0-rc4
minikube image load jpgouin/app-go-api:1.0-rc1
2. Install APISIX APIGateway
helm repo add apisix https://charts.apiseven.com
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
kubectl create ns ingress-apisix
helm install apisix apisix/apisix \
--set gateway.type=LoadBalancer \
--set ingress-controller.enabled=true \
--namespace ingress-apisix \
--set ingress-controller.config.apisix.serviceNamespace=ingress-apisix
3. Install Keycloak
kubectl create ns keycloak
kubectl create -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes-examples/keycloak.yaml -n keycloak
wget -q -O - https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/latest/kubernetes-examples/keycloak-ingress.yaml | \
sed "s/KEYCLOAK_HOST/keycloak.$(minikube ip).nip.io/" | \
kubectl create -f - -n keycloak
You can verify the installation with below commands
$ kubectl get ing -n keycloak
NAME CLASS HOSTS ADDRESS PORTS AGE
keycloak nginx keycloak.192.168.59.106.nip.io 192.168.59.106 80, 443 54m
> echo "" &&
echo "Keycloak: $KEYCLOAK_URL" &&
echo "Keycloak Admin Console: $KEYCLOAK_URL/admin" &&
echo "Keycloak Account Console: $KEYCLOAK_URL/realms/myrealm/account" &&
echo ""
Keycloak: https://keycloak.192.168.59.106.nip.io
Keycloak Admin Console: https://keycloak.192.168.59.106.nip.io/admin
Keycloak Account Console: https://keycloak.192.168.59.106.nip.io/realms/myrealm/account
$ kubectl get all -n keycloak
NAME READY STATUS RESTARTS AGE
pod/keycloak-7c7444bcf5-fwdsc 1/1 Running 0 44m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/keycloak LoadBalancer 10.109.145.178 192.168.59.24 8080:31190/TCP 44m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/keycloak 1/1 1 1 44m
NAME DESIRED CURRENT READY AGE
replicaset.apps/keycloak-7c7444bcf5 1 1 1 44m
4. Deploying the applications
Front-end application
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/front-app/deployment/kubernetes/deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/front-app/deployment/kubernetes/service.yaml
Back-end application
5. APISIX routes configuration
- Front-end application routing
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/scenario/Step-1a-front-route-insecure.yaml
- Now you can see the host path for the front-end app is book-app.demo.jpgouin.pro hence we application access url will be http://book-app.demo.jpgouin.pro/
- Back-end application routing
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/scenario/Step-1b-back-route-insecure.yaml
Please note that, demo-api.demo.jpgouin.pro is the backend app host path.
Add below entry to /etc/hosts file for DNS mapping
You can see that the API Gateway load balancer external ip is 192.168.59.25
dhanuka84@dhanuka84:~/research/apim$ cat /etc/hosts
192.168.59.25 book-app.demo.jpgouin.pro demo-api.demo.jpgouin.pro
6. Testing
Go to the website using the URL below.
http://book-app.demo.jpgouin.pro/
This will display a site without the below data. So you can add authors and books as below.
Make sure that the author first and last name is same.
7. Applying RBAC for the APIs exposed by microservices applications.
- Create a routing for the keycloak, by doing this we can access keycloak through API Gateway.
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/configuration/keycloak-route.yaml
- To create RBAC configuration in keycloak , you can login to the keycloak admin dashboard with below url then entering both username and password as admin .
https://keycloak.192.168.59.106.nip.io/
Or else you can upload a realm-export.json file to keycloak.
Create a realm by selecting the Create Realm button.
Browse to resource file (realm-export.json) .
- Finally you can check the configuration as below.
8. Apply OAuth2/OpenID configuration to API Gateway routes.
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/scenario/Step-2a-front-route-secure.yaml
kubectl apply -f https://raw.githubusercontent.com/dhanuka84/apisix-summit-material/master/scenario/Step-2b-back-route-secure.yaml
Now the front-end application router will use openid-connect plugin with given configuration.
Expected behavior is when we enter the web-application URL it will direct to keycloak username and password login page.
If you login as Jhon, he can create authors but can’t create books
If you login as Franck, he can create a book entry but can’t create an author record.
Both users can view the data created by them.
9. Testing
Once you login as Franck, you can’t create authors and will get 403 error code.
He still can enter the book record.
- This way we can secure APIs based resources and restrict actions based on configured RBAC.
No comments:
Post a Comment