无法使用Facebook AssumeRoleWithWebIdentity凭据访问AWS

时间:2013-07-01 11:01:04

标签: c# oauth amazon-web-services amazon-dynamodb

简短版

以Facebook用户身份登录,我使用我的oAuth令牌来假设IAM role on AWS。它返回看起来有效凭证的内容,例如有一个与我们的主密钥长度相似的AccessKeyId,SecretAccessKey。

当我尝试使用这些凭据访问DynamoDB表时,我得到两个例外之一:

  1. "The remote server returned an error: (400) Bad Request.";或
  2. "The security token included in the request is invalid."
  3. 我正在使用AWS C#SDK版本1.5.25.0

    长版

    正如我上面所说,我正在尝试使用Facebook身份授权的AmazonSecurityTokenServiceClient提供的凭据访问AWS上的DynamoDB表,如this AWS guide中所述。

    我创建的IAM角色的政策是:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "dynamodb:BatchGetItem",
            "dynamodb:PutItem",
            "dynamodb:Query",
            "dynamodb:Scan",
            "dynamodb:UpdateItem"
          ],
          "Sid": "Stmt1372350145000",
          "Resource": [
            "*"
          ],
          "Effect": "Allow"
        }
      ]
    }
    

    我如何获得凭据:

    1. 用户使用oAuth登录Facebook。
    2. 使用访问令牌,我假设IAM角色使用带有请求的AmazonSecurityTokenServiceClient.AssumeRoleWithWebIdentity
    3. 这会返回看似有效凭据的内容,例如一个与我们的主密钥长度相似的AccessKeyId,SecretAccessKey。

      using (var tokenServiceClient = new AmazonSecurityTokenServiceClient(RegionEndpoint.USEast1))
      {
          var request = new AssumeRoleWithWebIdentityRequest
          {
              DurationSeconds = (int)TimeSpan.FromHours(1).TotalSeconds,
              ProviderId = "graph.facebook.com",
              RoleArn = "arn:aws:iam::193557284355:role/Facebook-OAuth",
              RoleSessionName = result.id,
              WebIdentityToken = FBClient.AccessToken
          };
      
          var response = tokenServiceClient.AssumeRoleWithWebIdentity(request);
      
          AWSAssumedRoleUser = response.AssumeRoleWithWebIdentityResult.AssumedRoleUser;
          AWSCredentials = response.AssumeRoleWithWebIdentityResult.Credentials;
      }
      
    4. 我如何使用这些凭据:

      使用返回的凭据,我尝试访问 AWS DynamoDB 资源。

      using (var client = new AmazonDynamoDBClient(AWSCredentials.AccessKeyId, AWSCredentials.SecretAccessKey, AWSCredentials.SessionToken, RegionEndpoint.USEast1))
      {
          var context = new DynamoDBContext(client);
          var data = context.Scan<SomeData>();    
      }
      

      尝试"The remote server returned an error: (400) Bad Request."表时会返回Scan

      这是异常消息中的变化;如果我省略上述AWSCredentials.SessionToken

      中的AmazonDynamoDBClient
      using (var client = new AmazonDynamoDBClient(AWSCredentials.AccessKeyId, AWSCredentials.SecretAccessKey, RegionEndpoint.USEast1))
      {
          var context = new DynamoDBContext(client);
          var data = context.Scan<SomeData>();
      }
      

      尝试"The security token included in the request is invalid."表时会返回Scan

      问题

      此时我无法分辨出什么是错的,凭证无效或者我没有通过AWS所需的一切。

      任何人都可以提供任何有关错误的信息或如何进一步调试吗?

1 个答案:

答案 0 :(得分:2)

我将我的问题交叉发布到AWS论坛,并收到了亚马逊工程师的答复。

https://forums.aws.amazon.com/message.jspa?messageID=465057


DynamoDBContext对象在目标表上调用DescribeTable(并缓存此数据,因此为了获得最佳性能,您需要尽可能长时间地保持上下文对象,因此此调用仅进行每个目标表一次)。修改您的政策如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "dynamodb:BatchGetItem",
        "dynamodb:PutItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "dynamodb:UpdateItem",
        "dynamodb:DescribeTable"        
      ],
      "Sid": "Stmt1372350145000",
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  ]
}