Last active
September 16, 2022 19:16
-
-
Save haproxytechblog/74079ba7df75e3095cc3f872f8b560e4 to your computer and use it in GitHub Desktop.
Verify OAuth JWT tokens with HAProxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ openssl x509 -pubkey -noout -in ./myaccount.pem > pubkey.pem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ curl --request POST \ | |
--url https://myaccount.auth0.com/oauth/token \ | |
--header 'content-type: application/json' \ | |
--data '{"client_id":"abcd12345….","client_secret":"ABCD12345…","audience":"https://api.mywebsite.com","grant_type":"client_credentials"}' | |
{ | |
"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...", | |
"scope":"read:myapp write:myapp", | |
"expires_in":86400, | |
"token_type":"Bearer" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alg": "RS256", | |
"typ": "JWT" | |
} | |
{ | |
"iss": "https://myaccount.auth0.com/", | |
"aud": "https://api.mywebsite.com", | |
"exp": 1662753594, | |
"scope": "read write", | |
"gty": "client-credentials" | |
} | |
{ | |
// RSASHA256 signature | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
frontend myapi | |
bind :80 | |
bind :443 ssl crt /etc/haproxy/certs/foo.com/cert.crt alpn h2 | |
http-request redirect scheme https unless { ssl_fc } | |
http-request deny content-type 'text/html' string 'Missing Authorization HTTP header' unless { req.hdr(authorization) -m found } | |
# get header part of the JWT | |
http-request set-var(txn.alg) http_auth_bearer,jwt_header_query('$.alg') | |
# get payload part of the JWT | |
http-request set-var(txn.iss) http_auth_bearer,jwt_payload_query('$.iss') | |
http-request set-var(txn.aud) http_auth_bearer,jwt_payload_query('$.aud') | |
http-request set-var(txn.exp) http_auth_bearer,jwt_payload_query('$.exp','int') | |
http-request set-var(txn.scope) http_auth_bearer,jwt_payload_query('$.scope') | |
# Validate the JWT | |
http-request deny content-type 'text/html' string 'Unsupported JWT signing algorithm' unless { var(txn.alg) -m str RS256 } | |
http-request deny content-type 'text/html' string 'Invalid JWT issuer' unless { var(txn.iss) -m str https://myaccount.auth0.com/ } | |
http-request deny content-type 'text/html' string 'Invalid JWT audience' unless { var(txn.aud) -m str https://api.mywebsite.com } | |
http-request deny content-type 'text/html' string 'Invalid JWT signature' unless { http_auth_bearer,jwt_verify(txn.alg,"/etc/haproxy/pubkey.pem") -m int 1 } | |
http-request set-var(txn.now) date() | |
http-request deny content-type 'text/html' string 'JWT has expired' if { var(txn.exp),sub(txn.now) -m int lt 0 } | |
http-request deny if { path_beg /api/ } { method GET } ! { var(txn.scope) -m sub read } | |
http-request deny if { path_beg /api/ } { method DELETE POST PUT } ! { var(txn.scope) -m sub write } | |
default_backend servers | |
backend servers | |
balance roundrobin | |
server web1 192.168.56.31:3000 check maxconn 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ curl --request GET \ | |
-k \ | |
--url https://192.168.56.20/ \ | |
--header 'authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment