Skip to content

Instantly share code, notes, and snippets.

@haproxytechblog
Last active February 26, 2021 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haproxytechblog/cc78926ee74219d0636fde81e9874dc3 to your computer and use it in GitHub Desktop.
Save haproxytechblog/cc78926ee74219d0636fde81e9874dc3 to your computer and use it in GitHub Desktop.
Using HAProxy as an API Gateway, Part 2 [Authentication]
Authorization: Bearer <token>
[
"robo-hamster",
"space-hamster",
"commando-hamster",
"pirate_hamster"
]
<html>
<body>
<h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body>
</html>
curl --request POST \
--url 'https://myaccount.auth0.com/oauth/token' \
--header 'content-type: application/json' \
--data '{"client_id": "abcdefg12345", "client_secret": "HIJKLMNO67890", "audience": "https://api.mywebsite.com", "grant_type": "client_credentials", "scope": "read:hamsters write:hamsters"}'
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlJEVkNSVFZHTmpZNU5rVTJSVUV3TnpoRk56UkJRalU0TjBFeU5EWTNSRU01TWtaRFJqTkNNUSJ9.eyJpc3MiOiJodHRwczovL25pY2tyYW00NC5hdXRoMC5jb20vIiwic3ViIjoiNEp6Mm4yT2hMOTJEUlloMm5nY1cxWWxKZnp4cUVSVjdAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vYXBpLm15d2Vic2l0ZS5jb20iLCJpYXQiOjE1NDE1Mzk2MzgsImV4cCI6MTU0MTYyNjAzOCwiYXpwIjoiNEp6Mm4yT2hMOTJEUlloMm5nY1cxWWxKZnp4cUVSVjciLCJzY29wZSI6IndyaXRlOmhhbXN0ZXJzIHJlYWQ6aGFtc3RlcnMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.hI44dM3ROdnowjjbbnoLWZkeHKx0k-9nu-TWUmABRo3CC40O69aOSIzn4p24qni_5q65MNaSqsznXSb0x0saABawHG8rQ09Y1PcRmBCSNnS43ptkl4a302yGAvYOzNE0F7NkWYNVFoGqheFK88kHG3grWU94ZvAzJEai_ITVnG7n2-sgvaxk7AGpd5xLycrtMHxMC8iHvNja9YfnMgwlqW7b8B9M9KyTJrWGOg687-mGY9UEf4nD9doDa1owD4UcsONDppU7bBxgLEVlUbWth6Pd3Rc6pVfWQpzwY83FxIXiIGFr69ABlcoHajcoty7l_PyN3hmobhyZ-8hnqBWSeA",
"scope": "write:hamsters read:hamsters",
"expires_in": 86400,
"token_type": "Bearer"
}
curl --request POST \
--url https://api.mywebsite.com/api/hamsters/turbo-hamster \
--header 'authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiI...'
-----BEGIN CERTIFICATE-----
MIIDATCCAemgAwIBAgIJOTQvWZNFMdgBMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNV
BAMTE25pY2tyYW00NC5hdXRoMC5jb20wHhcNMTgxMDA5MDA1OTMyWhcNMzIwNjE3
MDA1OTMyWjAeMRwwGgYDVQQDExNuaWNrcmFtNDQuYXV0aDAuY29tMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIL8bebCh+pi68Rt0CCu104VqR10kuD0
E1yzwaywvaEiyhfUeDDKAyKC8yS5ilu9xyWK/pg/84RiWq7WoqhUm8L06jtknn/Z
COuyUdkn1QcdOG10lbbrUF1AOduTIvFYyT4zHrIcKt6MyeQUO0kHcXQU7lvM2C62
BboAasZFupDts1m1kPZMWaiSjLrE1eruhl8NrfipiPWMZJSJoYCQcmtN3REXk9z8
X7ZPgcMJ9hNN+Kv0fTYLZI4wS4TpHscVfbK18cL4uLrTCcip7jNey2KZ/YdbeHgm
mcQAdiB4veH4I2dAyqIdsy8Jk+KTs3Ae8qp+S3XtC8z/uXMbN7lRAwIDAQABo0Iw
QDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRh4OxTHcFgxEk96rKbvWHibUeB
wzAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBACYMzTV0kHcRDwJy
j+XHmmFimPCcgOPOwo4h4eSRIq8XCyFhdOlhuyj8T6ESClKaAz5OmKvXBBP7Onpk
Ucrbv1VaNCluc/X6in2hptru3L/Ouxjv22QwCWNVB288ns3cYszr5M1ycaWnqXDm
Y4/xoK3phUcTIQBFY1I1JuKxDzSihDeEAlkXMYwiCSreG1WuAmyA3oWEfdpfnwwz
3QT2YTRs3P/IKSlLeYzC1Wn5BYrmyHK1EC7scTofdFz+OqldINLB08kk7Axv73hw
D72zNfYVzX9Eh+d3jH6u6TsLD2M6dvTvYyMP8yRLy1LbbRpaZBfFdDrEtqOO0+61
o9gGYJE=
-----END CERTIFICATE-----
openssl x509 -pubkey -noout -in ./mycert.pem > pubkey.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvIL8bebCh+pi68Rt0CCu
104VqR10kuD0E1yzwaywvaEiyhfUeDDKAyKC8yS5ilu9xyWK/pg/84RiWq7WoqhU
m8L06jtknn/ZCOuyUdkn1QcdOG10lbbrUF1AOduTIvFYyT4zHrIcKt6MyeQUO0kH
cXQU7lvM2C62BboAasZFupDts1m1kPZMWaiSjLrE1eruhl8NrfipiPWMZJSJoYCQ
cmtN3REXk9z8X7ZPgcMJ9hNN+Kv0fTYLZI4wS4TpHscVfbK18cL4uLrTCcip7jNe
y2KZ/YdbeHgmmcQAdiB4veH4I2dAyqIdsy8Jk+KTs3Ae8qp+S3XtC8z/uXMbN7lR
AwIDAQAB
-----END PUBLIC KEY-----
global
lua-load /usr/local/share/lua/5.3/jwtverify.lua
setenv OAUTH_PUBKEY_PATH /usr/local/etc/haproxy/pem/pubkey.pem
setenv OAUTH_ISSUER https://myaccount.auth0.com/
setenv OAUTH_AUDIENCE https://api.mywebsite.com
frontend api_gateway
# Always use HTTPS to protect the secrecy of the token
bind :443 ssl crt /usr/local/etc/haproxy/pem/test.com.pem
# Accept GET requests and skip further checks
http-request allow if { method GET }
# Deny the request if it's missing an Authorization header
http-request deny unless { req.hdr(authorization) -m found }
# Verify the token by invoking the jwtverify Lua script
http-request lua.jwtverify
# Deny the request unless 'authorized' is true
http-request deny unless { var(txn.authorized) -m bool }
# (Optional) Deny the request if it's a POST/DELETE to a
# path beginning with /api/hamsters, but the token doesn't
# include the "write:hamsters" scope
http-request deny if { path_beg /api/hamsters } { method POST DELETE } ! { var(txn.oauth_scopes) -m sub write:hamsters }
# If no problems, send to the apiservers backend
default_backend apiservers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment