通过 API Gateway 保护对 AWS Lambda 的访问

Posted

技术标签:

【中文标题】通过 API Gateway 保护对 AWS Lambda 的访问【英文标题】:Securing access to AWS Lambda through API Gateway 【发布时间】:2017-12-16 12:36:32 【问题描述】:

我正在使用 AWS Lambda 和 API Gateway 创建简单的 REST API。 此 API 将由外部服务(脚本)使用,但我想保护对 API 的访问,因此它不会被公开访问。此外,我想限制某些服务访问 API 的某些部分,并能够随时撤销它们的权限。

API 示例:

CatsLambda -> GET /cats DogsLambda -> GET /dogs FishLambda -> GET /fish

外部脚本:

CatsScript 可以访问 /cats 但不能访问 /dogs/fish MammalScript 可以访问 /cats/dogs 但不能访问 /fish

我认为我需要为我的脚本创建某种用户并使用它们来访问 API。 我正在考虑使用 Cognito,但我不再确定这种设置是否可行。

你有什么想法吗?我是否必须在 API Gateway 上创建自己的授权方?

【问题讨论】:

【参考方案1】:

为此,您可以使用自定义授权方或 AWS Cognito 用户池。

如果您继续使用自定义授权器,您可以创建一个 lambda 函数来执行授权部分。 AWS 文档中的示例代码如下所示

console.log('Loading function');

exports.handler =  (event, context, callback) => 
    var token = event.authorizationToken;
    // Call oauth provider, crack jwt token, etc.
    // In this example, the token is treated as the status for simplicity.

    switch (token.toLowerCase()) 
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); 
    
;

var generatePolicy = function(principalId, effect, resource) 
    var authResponse = ;

    authResponse.principalId = principalId;
    if (effect && resource) 
        var policyDocument = ;
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = ;
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    

    // Can optionally return a context object of your choosing.
    authResponse.context = ;
    authResponse.context.stringKey = "stringval";
    authResponse.context.numberKey = 123;
    authResponse.context.booleanKey = true;
    return authResponse;

您可以阅读更多内容以及如何实现自定义授权者using this link。

如果您使用的是用户池,您可以将 API 与用户池集成。您可以按照this documentation 中定义的步骤进行集成。引自网站,

使用 API Gateway 控制台创建用户池授权者

在 API Gateway 中创建新 API 或选择现有 API。 从主导航窗格中,选择指定 API 下的 Authorizers。 在授权方下,选择创建,然后选择 Cognito 用户池授权方。

要配置这个授权者:

为 Cognito 区域选择一个区域。 对于 Cognito 用户池,选择一个可用的用户池。 授权人名称字段将自动填充所选用户池名称。但是,您可以根据需要对其进行自定义。 默认情况下,身份令牌源字段将设置为 method.request.header.Authorization。但是,您可以 如果你想定制它。使用默认值,授权将是 包含 API 调用者的传入请求标头的名称 身份令牌。 (可选)在应用客户端 ID 正则表达式字段中键入正则表达式以验证与用户池关联的客户端 ID。 选择创建以完成用户池与 API 的集成。 创建授权方后,您可以选择通过提供从用户池提供的身份令牌对其进行测试。

在方法上启用用户池授权者

选择(或创建)您的 API 方法。 选择方法请求。 在授权设置下,选择授权字段旁边的编辑图标。 从下拉列表中选择一个可用的 Amazon Cognito 用户池授权方。 选择复选标记图标以保存设置。

对您选择的其他方法重复这些步骤。

[更新] 使用 Ashan 建议的方法更新答案。

另一种选择是在 API 网关上使用具有 IAM 授权的 Cognito 用户组。可以通过分配给与组链接的角色的策略来授予访问权限。

【讨论】:

另一种选择是在 api 网关使用具有 iam 授权的 cognito 用户组。可以通过分配给与组链接的角色的策略来授予访问权限。 @Ashan 感谢您的指出。用你的方法更新了答案。

以上是关于通过 API Gateway 保护对 AWS Lambda 的访问的主要内容,如果未能解决你的问题,请参考以下文章

在 AWS 中运行 spring boot 应用程序并且只允许通过 AWS API Gateway 访问

CloudFront 后面的 API Gateway 不支持 AWS_IAM 身份验证吗?

API 创新不会触发 AWS API Gateway 的基于自定义请求的 lambda 授权方

HTTP 请求正文未通过 AWS API Gateway 访问 AWS lambda 函数

AWS API Gateway CORS 对 OPTIONS 正常,对 POST 失败

AWS API Gateway 的访问权限