简体   繁体   English

请求中包含的安全令牌无效。 aws js sdk

[英]The security token included in the request is invalid. aws js sdk

I posted here on the AWS forum 在AWS论坛上发布了这里

I'm using the aws-js-sdk v2.2.3 with the following code. 我正在使用带有以下代码的aws-js-sdk v2.2.3。 I get data back with Credentials populated. 我通过填充Credentials获取数据。 When I try to use the credentials I get the error that they are invalid. 当我尝试使用凭据时,我得到的错误是它们无效。 I'm using the developer authenticated identities flow. 我正在使用开发人员身份验证身份流程。 I have both roles Auth & UnAuth. 我有两个角色Auth和UnAuth。 My identity pool looks like it's correct. 我的身份池看起来是正确的。 The trust relationships look like they are pointing to the correct identity pool id. 信任关系看起来像是指向正确的标识池ID。 There are policies attached to the Auth role for S3 & DynamoDB. S3和DynamoDB的Auth角色附加了策略。 I'm at a loss. 我不知所措。 Any help would be appreciated. 任何帮助,将不胜感激。

javascript client side: 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);
    });

I console.log the Id & SecretKey and they are filled in. 我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);

My Solution 我的解决方案
What I came up with was to explicitly refresh the credentials versus get them lazily when I created a DynamoDb object for instance. 我想到的是显式刷新凭据,而不是在我创建DynamoDb对象时懒得。 Here's the function I use which returns a promise & resolves when the credentials are refreshed. 这是我使用的函数,它返回一个promise并在刷新凭据时解析。

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;
}

If you want to use Cognito credentials to call other AWS services, I recommend you use the high-level AWS.CognitoIdentityCredentials object from the Javascript SDK, instead of calling the service API directly. 如果要使用Cognito凭据调用其他AWS服务,我建议您使用Javascript SDK中的高级AWS.CognitoIdentityCredentials对象,而不是直接调用服务API。

You can find more information about how to initialize and use AWS.CognitoIdentityCredentials in the Cognito Developer Guide: Developer Authenticated Identities 您可以在Cognito开发人员指南中找到有关如何初始化和使用AWS.CognitoIdentityCredentials更多信息: 开发人员身份验证身份

Albert 阿尔伯特

The flow is like this: You ask the CognitoIdentityCredentials for a IdentityId , the IDentityId is supposed to track users accross devices and across Identities providers like (Facebook, Google, TWitter, etc.) then you with that ID you ask for a role attached to your pole CognitoIdentity , after you get the token, you ask the STS.assumeRoleWithWebIdentity for a temporary credentials with the appropriate roles attached to your pole. 流程是这样的:您向CognitoIdentityCredentials询问IdentityId ,IDentityId应该跟踪设备之间以及整个身份提供商(Facebook,Google,TWitter等)的用户,然后您使用该ID请求附加的角色您的极点CognitoIdentity ,在您获得令牌后,您要求STS.assumeRoleWithWebIdentity获取临时凭证,并在您的极点附加适当的角色。

Here is an example of how I did it: 这是我如何做到的一个例子:

// 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
                                    });

                                }
                        });
            }
        });

});

NB: This was a test to get access to the API Gateway service, but it is not different to get access to other services, it depends on the pole you configure it and its attached services. 注意:这是一个访问API网关服务的测试,但访问其他服务没有什么不同,这取决于您配置它的极点及其附加服务。

If you have credential for a user created in IAM you don't need the temporary token, but if you use this flow you have to include it. 如果您拥有在IAM中创建的用户的凭据,则不需要临时令牌,但如果您使用此流,则必须包含该凭据。

Another point, limit the access to the services on your pole, keep in mind that is a publicly given key, every one can use it to get access to your stuff. 另一点,限制访问您的杆上的服务,请记住,这是一个公开给定的密钥,每个人都可以使用它来访问您的东西。

STS.assumeRoleWithWebIdentity is used because we are on the web, in the AWS JS SDK, if you use iOS or android/java or Boto, you have to use STS.assumeRole. 使用STS.assumeRoleWithWebIdentity是因为我们在Web上,在AWS JS SDK中,如果您使用iOS或android / java或Boto,则必须使用STS.assumeRole。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM