AWS API网关身份验证(Cognito与自定义authrorizer)

时间:2016-10-29 21:33:59

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

我正在尝试使用联合身份验证创建无服务器应用程序(ReactJS,API Gateway,AWS Lambda,DynamoDB)。下面是我想象的那种建筑设计(为了简洁起见,我没有添加STS。我也不认为我完全理解了流程):

Authentication sequence

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

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

此时我有两种方法可以用来验证API。

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

  2. 我可以使用AWS cognito进行身份验证。为此,我创建了一个联合身份池,并将google app客户端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
        }
    });
    
  3. 现在我可以使用凭据来使用以下代码获取令牌

        // 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?

    进行基于标准令牌的API端点访问

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

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

1 个答案:

答案 0 :(得分:0)

您的云将自定义授权程序功能与oauth2令牌一起使用,或者您可以将Cognito与相应的IAM角色一起使用来管理用户对AWS资源的访问权限。

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

获得secretKey,accessKey,sessionToken和region后,您只需要向APIG签署每个请求。您不需要AWS SDK来执行此操作。

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