Paulo
01/30/2021, 2:59 PMhttpApi
event type in sls), which I also didn't know.
So, using httpApi
I'm able to define the required scopes
for my function. Is there a way to do something similar using the regular http
event type and a custom authorizer?
Also, what do you usually use in terms of AGW API type: REST or HTTP? I saw this page but would like to know about real experiences...
ThanksFrank
Frank
Frank
Paulo
01/30/2021, 5:59 PMPaulo
01/30/2021, 6:04 PMimport util from 'util';
import jwksClient from 'jwks-rsa';
import jwt from 'jsonwebtoken';
import debug from '../../../common/lib/debug';
import { handler } from "../../../common/lib/handler";
const getPolicyDocument = (effect, resource) => {
const policyDocument = {
Version: '2012-10-17', // default version
Statement: [{
Action: 'execute-api:Invoke', // default action
Effect: effect,
Resource: resource,
}]
};
return policyDocument;
};
// extract and return the Bearer Token from the Lambda event parameters
const getToken = (params) => {
if (!params.type || params.type !== 'TOKEN') {
throw new Error('Expected "event.type" parameter to have value "TOKEN"');
}
const tokenString = params.authorizationToken;
if (!tokenString) {
throw new Error('Expected "event.authorizationToken" parameter to be set');
}
const match = tokenString.match(/^Bearer (.*)$/);
if (!match || match.length < 2) {
throw new Error(`Invalid Authorization token - ${tokenString} does not match "Bearer .*"`);
}
return match[1];
};
const jwtOptions = {
audience: process.env.AUDIENCE,
issuer: process.env.TOKEN_ISSUER
};
const client = jwksClient({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 10, // Default value
jwksUri: process.env.JWKS_URI
});
const getSigningKey = util.promisify(client.getSigningKey);
const authenticate = async (params) => {
const token = getToken(params);
const decoded = jwt.decode(token, { complete: true });
if (!decoded || !decoded.header || !decoded.header.kid) {
throw new Error('invalid token');
}
const key = await getSigningKey(decoded.header.kid);
const signingKey = key.publicKey || key.rsaPublicKey;
const verified = jwt.verify(token, signingKey, jwtOptions);
return {
principalId: verified.sub,
policyDocument: getPolicyDocument('Allow', params.methodArn),
context: { scope: verified.scope }
};
};
export const main = handler(async (event) => {
try {
return await authenticate(event);
} catch (e) {
debug(e);
return {
policyDocument: getPolicyDocument('Deny', event.methodArn),
};
}
});
Paulo
01/30/2021, 6:07 PMRoss Coundon
02/01/2021, 9:58 AM