te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - AWS authorizer returns 500, message: null, with AuthorizerConfigurationException error in response - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AWS authorizer returns 500, message: null, with AuthorizerConfigurationException error in response - Stack Overflow

programmeradmin3浏览0评论

I've spent the better part of today trying to make authorizers work, I've checked multiple examples and they all seem to be doing the same thing my code does.

I use serverless framework here's the authorization code:

exports.handler = function (event: APIGatewayTokenAuthorizerEvent): APIGatewayAuthorizerResult {
    const authorizer = new Authorizer();

    try {
        if (!event.authorizationToken) throw new Error("No token");

        const token = event.authorizationToken.split(" ")[1];
        const decodedData = authorizer.verifyToken(token) as unknown as User;
        const policy = generatePolicy(token, event.methodArn);

        return {
            ...policy,
            context: {
                user: JSON.stringify(decodedData),
            },
        };
    } catch (err) {
        console.log(err);
        throw "Unauthorized";
    }
};

const generatePolicy = (principalId: string, methodArn: string) => {
    return {
        principalId,
        policyDocument: {
            Version: "2012-10-17",
            Statement: [
                {
                    Action: "execute-api:Invoke",
                    Effect: "Allow",
                    Resource: methodArn,
                },
            ],
        },
    };
};

and here's the serverless config

const serverlessConfiguration: AWS = {
service: "user-crud",
frameworkVersion: "2",
custom: {
    webpack: {
        webpackConfig: "./webpack.config.js",
        includeModules: true,
    },
},
plugins: ["serverless-webpack"],
provider: {
    name: "aws",
    runtime: "nodejs14.x",
    region: "eu-west-1",
    apiGateway: {
        minimumCompressionSize: 1024,
        shouldStartNameWithService: true,
    },
    environment: {
        AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
    },
    lambdaHashingVersion: "20201221",
},

functions: {
    jwtAuthorizer: {
        handler: "src/api/authorizer.handler",
        name: "jwtAuthorizer",
    },
    get: {
        name: "get",
        handler: "src/api/get.handler",
        role: "arn:aws:iam::109394173706:role/dynamodb_cloudwatch_full",
        events: [
            {
                http: {
                    path: "get",
                    method: "get",
                    cors: true,
                    authorizer: "jwtAuthorizer",
                },
            },
        ],
    },

}...

I always get 500 response when the token is correct and I return the object, so I guess there's something wrong with the return object?

If the token is incorrect and I throw "Unauthorized" then I get back the correct 401 response.

I've spent the better part of today trying to make authorizers work, I've checked multiple examples and they all seem to be doing the same thing my code does.

I use serverless framework here's the authorization code:

exports.handler = function (event: APIGatewayTokenAuthorizerEvent): APIGatewayAuthorizerResult {
    const authorizer = new Authorizer();

    try {
        if (!event.authorizationToken) throw new Error("No token");

        const token = event.authorizationToken.split(" ")[1];
        const decodedData = authorizer.verifyToken(token) as unknown as User;
        const policy = generatePolicy(token, event.methodArn);

        return {
            ...policy,
            context: {
                user: JSON.stringify(decodedData),
            },
        };
    } catch (err) {
        console.log(err);
        throw "Unauthorized";
    }
};

const generatePolicy = (principalId: string, methodArn: string) => {
    return {
        principalId,
        policyDocument: {
            Version: "2012-10-17",
            Statement: [
                {
                    Action: "execute-api:Invoke",
                    Effect: "Allow",
                    Resource: methodArn,
                },
            ],
        },
    };
};

and here's the serverless config

const serverlessConfiguration: AWS = {
service: "user-crud",
frameworkVersion: "2",
custom: {
    webpack: {
        webpackConfig: "./webpack.config.js",
        includeModules: true,
    },
},
plugins: ["serverless-webpack"],
provider: {
    name: "aws",
    runtime: "nodejs14.x",
    region: "eu-west-1",
    apiGateway: {
        minimumCompressionSize: 1024,
        shouldStartNameWithService: true,
    },
    environment: {
        AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
    },
    lambdaHashingVersion: "20201221",
},

functions: {
    jwtAuthorizer: {
        handler: "src/api/authorizer.handler",
        name: "jwtAuthorizer",
    },
    get: {
        name: "get",
        handler: "src/api/get.handler",
        role: "arn:aws:iam::109394173706:role/dynamodb_cloudwatch_full",
        events: [
            {
                http: {
                    path: "get",
                    method: "get",
                    cors: true,
                    authorizer: "jwtAuthorizer",
                },
            },
        ],
    },

}...

I always get 500 response when the token is correct and I return the object, so I guess there's something wrong with the return object?

If the token is incorrect and I throw "Unauthorized" then I get back the correct 401 response.

Share Improve this question edited Jul 11, 2021 at 20:57 NikVogri asked Jul 11, 2021 at 20:51 NikVogriNikVogri 1411 silver badge6 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

Well, there are some other reasons for getting,

{
    message : null
}

error from Api Gateway. I had a very hard time identifying mine.

  1. The API Gateway might lack permission to invoke the authorizer lambda. Make sure you add Lambda Invoke Role for your authorizer
  2. You should not modify the request context (not talking about response context). Whenever I try, I get Execution failed due to configuration error: Invalid JSON in response: Unrecognized field "headers", not marked as ignorable in Api Gateway Logs. You have to tackle it by adding cors with explicit mention of those headers
  3. The return policy should ply with the Lambda response 1.0 version. If you want to use boolean based return, you must enable lambda response 2.0
  4. If you have updated the authorizer lambda function name or something, it is better to delete the RestApiGateway and create again. The changes might not get updated in CloudFront properly sometimes.
  5. The response context you give will allow only String, Number or Boolean types. Example,

    function allowPolicy(methodArn) {
        console.log("Allow Policy")
        return {
            "principalId": "apigateway.amazonaws.",
            "policyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "execute-api:Invoke",
                        "Effect": "Allow",
                        "Resource": methodArn
                    }
                ]
            },
            "context": {
                "stringValue": "blablabla",
                "numberValue": 10,
                "booleanValue": true,
            }
        };
    }

Apparently, the handler needs to be async, otherwise, it expects a callback... Time well spent :|

You need to configure Resource-based policy statements in your AWS Lambda to allow API Gateway Authorizer to call your function. It is in Configuration -> Permissions -> Resource-based policy statements.

Then, add something like the following:

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "allow-api_gateway-authorizer-invoke",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws."
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "<LAMBDA AUTHORIZER FUNCTION ARN HERE>",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:execute-api:<API GATEWAY REGION>:<ACCOUNT_NUMBER>:*/authorizers/*"
        }
      }
    }
  ]
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论