简体   繁体   中英

AWS AppSync Lambda Authorizer

I just implemented a lambda resolver in AWS AppSync. The lambda and AppSync live in different projects; The template that provisions the function writes the function ARN to SSM and the template that builds AppSync pulls that SSM parameter down and assigns that ARN to an AdditionalAuthenticationProvider .

The deploy process goes in order synchronously; Lambda (create auth function, set ARN to SSM param) -> AppSync (create API, retrieve SSM param and assign to authorization provider). When I examine the console, I can see the correct function ARN is assigned as the authentication provider to AppSync.

The problem: when I go to issue a request, the lambda is never invoked, I can check CloudWatch and verify no invocations - I am just met with the response.

{
  "errors" : [ {
    "errorType" : "BadRequestException"
  } ]
}

If I do not provide a value to the authorization header, I get a 401 - which is the expected behavior of the lambda authorization directive, rejecting any requests without a value in that header before proceeding to the function. So it would appear that something isn't plumbed correctly, something is missing that I can't find in a doc to allow invocation.

The gotcha: if I go into the console and assign this same function ARN manually, everything works fine and stays working fine. It would seem that, perhaps, the console is doing something behind the scenes that my deploy is not, but I cannot seem to correctly identify what is missing.

I've been following this document https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#aws-lambda-authorization and one note gives me pause - and I have set these trust permissions, AFAIK.

Lambda functions used for authorization require a principal policy for appsync.amazonaws.com to be applied on them to allow AWS AppSync to call them. This action is done automatically in the AWS AppSync console

Here is the SAM template (without input params)


Resources:
  ServiceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: [ lambda.amazonaws.com, appsync.amazonaws.com ]
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: logs
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "*"
              - Effect: Allow
                Action:
                  - xray:*
                Resource: "*"
        - PolicyName: ssm
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: ssm:*
                Resource: "*"

  LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref AuthorizationFunction
      Action: lambda:Invoke
      Principal: appsync.amazonaws.com
      
  AuthorizationFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: <code-uri>
      Handler: app.lambda
      Runtime: nodejs14.x
      Role: !GetAtt ServiceRole.Arn
      Tracing: Active

  FunctionARNParameter:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Name: <name>
      Value: !GetAtt AuthorizationFunction.Arn

Maybe typing it out my problem was just what I needed. The last thing I tried, LambdaPermission was the key - but the action was incorrect and needed to be InvokeFunction . I also chose to assign the FunctionName as the lambda ARN instead of the name

LambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !GetAtt PPSAuthorizationFunction.Arn 
      Action: lambda: InvokeFunction # <--
      Principal: appsync.amazonaws.com

Hope this is useful to someone!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM