非AWS Kotlin应用如何通过IAM Roles Anywhere编程获取AWS临时凭证?
解决方案:用AWS SDK for Kotlin直接调用STS API生成临时凭证
你完全可以绕过aws_signing_helper命令行工具,直接通过AWS SDK for Kotlin调用STS的AssumeRoleWithCertificate API生成临时凭证,这是更优雅的集成方式,无需依赖外部进程。
核心原理
aws_signing_helper的底层逻辑就是通过X.509证书和私钥完成身份验证,调用STS服务的AssumeRoleWithCertificate接口获取临时会话凭证。我们可以直接用SDK复现这个流程。
步骤实现
1. 添加依赖
在Kotlin项目中引入AWS SDK for Kotlin的STS模块,以及处理证书/私钥的BouncyCastle库(用于解析PEM格式文件):
dependencies { implementation("aws.sdk.kotlin:sts:1.0.0") implementation("org.bouncycastle:bcpkix-jdk18on:1.78.1") implementation("org.bouncycastle:bcprov-jdk18on:1.78.1") }
2. 加载证书和私钥
从文件或安全存储中读取PEM格式的证书和私钥,解析为Java安全对象:
import org.bouncycastle.openssl.PEMParser import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter import java.io.FileReader import java.security.PrivateKey import java.security.cert.X509Certificate fun loadCertificate(certPath: String): X509Certificate { val parser = PEMParser(FileReader(certPath)) val certObj = parser.readObject() return JcaPEMKeyConverter().getCertificate(certObj) as X509Certificate } fun loadPrivateKey(keyPath: String): PrivateKey { val parser = PEMParser(FileReader(keyPath)) val keyObj = parser.readObject() return JcaPEMKeyConverter().getPrivateKey(keyObj) }
3. 调用STS获取临时凭证
初始化STS客户端,构造请求并调用API:
import aws.sdk.kotlin.services.sts.StsClient import aws.sdk.kotlin.services.sts.model.AssumeRoleWithCertificateRequest import java.util.Base64 suspend fun getTemporaryCredentials( roleArn: String, certificate: X509Certificate, privateKey: PrivateKey ): aws.sdk.kotlin.services.sts.model.Credentials { val encodedCert = Base64.getEncoder().encodeToString(certificate.encoded) val request = AssumeRoleWithCertificateRequest { this.roleArn = roleArn this.certificate = encodedCert this.privateKey = privateKey // SDK会自动处理私钥签名逻辑 this.roleSessionName = "kotlin-app-s3-session" // 自定义会话名称 // 可选:设置凭证有效期(最大1小时,受IAM角色配置限制) durationSeconds = 3600 } StsClient.fromEnvironment().use { stsClient -> val response = stsClient.assumeRoleWithCertificate(request) return response.credentials ?: throw IllegalStateException("Failed to get credentials") } }
4. 使用临时凭证操作S3
用获取到的临时凭证初始化S3客户端,执行文件下载等操作:
import aws.sdk.kotlin.services.s3.S3Client import aws.sdk.kotlin.services.s3.model.GetObjectRequest import java.io.File suspend fun downloadS3File( credentials: aws.sdk.kotlin.services.sts.model.Credentials, bucketName: String, key: String, outputPath: String ) { val s3Client = S3Client { credentialsProvider = aws.auth.credentials.StaticCredentialsProvider { accessKeyId = credentials.accessKeyId!! secretAccessKey = credentials.secretAccessKey!! sessionToken = credentials.sessionToken } region = "your-region" // 替换为S3桶所在区域 } s3Client.use { client -> val getObjRequest = GetObjectRequest { this.bucket = bucketName this.key = key } val response = client.getObject(getObjRequest) response.body?.writeToFile(File(outputPath)) } }
注意事项
- 确保你的证书和私钥拥有调用
AssumeRoleWithCertificate的权限,且目标IAM角色信任该证书对应的实体。 - 私钥需妥善保管,避免硬编码在代码中,建议通过环境变量或安全存储(如HashiCorp Vault)加载。
- 临时凭证最长有效期为1小时,需按需刷新。
内容的提问来源于stack exchange,提问作者Alex Romanov
相关产品推荐
相关产品推荐

