如何将apache配置为S3的反向代理

时间:2018-12-17 09:19:06

标签: java apache amazon-s3 proxy

我开发了一个模块,系统可以通过该模块将对象上传到亚马逊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:无法找到到请求目标的有效认证路径

谁能建议我应该修复哪一部分?

0 个答案:

没有答案