java - Apache Camel AWS S3 : credential expiration and temporary credentials

标签 java amazon-s3 apache-camel

Apache Camel 与 AWS S3 接口(interface)良好,但我发现它没有正确构建的场景。回顾我在网上看到的所有 Camel 示例,我从未见过有人在非本地环境中使用推荐的行业标准 AWS 临时凭证。使用有效期约为 6 个月的静态凭据既是一个安全问题,也是一个手动负担(刷新),实际上不应该在本地环境之外的任何地方使用。

给定一个自定义的 s3 客户端设置,Camel 可以获取临时凭证,但是,指向 AWS S3 的 Camel 路由将在某个时刻过期。 Camel 不够聪明,无法知道这一点,因此将继续尝试轮询 S3 存储桶,而不会无限期地抛出任何异常或超时错误。

我尝试向我的端点添加超时配置,如下所示:

aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client&timeout=4000

任何人都可以解释如何将 Camel 与 AWS 临时凭证连接起来,或者在 AWS 凭证过期时抛出异常(考虑到上述设置)?

感谢您的帮助!

<小时/>

更新:

我向 Apache Camel 推送了一项功能来处理上述问题: https://github.com/apache/camel/blob/master/components/camel-aws-s3/src/main/docs/aws-s3-component.adoc#use-useiamcredentials-with-the-s3-component

最佳答案

如果其他人需要的话,这个问题的答案对于教程来说已经足够密集了。现在,我将其复制并粘贴到正确的论坛和线程中以发布消息:

不想提示太多,我只想说,尽管 Camel 多么强大,但它的文档和示例库对于 AWS 世界的生产场景来说确实很缺乏......叹息... 对于任何开源库来说,这都是一个长篇大论,而且可能是一个延伸。

引用官方的camel-s3 documentation找到了解决凭证问题的方法首先了解如何创建高级 S3 配置(依赖于 aws sdk 本身 - 您可以在那里看到一个简单的示例 - 它手动创建 s3 客户端)。 弄清楚这一点后,我去了aws sdk documentation on IAM credentials弄清楚这如何在 EC2 实例上工作,因为我能够构建客户端本身。在上述文档中,还有一些简单的示例。在使用列出的示例进行测试后,我发现凭据刷新(此问题的唯一目的)不起作用。它一开始可以获取凭据,但在我的测试期间,在它们手动过期后,它没有刷新它们。 最后,我发现您可以指定一个可以自行处理凭据刷新的提供程序链。解释这一点的 aws 文档是 here .

最后,我仍然需要为轮询 aws s3 存储桶的本地 Camel 设置提供静态凭证,但是,位于 ec2 上的远程环境可以使用可以完美刷新自身的临时凭证来访问它们。哇萨! :)

为此,我只是创建了一个工厂,该工厂使用本地 Camel 设置进行本地开发,并使用依赖于临时 IAM 凭证的远程 Camel 设置。这让我无需担心安全问题,也无需手动刷新所有远程环境的凭据!

我不会解释如何创建工厂或如何完全设置本地和远程配置,但我将提供 AmazonS3ClientBuilder 的代码示例,该示例为远程设置创建 S3 客户端。

AmazonS3ClientBuilder.standard()
   .withCredentials(new InstanceProfileCredentialsProvider(false))
   .withRegion(Regions.US_WEST_2)
   .build();

如果有人希望了解如何让它发挥作用,我可以提供一个显示整个过程的示例项目。

根据请求,以下是我的 s3 客户端的本地和远程实现: 本地:

public class LocalAWSS3ClientManagerImpl implements AWSS3ClientManager {
    private static Logger logger = LoggerFactory.getLogger(LocalAWSS3ClientManagerImpl.class);
    private PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties;
    private SimpleRegistry registry = new SimpleRegistry();
    private CamelContext camelContext;

public LocalAWSS3ClientManagerImpl(PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties) {
    this.priorityCodeSourcesRoutesProperties = priorityCodeSourcesRoutesProperties;
    registry.put("amazonS3Client", getS3Client());
    camelContext = new DefaultCamelContext(registry);
    logger.info("Creating an AWS S3 manager for a local instance (you should not see this on AWS EC2s).");
}

private AmazonS3 getS3Client() {
    try {
        String awsBucketAccessKey = priorityCodeSourcesRoutesProperties.getAwsBucketAccessKey();
        String awsBucketSecretKey = priorityCodeSourcesRoutesProperties.getAwsBucketSecretKey();
        AWSCredentials awsCredentials = new BasicAWSCredentials(awsBucketAccessKey, awsBucketSecretKey);
        return AmazonS3ClientBuilder.standard().withCredentials(
                new AWSStaticCredentialsProvider(awsCredentials)).build();
    } catch (RuntimeException ex) {
        logger.error("Could not create AWS S3 client with the given credentials from the local config.");
    }
    return null;
}

public Endpoint getIncomingAWSEndpoint(final String incomingAWSBucket, final String region,
        final String fileNameToSaveAndDownload) {
    return camelContext.getEndpoint(
            "aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client"
            + "&region=" + region + "&deleteAfterRead=false" + "&prefix=" + fileNameToSaveAndDownload);
}

public Endpoint getOutgoingLocalEndpoint(final String outgoingEndpointDirectory,
        final String fileNameToSaveAndDownload) {
    return camelContext.getEndpoint(
            "file://" + outgoingEndpointDirectory + "?" + "fileName="
            + fileNameToSaveAndDownload + "&readLock=markerFile");
}
}

远程:

public class RemoteAWSS3ClientManagerImpl implements AWSS3ClientManager {
private static Logger logger = LoggerFactory.getLogger(RemoteAWSS3ClientManagerImpl.class);
private PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties;
private SimpleRegistry registry = new SimpleRegistry();
private CamelContext camelContext;

public RemoteAWSS3ClientManagerImpl(PriorityCodeSourcesRoutesProperties priorityCodeSourcesRoutesProperties) {
    this.priorityCodeSourcesRoutesProperties = priorityCodeSourcesRoutesProperties;
    registry.put("amazonS3Client", getS3Client());
    camelContext = new DefaultCamelContext(registry);
    logger.info("Creating an AWS S3 client for a remote instance (normal for ec2s).");
}

private AmazonS3 getS3Client() {
    try {
        logger.info("Attempting to create an AWS S3 client with IAM role's temporary credentials.");
        return AmazonS3ClientBuilder.standard()
                                    .withCredentials(new InstanceProfileCredentialsProvider(false))
                                    .withRegion(Regions.US_WEST_2)
                                    .build();
    } catch (RuntimeException ex) {
        logger.error("Could not create AWS S3 client with the given credentials from the instance. "
                     + "The default credential chain was used to create the AWS S3 client. "
                     + ex.toString());
    }
    return null;
}

public Endpoint getIncomingAWSEndpoint(final String incomingAWSBucket, final String region,
        final String fileNameToSaveAndDownload) {
    return camelContext.getEndpoint(
            "aws-s3://" + incomingAWSBucket + "?" + "amazonS3Client=#amazonS3Client"
            + "&region=" + region + "&deleteAfterRead=false" + "&prefix=" + fileNameToSaveAndDownload);
}

public Endpoint getOutgoingLocalEndpoint(final String outgoingEndpointDirectory,
        final String fileNameToSaveAndDownload) {
    return camelContext.getEndpoint(
            "file://" + outgoingEndpointDirectory + "?" + "fileName="
            + fileNameToSaveAndDownload + "&readLock=markerFile");
}

}

关于java - Apache Camel AWS S3 : credential expiration and temporary credentials,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48014829/

相关文章:

java - 'JOptionPane.showConfirmDialog() 这里的第一个参数是什么?

python - 从 AWS Lambda 连接到 Redshift

amazon-s3 - s3cmd ls 和同步命令成本

java - Apache Camel,在服务器启动和停止时发送消息

java - ActiveMQ 上的重复消息

JavaFX 图像填充

java - 如何将json对象添加到同级的另一个json对象中?

java - Apache Camel/Spring DSL 中 header 值的 xpath 内的子字符串

java - 如何仅使用给定的格式将给定的字符串转换为java中的日期?

amazon-web-services - Amazon Certificate Manager 给出 LimitExceededException