2
votes

I am creating a Cognito user pool with Cloudformation and setting LambdaConfig -> PreAuthentication to a Lambda function also created with Cloudformation. The problem is that the Lambda function seems to not be invoked. When authenticating, the user is logged in without the intervention of the PreAuthentication logic and the Cloudwatch logs for the lambda function are empty. If I test the function in the Lambda dashboard, it functions correctly. I'm not getting any errors.

Additionally, I am modeling this Cloudformation setup on an existing setup that does work. And the resources that result from the Cloudformation stack seem to have the same configuration as the working version.

The relevant parts of the cloudformation template look like this:

  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      LambdaConfig:
        PreAuthentication: !GetAtt UserAuthorizerFunction.Arn
      UsernameAttributes:
        - email
      UsernameConfiguration:
        CaseSensitive: false

The Lambda function is defined like:

  UserAuthorizerFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: Authorize_Users
      Description: Authorizes users
      Handler: index.handler
      Role: !GetAtt AuthorizerFunctionRole.Arn
      Code:
        ZipFile: |
          const AWS = require('aws-sdk')
          // stuff
      Runtime: nodejs12.x

The lambda function is created with a resource-based policy that looks correct:

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "AuthorizerFunctionPermission-WSIGC4MBBT0C",
      "Effect": "Allow",
      "Principal": {
        "Service": "cognito-idp.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-1:<redacted>:function:Authorize_Users",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:cognito-idp:us-east-1:<redacted>:userpool/us-east-1_<redacted>"
        }
      }
    }
  ]
}

Why isn't my PreAuthentication hook being executed? Is there a DependsOn requirement that I'm not thinking of?

1
Are you sure the permissions are correct? The function arn suggest the name Authorize_Users but your function has name ${StackName}_Authorize_Users? Also how did you create these permissions? There is no CFN code shown for them.Marcin
Thank you Marcin. My fault about function name / arn. When I created the question above, I simplified things a bit. The FunctionName and the ARN in the resource-based policy actually do match. I updated the question above to show that. re: CFN code and creating permissions - I'm not sure what you mean. The resource-based policy seems to be created automatically because I am using the function as a cognito trigger.Ben Gladwell
I'd agree it's most likely to be permissions. I have no experience with Cognito, but with API Gateway you can get similar behaviour when the service doesn't have rights to invoke the lambda. The last resource does seem to grant the appropriate access, though I'm used to seeing this as a AWS::Lambda::Permission resource rather than a policy. Strange that it's JSON and the other bits are YAML, are they in separate templates? If so, does the userpool not have access to the lambda at the time it's created? That could be the issue... seems to ring a bell.404
Thanks for looking at this 404. The JSON that you are seeing came from the Lambda console page on the Permissions tab. So it's separate from the Cloudformation yaml template. The JSON is actually part of the result of creating the cloudformation stack with the yaml.Ben Gladwell

1 Answers

1
votes

It turned out to be a known issue - at least, others are experiencing it: https://forums.aws.amazon.com/thread.jspa?messageID=897845&#897845

I needed to remove the ALLOW_CUSTOM_AUTH auth flow option and use ALLOW_USER_PASSWORD_AUTH.