If you are using Auth0 (or some OAuth authorization service) then you will most likely be interested in using JWT tokens via some kind of grant. Auth0 discusses how to call an API with such a token.
Perhaps you wish to use a custom authorizer for your serverless project.
To do so, you must write code to decode the JWT token before creating a policy (or not) to grant invoke permissions on your LF. Per various recommendations, the best method to protect your JWT tokens is to use RS256 signing.
However, if you are using pyjwt to decode RS256 tokens, this library depends upon cryptography and that, in turn, has compiled dependencies. If you try something like pip install cryptography -t .
or pip install pyjwt[crypto] -t .
to install the dependencies into your serverless project on OSX, then you will find that it doesn't work when you deploy on AWS.
You might see an error, something like:
No module named '_cffi_backend'
This is because pip
looked at your machine and decided that you need the OSX compiled dependencies. However, LFs run on Linux.
To solve the issue, you should find a Linux version of the installation package(s) that work with AWS Lambda's environment, as described in principle in this AWS article.
For installing cryptography
in particular, you can do the following:
- Install JWT as per usual into your serverless project -
pip install jwt -t .
- Visit the
cryptography
PyPi downloads page and download the appropriate-manylinux1_x86_64.whl
package for your version of Python and save it in your serverless project. - Decompress the wheel file into your project
unzip <your_wheel_file>
- Visit the
cffi
PyPi downloads page and choose the relevant.whl
package - Decompress the wheel file into your project
unzip <your_wheel_file>
- Install the
asn1crypto
dependency locally:pip install asn1crypto -t .
Now you have all the components needed to decode a RS256 JWT in your AWS LF using Python.
If using RS256, you will need to have your public key. For example, this will be available via Settings > Advanced Settings
in your Auth0 application, assuming you use Auth0. You need to look under the tab Certificates
where you will find the certificate and an option to download. You should download as a PEM to your serverless project.
However, you will not be able to use the PEM directly in your Python. You first need to convert it to a public key. You can do this using:
openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
You can then open the pubkey.pem
and paste it as a string into your Python code, something like:
public_key = b'-----BEGIN PUBLIC KEY-----\nMHYwEAYHKoZIzj0CAQYFK4EEAC...'
It is now available for you to decode the JWT via the Authorization Bearer <jwt_token>
header which is exposed to your custom authorizer in the event
variable: event['authorizationToken']
You can now decode your JWT:
tok = str(event['authorizationToken'])
jwt_token = tok.split(' ')[1]
audience = 'audience_set_in_api_on_auth0'
decoded = jwt.decode(jwt_token, pk, audience=audience, algorithms='RS256')
Of course, you might want to add various error handles to the above, but you get the idea.
Cheers, and happy JWT decoding.
What is the purpose of the
asn1crypto
library? Is it for converting downloaded PEM to a usable public key? I'm retrieving public key from remote .well-known and this layer seems to work fine without it...