Hello I have noticed an issue with v1.26.0 and lambda integration. Reverting to 1.25.0 fixes the issue with no other changes.
Good response with 1.25.0:
Request: /hello?username=kjhlkj
Status: 200
Latency: 311 ms
Response Body
{
“statusCode”: 200,
“body”: {
“message”: “Go Serverless v1.0! Your function executed successfully!”,
“input”: {
“body”: {},
“method”: “GET”,
“principalId”: “”,
“stage”: “test-invoke-stage”,
“cognitoPoolClaims”: {
“username”: “”,
“sub”: “”
},
“headers”: {},
“query”: {
“username”: “kjhlkj”
},
“path”: {},
“identity”: {
“cognitoIdentityPoolId”: “”,
“cognitoIdentityId”: “”,
“apiKey”: “test-invoke-api-key”,
“cognitoAuthenticationType”: “”,
“userArn”: “arn:aws:iam::blah:user/kboutin”,
“apiKeyId”: “test-invoke-api-key-id”,
“userAgent”: “Apache-HttpClient/4.5.x (Java/1.8.0_144)”,
“accountId”: “blah”,
“caller”: “blah”,
“sourceIp”: “test-invoke-source-ip”,
“accessKey”: “blah”,
“cognitoAuthenticationProvider”: “”,
“user”: “blah”
},
“stageVariables”: {}
}
}
}
Bad response with 1.26.0:
Request: /hello?username=kevin
Status: 500
Latency: 69 ms
Response Body
{
“message”: “Internal server error”
}
Response Headers
{}
Logs
Execution log for request test-request
Fri Feb 09 17:01:03 UTC 2018 : Starting execution for request: test-invoke-request
Fri Feb 09 17:01:03 UTC 2018 : HTTP Method: GET, Resource Path: /hello
Fri Feb 09 17:01:03 UTC 2018 : Method request path: {}
Fri Feb 09 17:01:03 UTC 2018 : Method request query string: {username=kevin}
Fri Feb 09 17:01:03 UTC 2018 : Method request headers: {}
Fri Feb 09 17:01:03 UTC 2018 : Method request body before transformations:
Fri Feb 09 17:01:03 UTC 2018 : Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:979912621417:function:testservice-dev-hello/invocations?username=kevin
Fri Feb 09 17:01:03 UTC 2018 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=************************************************************************************************************************************************************************************************************************************************************************************************************************0f64ae, X-Amz-Date=20180209T170103Z, x-amzn-apigateway-api-id=70ka97jslg, X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:blah:70ka97jslg/null/GET/hello, Accept=application/json, User-Agent=AmazonAPIGateway_70ka97jslg, X-Amz-Security-Token=FQoDYXdzEPL//////////wEaDBDQYIDgSd9fOG0VKiK3AwGUKBS9YYPc2wSIGyJoWUNkfJXLuWFRGrmE7/wLJlnwQ3fDLmpXsaNJA0zIoEJunlMHMn/2TUB9Y6bHs+BopsWD9K+XZwvJ7cBt6Gf0hinKoAKUS6mFfkU3CNPGxGVj+YXOy/1r0X3lxKw9hMGq4kZtJm+boPSGz7+pp55cCLF/rOJqge/RDpfGihi874u9MqiwOgts06CEf3VyBkn8J8o5AWtbrbb7XiUDoX+eSZ5YF/thNqMT8Gr/6XmtdbSaShhTCPSTx6+SBlBEse3opWbZWnzgrGOSbSW66+5yrx8kEmKgV6n/HZQC8ZN8Utp2wINicrbUmvSIvE+U [TRUNCATED]
Fri Feb 09 17:01:03 UTC 2018 : Endpoint request body after transformations:
{
“body”: {},
“method”: “GET”,
“principalId”: “”,
“stage”: “test-invoke-stage”,
"cognitoPoolClaims" : {
"username": "",
"sub": ""
},
"headers": {
}
,
"query": {
"username":
"kevin"
}
,
"path": {
}
,
"identity": {
"cognitoIdentityPoolId":
""
, "cognitoIdentityId":
""
, "apiKey":
"test-invoke-api-key"
, "cognitoAuthenticationType":
""
, "userArn":
"arn:aws:iam::blah:user\/kboutin"
, "apiKeyId":
"test-invoke-api-key-id"
, "userAgent":
"Apache-HttpClient\/4.5.x (Java\/1.8.0_144)"
, "accountId":
"blah"
, "caller":
[TRUNCATED]
Fri Feb 09 17:01:03 UTC 2018 : Sending request to https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:blah:function:testservice-dev-hello/invocations?username=kevin
Fri Feb 09 17:01:03 UTC 2018 : Received response. Integration latency: 48 ms
Fri Feb 09 17:01:03 UTC 2018 : Endpoint response body before transformations: {“statusCode”:200,“body”:{“message”:“Go Serverless v1.0! Your function executed successfully!”,“input”:{“body”:{},“method”:“GET”,“principalId”:"",“stage”:“test-invoke-stage”,“cognitoPoolClaims”:{“username”:"",“sub”:""},“headers”:{},“query”:{“username”:“kevin”},“path”:{},“identity”:{“cognitoIdentityPoolId”:"",“cognitoIdentityId”:"",“apiKey”:“test-invoke-api-key”,“cognitoAuthenticationType”:"",“userArn”:“arn:aws:iam::blah:user/kboutin”,“apiKeyId”:“test-invoke-api-key-id”,“userAgent”:“Apache-HttpClient/4.5.x (Java/1.8.0_144)”,“accountId”:“blah”,“caller”:“blah”,“sourceIp”:“test-invoke-source-ip”,“accessKey”:“blah”,“cognitoAuthenticationProvider”:"",“user”:“blah”},“stageVariables”:{}}}}
Fri Feb 09 17:01:03 UTC 2018 : Endpoint response headers: {X-Amz-Executed-Version=$LATEST, x-amzn-Remapped-Content-Length=0, Connection=keep-alive, x-amzn-RequestId=cfa7a9fc-0dba-11e8-8c6d-576e87b479c7, Content-Length=756, Date=Fri, 09 Feb 2018 17:01:03 GMT, X-Amzn-Trace-Id=root=1-5a7dd3cf-a6af3f86c5bd753be9d39243;sampled=0, Content-Type=application/json}
Fri Feb 09 17:01:03 UTC 2018 : Execution failed due to configuration error: No match for output mapping and no default output mapping configured
Fri Feb 09 17:01:03 UTC 2018 : Method completed with status: 500
My serverless.yml:
service: testservice
frameworkVersion: “>=1.2.0 <2.0.0”
custom: ${file(configuration.yml)}
provider:
name: aws
runtime: nodejs6.10
region: us-east-1
vpc:
securityGroupIds: ${self:custom.env.${opt:stage, self:provider.stage}.sg}
subnetIds: ${self:custom.env.${opt:stage, self:provider.stage}.subnet}
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get
cors:
origin: '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
allowCredentials: false
authorizer:
name: authorize
claims:
- username
integration: lambda
request:
parameters:
querystrings:
username: true
authorize:
handler: handler.authorize
Outputs:
IamRoleArnLambda:
Description: "ARN of the lambda IAM role"
Value: {
“Fn::GetAtt”: [
IamRoleLambda, Arn
]
}
The handler.js file:
‘use strict’;
const authorizeHandler = require(’./authorizeHandler’);
const helloHandler = require(’./helloHandler’);
module.exports.authorize = (event, context, cb) =>
authorizeHandler(event, context, cb);
module.exports.hello = (event, context, cb) =>
helloHandler(event, context, cb);
File helloHandler.js:
‘use strict’;
const hello = (event, context, callback) => {
console.log('event: ', event);
const response = {
statusCode: 200,
body: {
message: ‘Go Serverless v1.0! Your function executed successfully!’,
input: event,
},
};
callback(null, response);
};
module.exports = hello;
File authorizeHandler.js:
‘use strict’;
/**
- Generates a policy for AWS API Gateway custom authorization.
- @param {string} principalId The principal Id.
- @param {string} effect ‘Allow’ or ‘Deny’.
- @param {string} resource The method Arn (e.g. event.methodArn =
- (arn:aws:execute-api:::///))
- @return {object} The policy object.
- @private
*/
const _generatePolicy = (principalId, effect, resource) => {
const authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
const policyDocument = {};
policyDocument.Version = ‘2012-10-17’;
policyDocument.Statement = [];
const statementOne = {};
statementOne.Action = ‘execute-api:Invoke’;
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
return authResponse;
};
/**
-
Determine if request is authorized and filters the request appropriately.
-
@param {object} event The request event.
-
@param {object} context The context.
-
@param {callback} callback The callback function to call after determining if authorized.
-
@return {object} The callback function.
*/
const authorize = (event, context, callback) => {
let error = null;
let policy = null;
console.log(event);
if (event.query && event.query.username) {
policy = _generatePolicy(event.query.username, ‘Allow’, event.methodArn);
policy.context = event.query;
console.log(User, ${event.query.username}, is authorized to access.
);
return callback(null, policy);
} else {
console.log(‘Unable to validate user authorization.’);
error = ‘Unauthorized’;
}if (error) {
console.log(User not authorized to access: ${event.methodArn.path}
);
return callback(error);
// context.fail(error);
}
};
module.exports = authorize;