amazon-web-services - AWS API 网关身份验证(Cognito 与自定义授权器)

标签 amazon-web-services oauth-2.0 aws-lambda amazon-cognito serverless-framework

我正在尝试制作一个具有联合身份验证的无服务器应用程序(ReactJS、API 网关、AWS Lambda、DynamoDB)。下面是我设想的那种架构(为了简洁没有添加 STS。而且我认为我没有完全理解流程):

Authentication sequence

我已经创建了触发 lambda 函数的 API 网关端点。我想先用谷歌验证我的用户,如果他们成功,那么他们应该能够使用 API 端点。

第一步是使用标准 Outh2 向 google 验证用户。为此,我创建了 2 个未经身份验证的端点/signin/google 和/callback/google。一旦我在回调 lambda 函数中获得来自 google 的成功身份验证响应,我就有了可以使用的 id_token(以及其他)。

目前,我有 2 种方法可用于验证 API。

  1. 构建可用于 API 端点的自定义授权方。这是代码(https://github.com/prabhatsharma/api-gateway-custom-authorizer/)。这非常简单。我可以使用 google 提供的相同 id_token 来验证 API 端点。自定义授权方将验证 id_token 是否正常并授予对端点的访问权限。它还会缓存结果,这样就不需要每次都进行验证了。 (这是以这种方式重用 google 的 id_token 的好方法吗?)您可以将授权方与此一起使用 ( https://github.com/prabhatsharma/lambda-custom-auth )

  2. 我可以使用 AWS cognito 进行身份验证。为此,我创建了一个联合身份池,并将谷歌应用程序客户端 ID 设置为 cognito 控制台。在我的/callback/google lambda 函数中,我使用 AWS SDK 来获取 identityId、sessionToken 和 accessKeyId。 (源代码 https://github.com/prabhatsharma/lambda-cognito-auth )

    // Add the Google access token to the Cognito credentials login map.
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: config.COGNITO_IDENTITY_POOL_ID,   //dauth
        Logins: {
            'accounts.google.com': JSON.parse(body).id_token
        }
    });
    

现在我可以使用凭据通过以下代码获取 token

    // Obtain AWS credentials
    AWS.config.credentials.get(function () {
        // Access AWS resources here.
        // Credentials will be available when this function is called.
        var identityId = AWS.config.credentials.identityId;

        var cognitoidentity = new AWS.CognitoIdentity();

        var params = {
            IdentityId: identityId, /* required */
            Logins: {
                'accounts.google.com': JSON.parse(body).id_token
            }
        };

        cognitoidentity.getOpenIdToken(params, function (err, data) {
            if (err) console.log(err, err.stack); // an error occurred
            else {
                console.log(data);           // successful response
                res.headers = {
                    location: config.APPLICAION_URL + '/auth/google?' + querystring.stringify(data)
                }
                callback(null, res);   //redirect to front end application
            }
        });

我现在可以将 identityId 和 Token 传递到我的前端 reactJS 应用程序。

这是我几乎不需要帮助来理解这个概念的地方。我现在可以在浏览器中使用 AWS SDK 来访问 AWS 资源。但是等等!!!通过 Gateway 创建标准 RESTful API 的目的难道不是为了使用标准 javascript 而不依赖于任何特定的库吗?直接使用 AWS SDK 看起来更适合 android/ios/unity 应用程序的用例。我希望我团队中的开发人员也能够使用他们用于这种情况的前端标准 javascript 库。此外,我不想将导出的 API SDK 用于我的 API 端点,并且真的想让前端应用程序保持 AWS SDK 细节的清洁。手动使用 v4 签名对每个请求进行签名是多余的工作。我们不能使用 Cognito 进行基于标准 token 的 API 端点访问吗?

这种身份验证的最佳做法是什么?我的思考方向正确吗?

免责声明 - 请不要使用存储库中的代码。它正在进行中,尚未准备好生产。

最佳答案

您可以将自定义授权器功能与 oauth2 token 一起使用。或者, 您可以使用具有相应 IAM 角色的 Cognito 来管理用户对您的 AWS 资源的访问。

您在流程图中描述的第二种方法不需要在每个请求前使用 auth lambda,并允许您从前端控制对其他 AWS 资源的访问(例如 IoT)。

一旦你获得了secretKey、accessKey、sessionToken和region,你只需要对APIG的每一个请求进行签名。您不需要 AWS 开发工具包即可执行此操作。

如果您不想使用导出的 API,则必须自己对请求进行签名。它在 sigV4Client.js 中实现,因此很容易复制。无论如何,您将需要很少的依赖项,那么为什么不使用导出的 API?你已经在使用 React 了,它是如此之大。

关于amazon-web-services - AWS API 网关身份验证(Cognito 与自定义授权器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40323897/

相关文章:

php - 如何从亚马逊获取ASIN和价格

oauth-2.0 - 如何通过 OAuth2 从 vKontakte (VK) 获取访问 token ?

amazon-web-services - 使用cloudformation时未创建Lambda权限

git - 用于 CodeCommit repo 同步的 AWS Lambda

amazon-web-services - 从 AWS 上运行的 Apache Nifi 访问 AWS 服务

amazon-web-services - 使用 AWS ELB 作为服务将流量指向 AWS 外部的服务器

oauth - 如果攻击者获得了应用程序的client_secret,他可以做什么?

amazon-web-services - Lambda AWS X 射线。 Python SDK - 在本地停用

amazon-web-services - 如何使用AWS API检索资源的属性?

ssl - 用于演示的 Identity Server 4 星 ssl 证书