4

我发布了here on the AWS forum请求中包含的安全令牌无效。 aws js sdk

我在下面的代码中使用了aws-js-sdk v2.2.3。我收到的数据与Credentials填充。当我尝试使用凭据时,我收到错误信息,证明它们无效。我正在使用开发人员身份验证流程。我有两个角色Auth & UnAuth。我的身份池看起来是正确的。信任关系看起来像是指向正确的身份池ID。 DynamoDB中存在针对S3 &的Auth角色的策略。我很茫然。任何帮助,将不胜感激。

JavaScript客户端:

var cognitoidentity = new AWS.CognitoIdentity({region: 'us-east-1'}); 
    var params = { 
     IdentityId: user.cognito_id, 
     Logins: { 
    'cognito-identity.amazonaws.com': user.cognito_token 
     } 
    }; 
    cognitoidentity.getCredentialsForIdentity(params, function(err, data) { 
     if (err) console.log(err, err.stack); // an error occurred 
     else console.log(data.Credentials); 
    }); 

我CONSOLE.LOG的Id &中SecretKey它们填充在

var aws_creds = StateService.get('user').aws_creds; 
console.log(aws_creds.AccessKeyId); 
console.log(aws_creds.SecretKey); 
AWS.config.update({ accessKeyId: aws_creds.AccessKeyId, 
      secretAccessKey: aws_creds.SecretKey, 
      endpoint: ENV.aws_dyndb_endpoint, 
      region: 'us-east-1' 
      }); 
var dynamodb = new AWS.DynamoDB(); 


console.log("user obj: ", StateService.get('user')); 
var params = { 
    TableName: games_table_name, 
    KeyConditionExpression: "Id = :v1", 
    ExpressionAttributeValues: { 
     ":v1": {"N": id} 
    } 
}; 

return dynamodb.query(params); 

我的解决方案
我想出什么样的主意是明确刷新凭证,而不是在我为实例创建DynamoDb对象时懒惰地获取凭证。这是我使用的函数,当刷新凭证时,返回承诺&。

refresh: function() { 
    var deferred = $q.defer(); 
    AWS.config.region = 'us-east-1'; 
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({ 
     IdentityPoolId: COGNITO_IDENTITY_POOL_ID, 
     IdentityId: COGNITO_ID, 
     Logins: 'cognito-identity.amazonaws.com' 
    }); 

    AWS.config.credentials.refresh(function(error) { 
     if ((error === undefined) || (error === null)) { 
     $log.debug("Credentials Refreshed Success: ", AWS.config.credentials); 
     var params = { 
      region: 'us-east-1', 
      apiVersion: '2012-08-10', 
      credentials: AWS.config.credentials 
     }; 

     $rootScope.dynamodb = new AWS.DynamoDB({params: params}); 
     deferred.resolve(); 
     } 
     else { 
     $log.debug("Error refreshing AWS Creds:, ", error); 
     deferred.reject(error); 
     } 
    }); 

    return deferred.promise; 
} 
+0

保存getCredentialsForIdentity()响应的代码在哪里?在失败的操作中实际使用这些凭据的代码在哪里? – jarmod

回答

2

如果你想使用Cognito凭据来调用其他AWS服务,我建议你使用高级AWS.CognitoIdentityCredentials对象从JavaScript SDK,而不是直接调用服务API。

您可以找到有关如何初始化和Cognito开发者指南中使用AWS.CognitoIdentityCredentials更多信息: Developer Authenticated Identities

阿尔伯特

+1

我也有使用CognitoIdentityCredentials对象的相同问题。最终,它仍然会出现安全令牌无效的错误。 –

+0

@StephenBurke你有没有想过这个错误你的问题?我收到无效的安全令牌错误 –

+0

@BenDavis我用我的解决方案编辑了原始帖子。顶部的AWS论坛链接中还有更多信息。最终对我来说,我需要设置一个区域并显式刷新凭证。 –

1

流程是这样的:你问CognitoIdentityCredentialsIdentityId的IDentityId是应该追踪跨设备和身份提供者(如Facebook,谷歌,TWitter等)的用户,然后使用该ID请求您附加角色CognitoIdentity,获得令牌后,您可以要求STS.assumeRoleWithWebIdentity作为临时具有适当角色的证书通过你的杆子。

这里是我是如何做的一个例子:

// set the Amazon Cognito region 
AWS.config.region = 'us-east-1'; 

// initialize the Credentials object with our parameters 
AWS.config.credentials = new AWS.CognitoIdentityCredentials({ 
    IdentityPoolId: 'us-east-1:YMIDENTITYPOLEID', 
}); 

// We can set the get method of the Credentials object to retrieve 
// the unique identifier for the end user (identityId) once the provider 
// has refreshed itself 
AWS.config.credentials.get(function(err) { 
    if (err) { 
     console.log("Error: "+err); 
     return; 
    } 
    console.log("Cognito Identity Id: " + AWS.config.credentials.identityId); 

     params = { 
      IdentityId: AWS.config.credentials.identityId 
     } 

    // Other service clients will automatically use the Cognito Credentials provider 
    // configured in the JavaScript SDK. 

     // Get the Role associated with the id coming from the pool 
     var cognitoidentity = new AWS.CognitoIdentity(); 

     cognitoidentity.getOpenIdToken(params, function(err, data) { 
      if (err){ 
       console.log(err, err.stack); // an error occurred 
      }else{ 
         // Get temporoarly credientials form STS to access the API 
         var params = { 
          RoleArn: 'ROLE_OF_YOUR_POLE_ARN', /* required */ 
          RoleSessionName: 'WHATEVERNAME', /* required */ 
          WebIdentityToken: data.Token, /* required */ 
         }; 

         var sts = new AWS.STS() 

         console.log(data);   // successful response 
         console.log(data.Token) 

         sts.assumeRoleWithWebIdentity(params, function(err, data) { 
           if (err){ 
             console.log(err, err.stack); // an error occurred 
           }else{ 
             console.log(data);   // successful response 
             // Now we need these credentials that we got for this app and for this user 
             // From here we can limit the damage by 
             // Burst calling to the API Gateway will be limited since we now that this is a single user on a single device 
             // If suspicious activities we can drop this user/device 
             // The privileges are limited since the role attached to this is only the API GateWay calling 
             // This creds are temporary they will expire in 1h 

             var apigClient = apigClientFactory.newClient({ 
              accessKey: data.Credentials.AccessKeyId, 
              secretKey: data.Credentials.SecretAccessKey, 
              sessionToken: data.Credentials.Token, //OPTIONAL: If you are using temporary credentials you must include the session token 
              region: AWS.config.region // OPTIONAL: The region where the API is deployed, by default this parameter is set to us-east-1 
             }); 

             // Call the get to test 
             apigClient.deviceGet({}, {}) 
            .then(function(result){ 
             //This is where you would put a success callback 
               console.log(result) 
            }).catch(function(result){ 
             //This is where you would put an error callback 
            }); 

           } 
         }); 
      } 
     }); 

}); 

注:这是一个测试,以获取访问API网关服务,但它不是不同的以访问其他服务,这取决于在杆上配置它及其附加服务。

如果您拥有在IAM中创建的用户的凭证,则不需要临时标记,但是如果使用此流程,则必须包含它。

还有一点,限制您对杆子上的服务的访问,请记住这是一个公开给定的键,每个人都可以使用它来访问您的东西。

使用STS.assumeRoleWithWebIdentity是因为我们在Web上,在AWS JS SDK中,如果使用iOS或android/java或Boto,则必须使用STS.assumeRole。

希望这会有所帮助。

相关问题