I am trying to access s3 bucket. I am able to do so using my local machine(i.e. from my local machine to S3 bucket), but getting access denied issue while trying to access it from EC2 instance running tomcat 8 and java 8.
此外,当我上传文件时,为root用户设置了权限,如果我将我的存储桶保持为公共状态并从EC2上传文件,则不会为root用户设置权限。
public class AmazonS3UtilService {
public static final String NAME = "amazonS3Util";
private static String S3_SECRET = "S3_SECRET";
private static String S3_ID = "S3_ID";
private static String BUCKET_NAME = "S3_BUCKET";
private static final String SUFFIX = "/";
private static final String DEFAULT_FOLDER_PATH = "PHR/Reports/";
@Autowired
protected Environment props;
private AWSCredentials awsCredentials = null;
private AmazonS3 s3Client = null;
private String bucketName = null;
private static final Logger log = Logger.getLogger(AmazonS3UtilService.class);
private void prepareAWSCredentials() {
if (awsCredentials == null) {
log.info("Preparing AWS Credentials");
awsCredentials = new AWSCredentials() {
@SuppressWarnings("unused")
Map<String, String> env = System.getenv();
public String getAWSSecretKey() {
String S3_SECRET = System.getProperty(AmazonS3UtilService.S3_SECRET);
if (S3_SECRET == null) {
S3_SECRET = System.getenv(AmazonS3UtilService.S3_SECRET);
if (S3_SECRET == null) {
S3_SECRET = props.getProperty(AmazonS3UtilService.S3_SECRET);
}
}
log.info("S3_SECRET ---->" + S3_SECRET);
return S3_SECRET;
}
public String getAWSAccessKeyId() {
String S3_ID = System.getProperty(AmazonS3UtilService.S3_ID);
if (S3_ID == null) {
S3_ID = System.getenv(AmazonS3UtilService.S3_ID);
if (S3_ID == null) {
S3_ID = props.getProperty(AmazonS3UtilService.S3_ID);
}
}
log.info("S3_ID ---->" + S3_ID);
return S3_ID;
}
};
}
}
private void prepareAmazonS3Client() {
if (s3Client == null) {
log.info("Preparing S3 Client");
ClientConfiguration clientCfg = new ClientConfiguration();
clientCfg.setProtocol(Protocol.HTTP);
s3Client = new AmazonS3Client(awsCredentials, clientCfg);
Region region = Region.getRegion(Regions.fromName(props.getProperty("s3client.region")));
log.info("Region ----->" + props.getProperty("s3client.region"));
s3Client.setRegion(region);
}
}
private void prepareBucketName() {
bucketName = System.getenv(AmazonS3UtilService.BUCKET_NAME);
log.info("bucketName ------>" + bucketName);
}
}
private void prepare() {
try {
awsCredentials = null;
prepareAWSCredentials();
prepareAmazonS3Client();
prepareBucketName();
} catch (AmazonServiceException ase) {
log.error("Caught an AmazonServiceException, which means your request made it "
+ "to Amazon S3, but was rejected with an error response for some reason.");
log.error("Error Message: " + ase.getMessage() + " HTTP Status Code: " + ase.getStatusCode()
+ " AWS Error Code: " + ase.getErrorCode() + " Error Type: " + ase.getErrorType()
+ " Request ID: " + ase.getRequestId());
new AmazonS3ClientException(ase, ase.getMessage());
} catch (AmazonClientException ace) {
log.error(ace);
new AmazonS3ClientException(ace, ace.getMessage());
}
}
@SuppressWarnings("unused")
public String uploadDocument(UploadDocumentDetailDTO uploadDocumentDetail) {
prepare();
String tempFileName = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss").format(new Date());
String fileURL = null;
try {
File uploadFileContent = readBase64File(uploadDocumentDetail.getFileContent(), tempFileName);
uploadDocumentDetail.setContentType(FileContentTypeEnum.PDF);
String uploadFileName = getUploadFileName(uploadDocumentDetail);
PutObjectRequest request = new PutObjectRequest(bucketName, uploadFileName, uploadFileContent);
request.putCustomRequestHeader("Content-Type", "application/pdf");
request.putCustomRequestHeader("Content-Disposition", "inline");
PutObjectResult putObjectResult = s3Client.putObject(request);
URL url = generatePresignedUrlRequest(uploadFileName);
fileURL = url.toString();
} catch (Exception e) {
log.info(LoggerException.printException(e));
fileURL = "";
}
return fileURL;
}
public URL generatePresignedUrlRequest(String fileURL) {
log.info("Inside generatePresignedUrlRequest");
java.util.Date expiration = new java.util.Date();
long msec = expiration.getTime();
msec += 1000 * 60 * 60; // 1 hour.
expiration.setTime(msec);
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileURL);
generatePresignedUrlRequest.setMethod(HttpMethod.GET); // Default.
generatePresignedUrlRequest.setExpiration(expiration);
URL s = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
log.info("Url --->" + s);
return s;
}
private String getUploadFileName(UploadDocumentDetailDTO uploadDocumentDetail) {
StringBuffer uploadFileName = new StringBuffer();
uploadFileName.append(DEFAULT_FOLDER_PATH);
if (uploadDocumentDetail.getBeneficiaryId() != null)
uploadFileName.append(uploadDocumentDetail.getBeneficiaryId() + SUFFIX);
if (uploadDocumentDetail.getDocumentType() != null)
uploadFileName.append(uploadDocumentDetail.getDocumentType().getName() + SUFFIX);
// Check and create Folder
validateAndCreateFolder(uploadFileName.toString());
if (uploadDocumentDetail.getAssesmentId() != null)
uploadFileName.append(
uploadDocumentDetail.getAssesmentId() + "." + uploadDocumentDetail.getContentType().getName());
else
uploadFileName.append(
uploadDocumentDetail.getDefaultFileName() + "." + uploadDocumentDetail.getContentType().getName());
return uploadFileName.toString();
}
private static File readBase64File(String content, String fileName) throws Exception {
File file = File.createTempFile(fileName, ".tmp");
file.deleteOnExit();
FileOutputStream fileOuputStream = new FileOutputStream(file);
fileOuputStream.write(Base64.decodeBase64(content));
fileOuputStream.close();
return file;
}
public void validateAndCreateFolder(String folderName) {
List<S3ObjectSummary> fileList = null;
try {
fileList = s3Client.listObjects(bucketName, folderName).getObjectSummaries();
} catch (AmazonServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AmazonClientException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (fileList == null || fileList.isEmpty()) {
// create meta-data for your folder and set content-length to 0
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(0);
// create empty content
InputStream emptyContent = new ByteArrayInputStream(new byte[0]);
// create a PutObjectRequest passing the folder name suffixed by /
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, folderName, emptyContent, metadata);
// send request to S3 to create folder
s3Client.putObject(putObjectRequest);
}
}
/**
* This method first deletes all the files in given folder and than the
* folder itself
*/
}
以下是从EC2实例访问S3时的异常。
INFO com.medscheme.common.util.AmazonS3UtilService - com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 926E1213366626B9), S3 Extended Request ID: zQbb4JCalYExHZtDSv0GmWxoHrQZJUV3M+jlUiaVJY/sDxW/qoNFC8hizfangVCjweWZtOqC7/A=
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1275)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:873)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:576)
at com.amazonaws.http.AmazonHttpClient.doExecute(AmazonHttpClient.java:362)
at com.amazonaws.http.AmazonHttpClient.executeWithTimer(AmazonHttpClient.java:328)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:307)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3649)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3602)
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:679)
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:664)
at com.medscheme.common.util.AmazonS3UtilService.validateAndCreateFolder(AmazonS3UtilService.java:222)
at com.medscheme.common.util.AmazonS3UtilService.getUploadFileName(AmazonS3UtilService.java:200)
at com.medscheme.common.util.AmazonS3UtilService.uploadDocument(AmazonS3UtilService.java:166)
at com.medscheme.service.impl.ReportsServiceImpl.getReport(ReportsServiceImpl.java:133)
at com.medscheme.service.impl.ReportsServiceImpl.getReport(ReportsServiceImpl.java:1)
at com.medscheme.controller.ReportsController.getWellnessReportDetails(ReportsController.java:69)
答案 0 :(得分:0)
我可以在创建amazon客户端时使用BasicAWSCredentials类而不是AWSCredentials来解决此问题。 问题仅出在EC2实例上。 有谁知道EC2出了什么问题。