Я разработал модуль, с помощью которого моя система может загружать объект в amazon s3 и получать предварительно подписанный URL-адрес любого объекта из корзины S3.Он отлично работал в моей среде разработки и промежуточной среде.Тем не менее, он не работал на производстве, поскольку исходящая сеть с сервера WAS на Amazon s3 заблокирована.Потому что сервер находится внутри брандмауэра.К счастью, существует веб-сервер Apache, который находится в зоне DMZ и работает как прокси.
Amazon SA предложила мне настроить веб-сервер в качестве обратного прокси-сервера, чтобы весь трафик можно было перенаправлять на 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: невозможно найти действительный путь сертификации для запрошенной цели
Может кто-нибудь предложить мне, какую часть следует исправить?