Reputation: 381
I have drafted the following architecture
I'm having issues on the validate JWT part on the gateway (Not sure if this is how it's supposed to work).
From what I understand, when a request gets to the gateway, Express Gateway does the JWT validation against the credentials we've set up in the config.
Here is a snippet of gateway.config.yml:
policies:
- proxy
- logging
- jwt
- oauth2
pipelines:
service1:
apiEndpoints:
- service1
policies:
- logging:
- oauth2:
- action:
- jwt:
subject: 'cognito-app-client-id'
algorithms: [ 'alg' ]
checkCredentialExistence: false/true
issuer: 'cognito-issuer'
secretOrPublicKey: 'pub key from cognito'
audience: 'cognito-app-client-id'
clientId: 'cognito-app-client-id'
clientSecret: 'cognito-app-client-secret'
Note that secretOrPublicKey was retrieved from this URL: https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json and it returned the following:
{
"keys": [
{
"alg": "",
"e": "",
"kid": "",
"kty": "",
"n": "",
"use": ""
}
]
}
To test my endpoint, I made the following request to the gateway including the JWT I got from Cognito.
curl --location --request POST 'https://mygateway/service1' \
--header 'Authorization: Bearer eyYg...' \
--data ''
However I get a 401 (Unauthorized).
Somewhere, somehow, I'm missing something. I just don't know if I'm misunderstanding the whole flow, or I'm not setting up my config properly.
Does anyone have an idea of what I'm possibly missing, or the possible solution?
Upvotes: 0
Views: 137
Reputation: 381
Here is what I did to fix the issue.
Fetch my Cognito app-client JWK from this URL: https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json
Response:
{
"keys": [
{
"alg": "",
"e": "",
"kid": "",
"kty": "",
"n": "",
"use": ""
}
]
}
Convert the JWK to a .pem file (there are online tools for this), but for confidentiality purposes, I wrote this python script to do the conversion:
import json
from jwcrypto import jwk
jwk_data = {
"alg": "replace with actual value from jwk",
"e": "replace with actual value from jwk",
"kid": "replace with actual value from jwk",
"kty": "replace with actual value from jwk",
"n": "replace with actual value from jwk",
"use": "replace with actual value from jwk"
}
key = jwk.JWK(**jwk_data)
public_key = key.export_to_pem()
with open('public_key.pem', 'wb') as pem_file:
pem_file.write(public_key)
Of course you'll need to install jwcrypto with
python3 -m pip install jwcrypto
After generating the .pem file, I updated my gateway.config.yml as follow:
pipelines:
service1:
apiEndpoints:
- service1
policies:
- logging:
- jwt:
- action:
secretOrPublicKeyFile: cert/public_key.pem #cert is the folder where my .pem file is located.
checkCredentialExistence: false
- service1:
Making a cURL request to the gateway with the correct JWT now returns the desired output.
curl --location --request POST 'https://mygateway/service1' \
--header 'Authorization: Bearer eyYg...' \
--data ''
Upvotes: 1