aws-appsync-community icon indicating copy to clipboard operation
aws-appsync-community copied to clipboard

AppSync returns Unauthorized when using Lambda Authorizer

Open danitornow opened this issue 2 years ago • 15 comments

When utilizing the AWS Lambda Authorizer for AppSync as a secondary option, unable to get any request to come back as authorized. As part of testing, set the Authorizer to return true in every circumstance, but it was still returning an ‘Not Authorized’ error in AppSync. It appears that this is an issue with AppSync and it's Lambda Authorizer. I am able to confirm it calls the Lambda, and the response is hardcoded to be true, but it still fails in the AWS AppSync console saying it is unauthorized. We are able to perform our queries with the API Key in the Console but it fails and says ‘Unauthorized’ with the AWS Lambda Authorizer for the same query.

We are deploying AppSync via CloudFormation, utilizing Serverless Framework and the AppSync plugin.

The return from the Lambda was hardcoded (for testing) to this:

{
  "isAuthorized": true,
  "resolverContext": {}
}

The error message in AppSync:

  "data": {
    "getEvent": null
  },
  "errors": [
    {
      "path": [
        "getEvent"
      ],
      "data": null,
      "errorType": "Unauthorized",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Not Authorized to access getEvent on type Query"
    }
  ]
}

Made sure to include resolverContext due to this thread about Amplify issues with AppSync. GitHub thread about Amplify issue with AppSync Lambda Auth: https://github.com/aws-amplify/amplify-cli/issues/10047

Testing with an empty resolverContext and non-empty resolverContext produced the same results.

Lambda Code, Typescript compiled to Node 14:

Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;

async function handler(lambdaEvent) {

    console.log('Received event context: {}', JSON.stringify(lambdaEvent.requestContext));
    return {
        isAuthorized: true,
        resolverContext: {}
    };
}
exports.handler = handler;
//# sourceMappingURL=authenticate.js.map

Example of Context coming from AppSync invocation:

    "apiId": "zpaawy2f7rbqdpupeik44az6wm",
    "accountId": "$$$$$$$$$$$",
    "requestId": "596b0f97-a6eb-47e0-bf98-f6659fc27df0",
    "queryString": "query MyQuery {\n  getEvent(id: \"2193\") {\n    location {\n      name\n    }\n    name\n    start_time\n    end_time\n  }\n}\n",
    "operationName": "MyQuery",
    "variables": {}
}

danitornow avatar Mar 31 '22 15:03 danitornow

I'm experiencing the exact same behaviour also from aws console, using lambda response with isAuthorized fixed to true.

gabrieleCutowl avatar Apr 14 '22 12:04 gabrieleCutowl

Having the same issue, getting Not Authorized when returning isAuthorized: true.

toha87 avatar Apr 14 '22 15:04 toha87

Same here.

fomson avatar Apr 18 '22 03:04 fomson

Same here

sivivan avatar Apr 21 '22 09:04 sivivan

Having done a bit more investigation it appears that this issue is only present when having multiple authorizers, i.e. Lambda Authorisation as a secondary authorization option (with API key being the first). If I were to test Lambda authorization on its own then the same lambda function works just fine.

I have tried swapping the order, i.e. using lambda as default and api key as a secondary and now API key throws the same error.

sivivan avatar Apr 21 '22 09:04 sivivan

@sivivan, could you please elaborate a bit more? :)

By any chance, is this comment relevant to what you are suggesting? :)

fomson avatar Apr 21 '22 15:04 fomson

@fomson basically it appears that Appsync only has issues if two or more auth mechanisms are configured. You can use either Lambda or API key just fine when just one of them is configured. The moment you add a second one the second auth method that you have added will throw an error of "Not Authorized to access on type Query".

sivivan avatar Apr 21 '22 16:04 sivivan

@snvishna, what do you mean by "Lambda" auth mechanism?

In Transformer v1, in my GraphQL [AppSync], I have set up two authorisation modes: IAM (default) and Amazon Cognito User Pool.

As Lambdas are supposedly "private", in my GraphQL schema, on my Type(s), one of the @auth rules I have is {allow: private, provider: iam, operations: [create, update, delete, read]}. I think this means that anything that has "authed IAM role" [incl. my Lambda] will be able to do all those "operations" on the Type [incl. Amplify-generated resolvers]. I did give my Lambda access to my API/GraphQL [and Type(s)] in amplify MY_FUNCTION update...

So, do you suggest that in Transformer v2, if I had only one authorisation mode [either IAM or User Pool], things would work?

fomson avatar Apr 21 '22 16:04 fomson

@fomson apologies I am not familiar what Transformer v2 is.

I am just using the AWS Appsync (without using Amplify) directly.

But, yes, this is what I suggest is the root cause. Try testing with just one authorisation mode and see if things work.

For me the problem occurs when I have two modes added, i.e. API_KEY and Lambda auth modes.

In your case it might be due to IAM and User Pool being the two modes.

sivivan avatar Apr 21 '22 19:04 sivivan

@sivivan I see. My apologies too for bringing confusion with Amplify [just noticed that this thread has nothing to with Amplify]

Either way, it does seem that there is something wrong with authorisation. Up until very recently, both IAM and User Pool worked well for me. It would not make sense to only allow one way to authorise as depending on the type of user, different operations could be permitted...

I will keep this thread in mind if a solution occurs for [my] Amplify-linked AppSync issues :)

fomson avatar Apr 21 '22 20:04 fomson

For anyone running into the same issue, I had this error and managed to resolve it - Query was explicitly defined, and i had to add the @aws_lambda directive to it, in addition to adding the same directive to the type itself. Once i added both, the request seemed to work fine. Screenshot 2022-07-07 at 4 12 36 PM Screenshot 2022-07-07 at 4 13 41 PM

NourDT avatar Jul 07 '22 14:07 NourDT

same here when we upgraded aws-cdk to v2

JandenMa avatar Sep 09 '22 11:09 JandenMa

Having done a bit more investigation it appears that this issue is only present when having multiple authorizers, i.e. Lambda Authorisation as a secondary authorization option (with API key being the first). If I were to test Lambda authorization on its own then the same lambda function works just fine.

I have tried swapping the order, i.e. using lambda as default and api key as a secondary and now API key throws the same error.

This sums up the problem. I can also reproduce it with the query client of appsync, if you set an api key as secondary authentication providers, even if you select it in the query client setting any queries will throw Unauthorized

jbreuil avatar Jun 16 '23 15:06 jbreuil

I am facing the same issue when my default mode is API_KEY and OIDC as additional mode. I keep getting unauthorized.

As soon as i make OIDC as deafult with the same configuration, it starts working.

Can please someone confirm if the same behavior happening with aws_lambda as additional mode happens with OIDC as additional mode

nits1991 avatar Jan 30 '24 20:01 nits1991