安卓:用户登录Amazon Cognito并在Amazon S3之间传输数据

3
我想请你帮我翻译以下关于Android的概念。我希望用户能够使用Amazon Cognito在我的应用程序上创建账户和登录,以识别他们的身份。一旦用户成功登录,该用户可以从Amazon S3下载个人文件。
我已经按照AWS Mobile Hub提供的代码实现了登录功能,一切似乎都很顺利:我能够通过我的应用程序创建一个测试账户并且没有出现任何错误。显然,由于S3部分出现问题,我无法测试后端的功能。登录的代码非常基本,如下所示:
public class AuthenticatorActivity_old extends Activity {
    @Override    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
            SignInUI signin = (SignInUI) AWSMobileClient.getInstance().getClient(AuthenticatorActivity_old.this, SignInUI.class);
            signin.login(AuthenticatorActivity_old.this, home.class).execute();
        }).execute();        
    }
}

这段代码与一堆亚马逊库和awsconfiguration.json文件一起使用,我假设它声明了credentialsProvider

关于用户可以下载的个人文件,每个用户都会在应用程序的存储桶中得到自己的文件(只有一个存储桶,因为我不想为每个用户创建一个单独的存储桶),并且只有已登录的用户才有权下载此文件。我编写了一个IAM策略,它看起来像这样,如果我理解正确的话,它只允许用户下载名为[bucket]/cognito/[username]/fixedfilename.jpg的文件:

{
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": ["s3:ListBucket"],
              "Resource": ["arn:aws:s3:::<BUCKET-NAME>"],
              "Condition": {"StringLike": {"s3:prefix": ["cognito/<APPLICATION-NAME>/"]}}
            },
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
              ],
              "Resource": [
                "arn:aws:s3:::<BUCKET-NAME>/cognito/<APPLICATION-NAME>/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::<BUCKET-NAME>/cognito/<APPLICATION-NAME>/${cognito-identity.amazonaws.com:sub}/*"
              ]
            }
          ]
}

我认为目前为止我做得还不错(尚未测试完毕,所以不确定)。但现在来到棘手的部分。要从S3下载文件需要执行以下步骤:
  1. 首先使用BasicAWSCredentails类创建用于访问S3的AWS凭据
  2. 将AWS凭证传递给AmazonS3实例
  3. 然后将AmazonS3对象传递给TransferUtility类
因此,如果我理解正确,之前提到的登录过程应该保存AWS凭据。此凭证文件是根据我的存储桶和已登录用户的凭据定制的。
AWS Mobile Hub只是告诉我去https://docs.aws.amazon.com/aws-mobile/latest/developerguide/add-aws-mobile-user-data-storage.html#add-aws-mobile-user-data-storage-app并实现这一点。即使我使用提供的精确代码,我仍然会收到错误:AmazonS3 client is required please set using .s3Client(yourClient). 看起来Amazon提供了有问题的代码。查看AmazonS3client是什么,AmazonS3 s3 = new AmazonS3Client(credentialsProvider);,我再次看到了credentialsProvider。它是在登录过程中创建的(我猜测),但我无法提取它,因为它隐藏在Amazon的库和awsconfiguration.json中(我再次猜测。这里有很多黑匣子)。
我在Amazon提供的许多文档/教程/示例应用程序中迷失了方向,而且似乎他们最近进行了更新,使得一些在线文本不相关了。
有人能帮帮我吗??
-------------------------------- 更新 ---------------------------
以下是Amazon提供的与awsconfiguration.json文件结合使用的上传到S3的代码:
public class YourActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        uploadData();
    }

   public void uploadData() {

   TransferUtility transferUtility =
         TransferUtility.builder()
               .context(getApplicationContext())
               .awsConfiguration(awsConfig)
               .build();

   TransferObserver uploadObserver =
         transferUtility.upload(
               "s3Folder/s3Key.txt",
               new File("/path/to/file/localFile.txt"));

   uploadObserver.setTransferListener(new TransferListener() {

     ..... some more code

错误发生在Transferutility.builder中,我希望将其更改如下:
AmazonS3 s3Client = new AmazonS3Client(credentialsProvider);

                      TransferUtility.builder()
                        .s3Client(s3Client) <------------this one
                        .context(getApplicationContext())
                        .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
                        .build();

重点是我不能使用用户登录凭据来拥有S3Client(或者我可以吗???)(而不必从头构建登录活动,而是使用Amazon的代码,因为那有点超出我的能力范围!)

1个回答

1
您可以像这样创建一个CredentialsProvider对象:
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
            getApplicationContext(),
            &quot;us-east-1:dbacd6aa-9393-475e-b687-xxxxxxxxx&quot;, // Your Identity Pool ID
            Regions.US_EAST_1 // Your Region
    );

如果您不想每次都创建这个代码,那么可以将其写入单独的类中,并使用setter和getter方法来使用它。

在设置transferutility的过程中,需要包含用户信息。这是在创建credentialsprovider的getApplicationContext()部分发生的吗?还是我的credentialsprovider的基本理解有误? - daan166
不,我认为你误解了credentialProvider。credentialProvider用于授权您的应用程序连接请求访问您的AWS服务器,而不是验证用户的登录凭据。 - Rahul Kumar
啊,我现在明白了,感谢你的解释。我已经解决了错误。所以,在登录过程之后,“约翰”的凭据(用户john1234)会被本地存储(我相信是在共享首选项中)。在这个过程中,应用程序何时向服务器发送消息,“嘿,这是john1234,是我想要在服务器上存储文件x,而不是mike4321”?因为这对我来说非常重要,约翰只能存储名为/john/filex的文件,并且只能检索以/john/开头的文件。Mike4321不应该被允许访问此文件或使用/john/进行写入。 - daan166
抱歉回复晚了。如果您仍然想知道如何将这些文件存储在S3上,您可以在上面的代码中提供上传路径:transferUtility.upload( "s3Folder/s3Key.txt", new File("/path/to/file/localFile.txt")); 您的目标路径可以像这样:"s3Folder/username/fileName.txt" - Rahul Kumar
如果我帮助解决了您的问题,我会非常感激如果您能把这个答案标记为已接受。 - Rahul Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接