We are seeing some odd behavior with AWS API Gateway and Auth0 Authorizers. We are getting random 403 errors back from our APIs(Lambdas).
We can hit an API and get a 200 back. Then, seconds later, we are getting a 403 out of the blue.
{“Message”:“User is not authorized to access this resource”}
Doing some digging around, it sounds similar to this issue:
https://forums.aws.amazon.com/thread.jspa?threadID=225934&tstart=0
However, I don’t think that post is using Auth0, but I am not 100% sure.
Has anybody experienced something similar?
Your issue sounds familiar. Let me explain the issue I had a while ago maybe it helps you.
I used the custom authorizer and in API Gateway and disabled the Cache. In spite of that it cached the authorize request!
I was sending GET and POST to the same resource. First time that I send a GET the request, it worked fine. Any GET request would work fine but I couldn’t send a POST request for that resource. If I would wait for few minutes and send a POST, it would work again but this time GET had problem.
I solved this issue by changing the returned policy. Each time I send back the policy I allow both GET and POST for that resource. If this change doesn’t make any vulnerability on your system you can try it.
Thanks, @armanfatahi! When you say “send back the policy I allow both GET and POST for that resource”, is that done on the API Gateway or somewhere else?
It’s done in the custom authorizer.
The custom authorizer checked the access_token and creates a policy. Then return the policy to API Gateway.
If you are using the custom authorizer Auth0 introduced, you should see this in the lib.js:
jwt.verify(token, signingKey, { audience: process.env.AUDIENCE, issuer: process.env.TOKEN_ISSUER },
function (err, decoded) {
if (err) {
cb(err);
}
else {
cb(null, {
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', params.methodArn),
context: {
scope: decoded.scope
}
});
}
});
I changed this code to:
...
jwt.verify(token, signingKey, { audience: process.env.AUDIENCE, issuer: process.env.TOKEN_ISSUER },
function (err, decoded) {
if (err) {
cb(err);
}
else {
cb(null, {
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', "*";),
context: {
scope: decoded.scope
}
});
}
});
Which means if the user is authorized, allow using the whole API resources, this includes GET and POST for each resource.
Thanks a lot for sharing it with the rest of community!
I have been struggling with this issue for a few days now…
Thanks for the solution @armanfatahi