Kong Gateway
In this section we will set up Kong Gateway with a custom lua plugin to make AuthZen requests. The Kong setup follows the instructions for installing with docker on the Kong docs, and the plugin is forked from the AuthZen Github repository with some minor edits.
Note: At the time of writing, this plugin has not been published to the Kong plugin marketplace, this page will be updated once that is the case.
Install and run Kong with the plugin
First, we need to make a small change to the plugin lua so that requests will be sent to the locally running Enforcer PDP. In the KongPlugin
folder, edit the file kong/plugins/authzen/access.lua
such that on line 10 the pdpurl
points to your locally running PDP. Enter your local IP here.
The following steps mirror the Kong installation documentation, with the addition of copying the plugin files to /usr/local/share/lua/5.1/kong/plugins/authzen
and instructing Kong to include this plugin on start. If you're already familiar with Kong and comfortable doing these steps, feel free to skip ahead to the next section.
In the KongPlugin
folder, run the following commands:
Build the docker container image with the plugin.
docker build -t kongwithauthzen .
Create a network for Kong Gateway and the Kong DB.
docker network create kong-net
Run the Kong database image.
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e "POSTGRES_PASSWORD=kongpass" \
postgres:13
And then setup the database ready to be used.
docker run --rm --network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kongpass" \
-e "KONG_PASSWORD=test" \
kong/kong-gateway:3.10.0.1 kong migrations bootstrap
Run the Kong gateway with the AuthZen plugin.
docker run -d --name kong-gateway \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kongpass" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_ADMIN_GUI_URL=http://localhost:8002" \
-e KONG_LICENSE_DATA \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
-p 8002:8002 \
-p 8445:8445 \
-p 8003:8003 \
-p 8004:8004 \
kongwithauthzen
Verify that Kong is running and the AuthZen plugin is present. There should be an entry in the json named authzen
.
curl http://localhost:8001 -s | jq .plugins
Setup a basic proxy to the to-do API
The following steps will set up the bare minimum for Kong to proxy to the To-do API. All traffic where the route begins with /todolist/
will be forwarded. For information on configuring Kong services and routes, refer to the Kong documentation.
Create a service in Kong that represents the To-do API.
Note: Enter your local IP in the snippet below.
curl --location 'http://localhost:8001/services' \
--header 'Content-Type: application/json' \
--data '{
"name": "todo_service",
"url": "http://<Your local IP>:5077"
}'
Set-up a route that forwards all traffic to the To-do API.
curl --location 'http://localhost:8001/services/todo_service/routes' \
--header 'Content-Type: application/json' \
--data '{
"paths": [ "/todolist" ],
"name": "todo_proxy"
}'
Call the upstream API
At this point, make some requests via Kong and verify that you get a response from the to-do API.
curl --location 'http://localhost:8000/todolist/api/todos'
Enable the AuthZen plugin on the configured service
In the Enforcer PDP project, add the Rsk.Enforcer.AuthZen
NuGet package, and then in Program.cs
call UseEnforcerAuthZen
during startup. The file should look as follows:
using Rsk.Enforcer;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddEnforcer("AcmeCorp.Global", options =>
{
options.Licensee = "DEMO";
options.LicenseKey = "Obtain a free demo license key from https://www.identityserver.com/products/enforcer";
})
.AddFileSystemPolicyStore("Policies")
;
var app = builder.Build();
app.UseEnforcerAuthZen();
app.Run();
We also need to enable the kong plugin on the configured service and verify that the PDP is being invoked.
curl --location 'http://localhost:8001/services/todo_service/plugins' \
--header 'Content-Type: application/json' \
--data '{
"name": "authzen"
}'
The plugin expects there to be an authorization header on the request with a bearer token. The subject in the token will form part of the request to the PDP, as per the AuthZen spec.
You can view and generate bearer tokens using JWT.io. For the purposes of this demo, only the sub
property of the payload is required.
curl --location 'http://localhost:8000/todolist/api/todos' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
Given that our starter policy always returns a permit result, the request above should return data from the to-do list.
Change the policy result to deny
on line 12 of policy.alfa
and retry the request above. You should now see an error message stating AuthZEN: Access Forbidden
.