【问题标题】:AWS: Secure API Gateway with developer authenticated identityAWS:具有开发人员身份验证的安全 API 网关
【发布时间】:2017-08-05 04:43:23
【问题描述】:

我想知道是否有人对如何解决 API Gateway/Lambda 上的以下问题有一个好主意 - API 的使用者只需要一个令牌,该令牌将通过附加到 API 网关的认知授权器授权他们,API 必须处理好所有事情,然后回火一个令牌。

所以用户向我的登录 Lambda 发送他们的用户名和密码,以便按照文档我执行以下操作(为简洁起见,我删除了错误处理):

    const cognitoidentity = new AWS.CognitoIdentity({ region: 'eu-west-1' })
    const userId = authenticationService.authorise(username, password)
    const params = {
        IdentityPoolId: 'eu-west-1:my-identity-pool-id',
        Logins: {
            'myapp.mydomain.com': userId,
        },
    }
    cognitoidentity.getOpenIdTokenForDeveloperIdentity(params, (err, data) => {

  // Now I have an OpenId token and an identity Id


})

最初我认为我应该调用 GetCredentialsForIdentity,但它并没有返回访问令牌,我是沿着正确的路线前进还是错过了什么?

更新:明确地说,我不希望消费者必须实现 AWS 客户端 sdk,基本上我希望他们能够简单地添加一个标头,让他们像传统 api 一样发出请求。

【问题讨论】:

  • 如果消费者不需要实现AWS SDK,如何获取访问API的token?您有一个自定义令牌生成器或类似的东西供您的消费者使用?
  • 好吧,对于用户池来说,他们会得到一个 JWT,这很好 - 从进一步的研究来看,我认为身份池是在浪费时间,所以是的,我正在考虑创建自己的 JWT 实现以与联合身份一起使用,当我证明这一点时,我会用答案更新它。

标签: amazon-web-services lambda aws-api-gateway amazon-cognito


【解决方案1】:

根据评论更新: 检查此代码

 var data = {
        UserPoolId : '...', // Your user pool id here
        ClientId : '...' // Your client id here
    };
    var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(data);
    var cognitoUser = userPool.getCurrentUser();

    if (cognitoUser != null) {
        cognitoUser.getSession(function(err, session) {
            if (err) {
               alert(err);
                return;
            }
            console.log('session validity: ' + session.isValid());

            AWS.config.credentials = new AWS.CognitoIdentityCredentials({
                IdentityPoolId : '...' // your identity pool id here
                Logins : {
                    // Change the key below according to the specific region your user pool is in.
                    'cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>' : session.getIdToken().getJwtToken()
                }
            });

            // Instantiate aws sdk service objects now that the credentials have been updated.
            // example: var s3 = new AWS.S3();

        });
    }

session.getAccessToken().getJwtToken()会给你访问令牌

此链接http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html 可能会对您有所帮助。

您必须在用户使用用户名和密码登录后生成访问令牌。您可以稍后验证该密钥。 否则,当用户通过验证时,您可以使用 STS 生成凭据并传递。

对于 API 网关,检查您是否可以在代码中创建 API 密钥并使用它。

【讨论】:

  • 嘿,谢谢,我遇到的问题实际上是在获得 openId 令牌后获取访问令牌、身份令牌等。
  • @MrkFldig 检查更新。链接:docs.aws.amazon.com/cognito/latest/developerguide/…
  • 感谢 Skarfa,但那是一个用户池,而不是一个身份池。
  • @MrkFldig 我认为您只能从用户池中获取访问/身份令牌。检查InitiateAuth函数:docs.aws.amazon.com/cognito-user-identity-pools/latest/…
  • 是的,我在这个年龄段眨眼了,我可以使用assumeRoleWithWebIdentity,但是如果他们不使用aws sdk,用户需要自己签署请求。
【解决方案2】:

代码中缺少的步骤如下:

  • 调用 AWS STS 以获取临时访问令牌
  • 签署临时访问令牌
  • 返回此签名值并将其与其他一些标头一起传递到最终请求中。

将您的请求传递给 API 端点的实际标头类似于:

{
   'Authorization': 'algo Credentials=<creds>, SIgnedHeaders=host;x-amz-date, Signature=<sig>',
   'x-amz-date': '<some date>',
}

实际上,创建这些标题可能会有点痛苦。痛苦的描述可以在这里找到:https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

我在后端使用 python,我只是使用 AWS 签名库来为我完成签名。

https://gist.github.com/rcadena/e071c26d9e4126af42eb29182ca5acb1

说了这么多,我不确定是否推荐这种为外部客户提供签名的整个方式。仅举一个困难:如果您必须将正文传递给最终端点请求,那么您必须从后端获取全新的签名,因为签名使用正文作为其摘要的一部分;您不能只重用 Authorization 标头。

我接下来要研究的可能是以编程方式在后端制作 API 网关访问令牌,但我不确定这些是否可以与身份相关联。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2017-09-25
    • 1970-01-01
    • 2015-04-15
    • 2016-06-29
    相关资源
    最近更新 更多