Hello,
We have implemented an AWS lambda function in C# (.NET8). This lambda is an authorizer in our API Gateway. Its role is to decided if the received request can be sent to the api behind the gateway.
As we use the Authorization Code Flow, the request will contain a json web token signed by our Auth0 private key.
One of the contraints is that with the lambda function, we pay for the execution time. Thus, to avoid reading a public key each time to validate the token, we want to cache it in our AWS storage (retrieve it is free and very fast). The caching will be done in clear text. In case of the public key would change during its caching period, we have mechanism to read the new key and cache it. We don’t use any dependency injection, and we minimize the amount of external libraries as much as possible.
My question is : what is the best way to validate this token?
We considered several options:
-
Read the public key from “[our-domain].auth0.com_pem” and validating the token. How do we get the kid for this public key? Is there any url to get it?
-
Read the openid signing keys from “[our-domain].auth0.com_.well-known_openid-configuration” and validating the token. The problem is that keys don’t seem to be serializable. We follow this example: “developer.okta.com_code_dotnet_jwt-validation”. Is there a way to serialize them?
-
Read the Json web key set from “[our-domain].auth0.com_.well-known_jwks.json” and validate the token. In our case, this json document contains 2 different public keys with their kid. This json document (or part of it) would be easily serializable. Since we don’t know which public key to use to validate the token, we should try one key, and if it fails, try the other. Since we don’t know if we could have more than 2 keys, we would have to try all the keys until one of them succeeds.
Thank you.
Bellow is the code to validate the token from a public key.
public ClaimsPrincipal? GetClaimsPrincipal(string authToken, string publicKey, string keyId)
{
var rsaPublicKey = RSA.Create();
rsaPublicKey.ImportFromPem(publicKey);
var rsaKey = new RsaSecurityKey(rsaPublicKey) { KeyId = keyId };
var tokenHandler = new JwtSecurityTokenHandler();
var validationParams = new TokenValidationParameters
{
IssuerSigningKey = rsaKey,
ValidAudience = "an-audience",
ValidIssuers = ["issuer1", "issuer2"],
SignatureValidator = (token, _) => new JwtSecurityToken(token)
};
try
{
ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(authToken, validationParams, out _);
return claimsPrincipal;
}
catch (Exception ex)
{
//Log an error
return null;
}
}