我开发了一个模块,系统可以通过该模块将对象上传到亚马逊s3并从S3存储桶中获取任何对象的预签名url。 在我的开发环境和暂存环境中运行良好。但是,由于从WAS服务器到Amazon s3的传出网络被阻止,因此无法在生产环境中使用。因为服务器在防火墙内部。幸运的是,在DMZ区域中有一个Apache Web服务器,它可以作为代理服务器。
Amazon SA建议我将Web服务器配置为反向代理,以便将所有流量转发到S3。
我已经按照以下步骤配置了Apache。
SSLProxyEngine On
ProxyPreserveHost on
ProxyPass /s3 https://{bucketname}.s3.amazon.com/
ProxyPassReverse /s3 https://{bucketname].s3.amazon.com/
enter code here
下面是我用于将文件上传到S3的代码。
@Override
public void uploadService(String regionName, String bucketName, String awsAccessKey, String awsSecretKey, File srcFile, String targetKey,String manufacturer) {
URL endpointUrl;
endpointUrl = getEndpoint(regionName, bucketName, targetKey, manufacturer);
byte[] contentHash = AWS4SignerBase.hash(srcFile);
String contentHashString = BinaryUtils.toHex(contentHash);
Map<String, String> headers = new HashMap<String, String>();
headers.put("x-amz-content-sha256", contentHashString);
headers.put("content-length", "" + srcFile.length());
headers.put("x-amz-storage-class", "STANDARD");
AWS4SignerForAuthorizationHeader signer = new AWS4SignerForAuthorizationHeader(
endpointUrl, "PUT", "s3", regionName);
String authorization = signer.computeSignature(headers,
null, // no query parameters
contentHashString,
awsAccessKey,
awsSecretKey);
// express authorization for this as a header
headers.put("Authorization", authorization);
// make the call to Amazon S3
String response = HttpUtils.invokeHttpRequest(getProxyUrl(targetKey, manufacturer), "PUT", headers, srcFile);
logger.debug("--------- Response content ---------");
logger.debug(response);
logger.debug("------------------------------------");
}
private URL getEndpoint(String regionName, String bucketName, String targetKey,String manufacturer) {
URL endpointUrl;
try {
endpointUrl = new URL("https://" + bucketName + ".s3.amazonaws.com/cloud/"+manufacturer+"/"+ targetKey);
// endpointUrl = new URL("https://localhost/s3/"+manufacturer+"/"+ targetKey);
} catch (MalformedURLException e) {
throw new RuntimeException("Unable to parse service endpoint: " + e.getMessage());
}
return endpointUrl;
}
private URL getProxyUrl (String targetKey,String manufacturer) {
URL endpointUrl;
try {
endpointUrl = new URL("https://localhost/s3/"+manufacturer+"/"+ targetKey);
// endpointUrl = new URL("https://localhost/s3/"+manufacturer+"/"+ targetKey);
} catch (MalformedURLException e) {
throw new RuntimeException("Unable to parse service endpoint: " + e.getMessage());
}
return endpointUrl;
}
测试失败,并显示以下消息。
java.lang.RuntimeException:请求失败。 sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到到请求目标的有效认证路径
谁能建议我应该修复哪一部分?