Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging AWS HTTP API (beta) JWT Authorizer

I am experimenting with the AWS Api Gateway's beta "HTTP API" functionality.

As part of this experimentation I am trying to authorize access to the api using a "JWT Authorizer":

https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html

The documentation states that the JWT will go through a workflow consisting of a series of checks/verification on the JWT before it is authorized, or rejected.

Without the authorizer, the endpoint is accessible. With the authorizer I get a 401 response with the json:

{"message":"Unauthorized"}

I am trying work out at which step the Authorizer is rejecting the JWT. I have setup a log for the api endpoint and see the request coming in, but it provides no insights into why the authorization is failing.

Is there a way to debug why/where the authorizer is failing?

Note: This is not talking about lamda authorizers, and I am not using Cognito to generate the JWT.

like image 242
James P McGrath Avatar asked Mar 03 '23 22:03

James P McGrath


2 Answers

401 means that the authentication of the user could not be established. Basically, the JWT is either faulty or is not being provided with the request in the header that API Gateway is expecting.

Also, API Gateway is not a full blown server, so won't get to debug how API gateway is making use of the JWT. While that maybe a bummer, please do note that it does provide you a highly scalable, reliable and cheap HTTP endpoint for your backend with a built in JWT based authentication support and it just became available across most of the regions. So, I wouldn't cross it out just yet.

Coming back to your question. Though I don't know how to help with the debug part. I can tell you the steps I took to experiment with the JWT authorizer without writing a single line of code.

  1. Created a temp JWK via https://mkjwk.org/ which gives you a public key and private + public key pair set using a kid of your choice and RS256 algo
  2. Copy the public key and insert it in your ISSUER_URL/.well-known/jwks.json. If you are not using Cognito, you can carry out the experiment with placing the file in S3 (your S3 bucket url becomes the issuer url in this case). If using S3, you will also need to create ISSUER_URL/.well_known/openid-configuration file and make these files publicly available for the duration of the experiment. These files follow a standard format (OIDC) which you can search online. Do note that the jwks.json file only contains only the public key, so it doesn't matter even if someone else gets their hands on it.
  3. Take the private + public key pair set and go to https://8gwifi.org/jwkconvertfunctions.jsp to get separate private and public RSA pem keys
  4. Go to https://jwt.io/ and pick RS256 algo, kid header claim (using the same value used to generate the keys in the first step), aud claim in the payload (this should match the configuration you chose while setting JWT authorizer in HTTP API gateway), iss claim in the payload (this should match the ISSUER_URL), exp claim in the payload (expiry time of the JWT, you can use https://www.epochconverter.com/), nbf claim in the payload (just take the current timestamp from https://www.epochconverter.com/) and also the public and private RSA pem keys that you got from the previous step are to placed in their corresponding signature section. Also provide the scp payload claim if you set the authorization scope while setting up JWT authorizer with HTTP API gateway

After doing all of this, I was able to test out that API gateway was able to work with the JWT that I generated. Now, I can go about coding this thing with more confidence and luckily, there are tools in JAVA, node, etc, already available.

like image 116
Ashish Goel Avatar answered Mar 07 '23 06:03

Ashish Goel


Take a look at the response. There is a header called www-authenticate, which contains an error response, if authentication failed.

i.e:

www-authenticate: Bearer scope="" error="invalid_token" error_description="JWKS communication error"

If you use curl, you can try it with -v to see the full response including the header.

like image 42
Jörn Krüger Avatar answered Mar 07 '23 05:03

Jörn Krüger