docker run -d --name mockbin_redis redis
docker run -d --link mockbin_redis:redis --name mockbin mashape/mockbin
docker run -d --name kong-database \
-p 9042:9042 \
cassandra:2.2
docker run -d --name kong \
--link kong-database:kong-database \
--link mockbin:mockbin \
-e "KONG_DATABASE=cassandra" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PG_HOST=kong-database" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 7946:7946 \
-p 7946:7946/udp \
kong
curl -s -X POST \
--url http://localhost:8001/apis/ \
--data 'name=mockbin' \
--data 'upstream_url=http://mockbin:8080/' \
--data 'request_path=/mockbin' \
--data 'strip_request_path=true' | jq .
curl -s -X GET --url http://localhost:8000/mockbin/request | jq .
curl -s -X POST http://localhost:8001/apis/mockbin/plugins \
--data "name=rate-limiting" \
--data "config.minute=5" | jq .
curl -s -X POST http://localhost:8001/apis/mockbin/plugins \
--data "name=key-auth" | jq .
curl -s -X GET --url http://localhost:8000/mockbin/request | jq .
curl -s -X POST http://localhost:8001/consumers/ \
--data "username=mmarie" | jq .
curl -s -X POST http://localhost:8001/consumers/mmarie/key-auth -d '' | jq .
curl -s http://localhost:8000/mockbin/request?apikey=<generated_key> | jq .
curl -s http://localhost:8000/mockbin/request \
-H 'apikey: <generated_key>' | jq .
x-consumer-id and x-consumer-username have been filled by kong.
Is it enough to secure an api? No. We can't create api-key like that, because the user didn't authenticate himself anywhere before calling it... And what happend if the user leaves the company? You will have to check each day the entire user db (most of the case : a LDAP), to know if all the users are still there. Avoid scheduled tasks !
JWT is stateless! It can embed some data, like user profile.
Kong supports JWT, it can validate the signature and validate fields like expiration date.
- Delete the API key plugin
curl -s -X GET http://localhost:8001/apis/mockbin/plugins | jq .
curl -s -X DELETE http://localhost:8001/apis/mockbin/plugins/{api-auth id}
- Add a JWT plugin to api
curl -s -X POST http://localhost:8001/apis/mockbin/plugins \
--data "config.key_claim_name=aud" \
--data "name=jwt" | jq .
- Add a JWT plugin to consumer
RSA_PUB_KEY="-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvgKPUi8QOX7FD0328ELk7WiKc
DTwOF3NGn2lXJuUmj8p3o+yOQ2dDBnhWO+IUctTaq9YzI6QVLyRqSxBDJouRjhsz
7B9BSfnkN8fRdEqKAtgQcdjrVjNkyrGescKMDeokatwa7ZrEmQ3ubRdzMtglQ2y7
q8bGGHkaE9DJtj2xdQIDAQAB
-----END PUBLIC KEY-----"
curl -s -X POST http://localhost:8001/consumers/mmarie/jwt \
--data "key=mmarie" \
--data "algorithm=RS256" \
--data-urlencode "rsa_public_key=$RSA_PUB_KEY" | jq .
- Craft a new token
Algorithm : RS256
Payload
{
"sub": "1234567890",
"name": "Max Marie",
"aud": "mmare"
}
Public key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvgKPUi8QOX7FD0328ELk7WiKc
DTwOF3NGn2lXJuUmj8p3o+yOQ2dDBnhWO+IUctTaq9YzI6QVLyRqSxBDJouRjhsz
7B9BSfnkN8fRdEqKAtgQcdjrVjNkyrGescKMDeokatwa7ZrEmQ3ubRdzMtglQ2y7
q8bGGHkaE9DJtj2xdQIDAQAB
-----END PUBLIC KEY-----
Private key
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCvgKPUi8QOX7FD0328ELk7WiKcDTwOF3NGn2lXJuUmj8p3o+yO
Q2dDBnhWO+IUctTaq9YzI6QVLyRqSxBDJouRjhsz7B9BSfnkN8fRdEqKAtgQcdjr
VjNkyrGescKMDeokatwa7ZrEmQ3ubRdzMtglQ2y7q8bGGHkaE9DJtj2xdQIDAQAB
AoGAUcyxj5V9Uf3ED4r5pbhdvY4rZ3S7sw23Cwmt/ZMBZ1HJ2q2qyjwcWx8e44KR
w1oqX6mL8tX/2mfYnzpRYBsNHYrrG2U+RPWYghu5MWAkiukqawENSuE0hgYs2Bs2
Y8urbTZvpOeG9d/LcXh4VGE/uHdXc/95xsG3K0kwe7d+u5kCQQDZEptSTmNUYZen
6l4IQaL+zB68imZtTLoO9bEC6uaycz8Ko5p/68dkkY9hwqdYhIuaKV/OpjwOqeRL
BPbfTS7/AkEAzvmgFyDinsY2KqF8Qs1KEAUjNa5t/hNxkgYhNSpsTN8hCBS86Ujm
L1zMbmTdEg7dABsNfthPvucFGwwdD2fTiwJBAJ3OpRQk4JlLiZENFOczsGdDxWST
yPrUuL5/ZvwUATriBYaagYtVwVMfbvlHJZl4YnTkdz4oI6kVYV4YcdDMr8kCQQCb
WvO3aI+x7cWqqhvDaKQ28iRDnvIgzCdrG/7BEV7JNJJupmJGGNnuoxEvq7XkYBOy
iJvQojz5Zh6G9si5T42RAkAB22HzNc6RcstvTy8JIZ4jO17AJnrguEKCGdMdbziO
HGX4UZ2esZvLAYf9g2yHfGf5+5ITt8vAqvP3ghmkgw26
-----END RSA PRIVATE KEY-----
- Call the API
curl -s http://localhost:8000/mockbin/request \
-H 'Authorization: Bearer {TOKEN}' | jq .
- Kong will be there to authorize the users to access any api
- The SSO only authenticate user with his credentials
Which SSO?
Why?
- Opensource
- Owned by redhat
- Out of the box
- Scalable
- Openid connect protocol, JWT implementation
docker run -d -e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin \
-p 8080:8080 \
--name keycloak \
jboss/keycloak
Create a new realm and a new client.
curl -s -X POST http://localhost:8001/consumers/ \
--data "username=webapp" | jq .
curl -s -X POST http://localhost:8001/consumers/webapp/jwt \
--data "key=webapp" \
--data "algorithm=RS256" \
--data-urlencode "rsa_public_key=$RSA_PUB_KEY" | jq .
Add some checks on JWT token
curl -X PATCH http://kong:8001/apis/{api}/plugins/{jwt plugin id} \
--data "config.claims_to_verify=exp,nbf"