AnthonyDeroche / mod_authnz_jwt

An authentication module for Apache httpd using JSON Web Tokens
Other
79 stars 46 forks source link

Cognito integration #6

Open andrewlear opened 7 years ago

andrewlear commented 7 years ago

We are utilizing Apache HTTP server as a gateway in AWS for APIs and front-end web code in S3 buckets. We currently use mod_auth_mellon for authentication and pass user information in headers back to our API's when a client successfully authenticates.

We are looking to switch to AWS Cognito for authentication utilizing JWT.

I have been experimenting with your module. On it's own, I can utilize JWT to grant access to protected URI's. When I attempt to utilize it with Cognito, I am running into errors.

Steps used to recreate:

  1. Harvest jwks.json for our specific user pool in Cognito. https://cognito-idp.us-east-1.amazonaws.com//.well-known/jwks.json I pull the one public key from it that our JWT tokens are signed with.
  2. Run that public key through the following process: Convert it to pem: https://runkit.com/npm/jwk-to-pem
  3. Trim out all unnecessary info from pem: openssl rsa -inform pem -in FILEPATH.pem -pubin -pubout -RSAPublicKey_in

When I put the JWT token I have and the fully processed pem into the debugger on https://jwt.io, the signature validates correctly. However, when I throw them into Apache utilizing mod_authz_jwt, I get an invalid token and/or invalid signature error.

The problem is 2-fold, Cognito exposes 2 keys through the jwks.json and this module claims invalid token/signature when converting one of the keys for static use. Can you modify this module so I can pass it the URL for the jwks.json file and have the module harvest and covert those keys?

AnthonyDeroche commented 7 years ago

Hello,

The token should be correctly decoded if you transform the public exponent "n" of your jwks into a valid PEM RSA public key. To validate signature, I'm using libjwt (https://github.com/benmcollins/libjwt) using itself openssl.

Can you give me public keys in PEM format used to check validation and a JWT (even expired) delivered by AWS to try to help you more ? You can email me at anthony[at]deroche.me

Regarding the last question, I cannot support JWKS for the moment in my module, although it might be interesting to do so. The underlying library I'm using does not support JWKS itself. I will propose it on the tracker.

andrewlear commented 7 years ago

Thanks. I emailed you the requested items. Did you receive them? Thanks.

AnthonyDeroche commented 7 years ago

Hello, yes I received your email. I will take a look at this and I will keep you posted.

AnthonyDeroche commented 7 years ago

I reproduced the bug, and it seems to be a bug of the underlying lib I'm using to decode tokens. I opened an issue on the repo of the lib. I will keep you posted as soon as I have more information.

AnthonyDeroche commented 7 years ago

The bug has been fixed, you should be able to validate tokens using my module using a PEM public key. Be careful to use libjwt v1.7.3, I updated the README with the correct version.

andrewlear commented 7 years ago

Thank you. I will put libjwt 1.7.3 into the lab and will update you with the findings.

andrewlear commented 7 years ago

I have been able to confirm that if I utilize the correct key that the JWT will validate. However, a Cognito user pool utilizes 1 of 2 keys to sign the JWT. Is there a mechanism that I can utilize to specify both keys as 2 AuthJWTSignaturePublicKeyFile entries in the Apache config, or add both keys to 1 file and have the module iterate over both keys to validate the JWT?

If you require a new JWT, let me know and I can supply that via email. Thanks.

andrewlear commented 7 years ago

I hate to be a bother with this, but are you actively working on this or can I have a friend of mine submit a pull request to work on this functionality? Thanks.

AnthonyDeroche commented 7 years ago

I just saw your messages, I'm not working on this for now, you can submit a pull request!