【问题标题】:How to Amazon S3 pre-signed URL from android app without exposing Amazon Web Services credentials如何在不暴露 Amazon Web Services 凭证的情况下从 Android 应用程序预签名 URL
【发布时间】:2021-10-25 19:39:06
【问题描述】:

在我的 android 应用程序中,我使用 Amazon S3 预签名 URL 并使用以下代码在应用程序中显示图像

var preSignedUrl = ""
        val s3Client: AmazonS3Client?
        val credentials: BasicAWSCredentials?
        credentials = BasicAWSCredentials(BuildConfig.AWS_ACCESS_KEY_ID, BuildConfig.AWS_SECRET_ACCESS_KEY)
        s3Client = AmazonS3Client(credentials)

        try {
            val s3URI = AmazonS3URI(imgUrl)

            // Set the pre signed URL to expire after one day.
            val expiration = Date()
            var expTimeMillis: Long = Instant.now().toEpochMilli()
            expTimeMillis += (1000 * 60 * 60 * 24 * 7).toLong()
            expiration.time = expTimeMillis

            val generateSignedUrlRequest = GeneratePresignedUrlRequest(s3URI.bucket, s3URI.key)
                .withMethod(HttpMethod.GET)
                .withExpiration(expiration)
            val url: URL = s3Client.generatePresignedUrl(generateSignedUrlRequest)
            preSignedUrl = url.toString()
            Logger().logInfo("AWS", "getImagePreSignedUrl $preSignedUrl")
        }catch (illEx: IllegalArgumentException){
            Logger().logInfo("AWS", "getImagePreSignedUrl err ${illEx.message.toString()}")
        }

        return preSignedUrl

但在将应用程序发布到谷歌播放后,它给了我以下警告

Your app(s) expose Amazon Web Services credentials.

请告诉我如何在应用程序中实现这一点,无论是否在应用程序中存储 AWS 密钥和秘密?

【问题讨论】:

  • 您使用什么 AWS 开发工具包来创建原生 Android 应用程序。看起来您正在编写 Kotlin 代码并使用 AWS SDK for Java V1
  • 我正在使用这些implementation 'com.amazonaws:aws-android-sdk-s3:2.25.0' implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.25.0@aar') { transitive = true } implementation ('com.amazonaws:aws-android-sdk-auth-userpools:2.25.0@aar') { transitive = true }
  • 通常不会在设备上创建预签名 URL。您可以在 Lambda 之类的东西中创建一个端点,并通过某种用户验证将预签名的 URL 交还给应用程序以供其使用。

标签: android amazon-web-services kotlin amazon-s3 android-security


【解决方案1】:

原生 Android 应用无法使用其他应用可以用来读取凭据的大多数方式。例如,原生 Android 应用无法从共享凭据和配置文件中的 [default] 凭据配置文件加载凭据(这可以使用 Java Desktop Swing 应用等应用轻松完成)。

使用 StaticCredentialsProvider 是一种合理的解决方法。这确实意味着您在使用此提供程序时必须在代码中指定您的信用。

【讨论】:

  • 使用 StaticCredentialsProvider 如何防止将凭据放入应用程序?
  • 它没有——我的意思是,鉴于大多数其他读取凭据的方法在本机 Android 应用程序中不起作用,我无法找到解决方法。另外,请在接下来的几周内密切关注此线程。
【解决方案2】:

我有一个粗略的想法。

您将需要 API Gateway、AWS Lambda 和 SSM Parameter Store/Secrets Manager。

  1. 创建 API 网关。通过为您的 Android 应用提供 API 密钥来保护传入请求。
  2. 触发 Lambda 函数以检索存储在 Secrets Manager 或 Parameter Store 中的凭据。
  3. 使用您的应用程序可用的私钥加密数据。
  4. 在响应中发送加密的 Secret 和 Access Key。
  5. 解密应用程序中的数据。

这在技术上是一种负担,您应该在应用程序启动时执行一次,然后将凭据存储在 Shared Preferences 中并停止检索,直到您在首选项中有一些值。

或者由你决定如何管理它。

【讨论】:

  • 或者可能使用 Cloudfront。
猜你喜欢
  • 2016-05-02
  • 2020-05-27
  • 2010-09-14
  • 2016-06-07
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多