Introduction
This tutorial will take you through the steps required to setup Enforcer as a standalone policy decision point and integrate with Kong Gateway via the AuthZen protocol. We will then use Enforcer to authorize requests to another API upstream of Kong.
This tutorial does not require prior Enforcer or Kong knowledge. However, if you are not familiar with either Enforcer or Alfa, you may find the ALFA and Securing APIs tutorials beneficial prior to starting this.
In the tutorial we will use Docker to run Kong Gateway, so ensure you have that installed if you wish to follow the tutorial to the letter.
Learning objectives:
- Craft AuthZen compatible policies in Alfa
- Integrate Enforcer with Kong Gateway using a custom plugin
Scenario
The code in this tutorial models a multi-user to-do list. The to-do list supports basic create, read, update and delete operations as well as marking individual tasks as being complete. We will model three levels of access:
- Administrators are able to perform all actions on the to-do list.
- Workers can view to-do items and mark them as complete.
- Guests can only view to-do items.
Starter solution
During this tutorial, you will be modifying ALFA policies. We recommend installing an ALFA plugin for your editor; this will colorize and highlight syntax errors in the ALFA.
If you don't have a license key for Enforcer, obtain a demo one by visiting https://identityserver.com/products/enforcer.
To get the starter solution, clone the following GIT repository to your machine:
https://github.com/RockSolidKnowledge/Samples.Enforcer
Go to the KongTutorial/Before
folder and open two solutions KongTutorialBackend.sln
and KongTutorialRemoteEnforcer.sln
in your development environment.
The code you will be working from has the to-do list features described above already implemented. The Enforcer solution starts an empty web application and has an Alfa policy which always returns a permit result. During the tutorial we will implement the necessary features in this project.
Lets look at the code to see how it works.
The Todo API
Examine the code in the KongTutorialBackend
project and understand whats here. There are two components, TodoController.cs
and DataStore.cs
. The To-do controller implements the various interactions as described above, and the data store maintains the todo list data. Data is held in-memory while the application runs.
Run the application and make some http requests to each of the endpoints to verify that they work as described.
The relative URLs for the operations are:
Get all task:s GET
/api/todos
curl --location 'http://localhost:5077/api/todos'
Get task by Id: GET
/api/todo/{id}
curl --location 'http://localhost:5077/api/todo/1'
Create task: POST
/api/todo
curl --location 'http://localhost:5077/api/todo' \
--header 'Content-Type: application/json' \
--data '{
"text": "Authorize requests with Enforcer",
"done": false
}'
Update task: PUT
/api/todo
curl --location --request PUT 'http://localhost:5077/api/todo' \
--header 'Content-Type: application/json' \
--data '{
"id": 1,
"text": "Authorize requests with Enforcer",
"done": true
}'
Delete task: DELETE
/api/todo/{id}
curl --location --request DELETE 'http://localhost:5077/api/todo/1'
Complete task by Id: PATCH
/api/todo/{id}
curl --location --request PUT 'http://localhost:5077/api/todo/1'
The Enforcer Policy Decision Point
Examine the code in the KongTutorialRemoteEnforcer
project. All that exists here is some basic Enforcer wire-up in Program.cs
and an authorization policy stored on the file system. Enter your license key in the AddEnforcer
call and verify that the project runs.
Open and inspect the authorization policy Policies/policy.alfa
. The contents are as follows:
namespace AcmeCorp {
import Oasis.Attributes.*
import Oasis.Functions
import Enforcer.Functions
policyset Global {
apply firstApplicable
policy TodoServicePolicy {
rule permitAll {
target clause true
condition true
permit
}
}
}
}
We have a policy entry point named AcmeCorp.Global
, which has a child policy to govern the to-do API. This policy has a single rule which always returns a permit
result.
Note:
Through the rest of this tutorial, we will use Kong Gateway hosted in Docker. The gateway will need to make network requests to these two projects, and localhost
will refer back to the docker container. The simplest way around this without diving into docker configuration is to refer to each service by IP. Find your local ip address, and update Properties/launchSettings.json
in both projects. Replace localhost
with your local IP.