赞
踩
我用的 ServiceAccount 关联的 IAM Role 做的 k8s 应用内的授权。使用的 aws-java-sdk v1 的版本客户端。 这样 Presign 一个 S3 文件:
- import java.io.BufferedReader;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.URL;
- import java.util.Date;
-
- import com.amazonaws.SDKGlobalConfiguration;
- import com.amazonaws.auth.WebIdentityTokenCredentialsProvider;
- import com.amazonaws.services.s3.AmazonS3;
- import com.amazonaws.services.s3.AmazonS3ClientBuilder;
- import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
-
- public class S3Signer{
- static{
- System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
- }
-
- public static String generateUrl(AmazonS3 amazonS3, String bucketName, String key) {
- GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucketName,key);
- // 1 hour expiration time
- urlRequest.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60));
- URL url = amazonS3.generatePresignedUrl(urlRequest);
-
- return url.toString();
- }
-
- public static void main(String[] args) {
- String region = args[0];
- String roleArn = args[1];
- String sessionName = args[2];
- String tokenFile = args[3];
-
- String bucketName = args[4];
- String key = args[5];
-
- AmazonS3ClientBuilder builder = AmazonS3ClientBuilder.standard().withRegion(region);
-
- System.out.println("roleArn:"+ roleArn + " tokenFile:" + tokenFile + " sessionName:" + sessionName);
- builder.withCredentials(WebIdentityTokenCredentialsProvider.builder()
- .roleArn(roleArn)
- .webIdentityTokenFile(tokenFile)
- .roleSessionName(sessionName)
- .build());
-
- AmazonS3 s3 = builder.build();
-
- String location = s3.getBucketLocation(bucketName);
- System.out.println("bucket location:" + location + " bucket: " + bucketName);
- s3.putObject(bucketName,"hello.txt", "hello world");
-
- System.out.println(generateUrl(s3, bucketName, key));
-
- }
- }
如果你有遇到下面这个 AuthorizationQueryParametersError 错误,
- <Error>
-
- <Code>AuthorizationQueryParametersError</Code>
-
- <Message>X-Amz-Algorithm only supports "AWS4-HMAC-SHA256 and AWS4-ECDSA-P256-SHA256"</Message>
-
- <RequestId>EHCHR1687MYQKZZD</RequestId>
-
- <HostId>xlywJTkA5oqp/9sA6VaVKqYwGEDKpK2AS5EK2R6DVpioNZUGJS3I97lWFAKAxNVYfHVMCJ4RDZM=</HostId>
-
- </Error>
这个错误说明签名得到了 AWS3 的参数,算法不支持,需要使用 S4的算法。加上签名的代码:
System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
如果遇到下面的 UnauthorizedAccess 错误信息,提示 You are not authorized to perform this operation:
- <Error>
- <Code>UnauthorizedAccess</Code>
- <Message>You are not authorized to perform this operation</Message>
- <RequestId>MCRMH7258TQ6ATXG</RequestId>
- <HostId>D7WNA1djj5eHh3oA2x6Sj7ef7ke2R3VxX4DyB+uiNsOXQHmQaLI/MzTO/mQqIQ9wWIfi3wyFY8A=</HostId>
- </Error>
依次检查:
1.权限是否正确。 比如用 IAM Role 的话,检查 环境变量中是否有正确的信息
kubectl exec my-application-deplyoment-67f8d677f5-ztw7z env | grep AWS
比如我的信息
- AWS_REGION=cn-northwest-1
- AWS_ROLE_ARN=arn:aws-cn:iam::xxxx:role/my-cluster-addon-iamserviceaccount-al-Role1-abcd
- AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
- AWS_DEFAULT_REGION=cn-northwest-1
2.检查授权策略是否包含了 S3 的访问权限。
3.如果是在中国区,默认访问不了 80, 443 端口的 URL。需要上传 ICP 备案信息之后才可以正常访问到。 参考:amazon web services - You are not authorized to perform this operation - Stack Overflow
如果读取 token 遇到错误, 参考:
https://github.com/aws/aws-sdk-java-v2/issues/1470s
使用 aws 2.0 SDK 签名 S3 URL:
1Example usage for com.amazonaws.services.s3.model GeneratePresignedUrlRequest GeneratePresignedUrlRequest
https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/GetObjectPresignedUrl.java
AWS Java SDK 2.0 create a presigned URL for a S3 object | Newbedev
[Solved] Java Can't access S3 PreSigned URL due to authorization - Code Redirect
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。