在不允许 getEnv 调用的受保护环境中创建 AmazonHttpClient
Posted
技术标签:
【中文标题】在不允许 getEnv 调用的受保护环境中创建 AmazonHttpClient【英文标题】:create AmazonHttpClient in a protected environment which does not allow getEnv calls 【发布时间】:2020-11-25 19:33:17 【问题描述】:从AWS SDK 的版本 1.11.700 切换到 1.11.908,我们的一个库现在无法在受保护的环境中工作。更具体地说,新的 SDK 版本已更改 ClientConfiguration,因此它现在通过检查环境变量来实例化 RetryPolicy。
不幸的是,我们将把这个库部署到一个禁止(SecurityManager in place)访问环境变量的环境中。 这意味着我们所有依赖于AmazonHttpClient 的代码不再可用,因为:
要实例化AmazonHttpClient
,您必须传入有效的 ClientConfiguration
(不接受 null)
要创建有效的ClientConfiguration
,您需要能够读取环境变量
这是堆栈跟踪:
java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.AWS_RETRY_MODE")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:886)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at com.boomi.security.ExtendedSecurityManager.checkPermissionImpl(ExtendedSecurityManager.java:207)
at com.boomi.security.ExtendedSecurityManager.checkPermission(ExtendedSecurityManager.java:114)
at java.lang.System.getenv(System.java:894)
at com.amazonaws.retry.internal.RetryModeResolver.envVar(RetryModeResolver.java:67)
at com.amazonaws.retry.internal.RetryModeResolver.resolveRetryMode(RetryModeResolver.java:72)
at com.amazonaws.retry.internal.RetryModeResolver.<init>(RetryModeResolver.java:46)
at com.amazonaws.retry.RetryPolicy.<clinit>(RetryPolicy.java:35)
at com.amazonaws.retry.PredefinedRetryPolicies.<clinit>(PredefinedRetryPolicies.java:30)
at com.amazonaws.ClientConfiguration.<clinit>(ClientConfiguration.java:89)
我们提出的所有选项都不适用于这种情况:
子类化ClientConfiguration
以抑制异常:无法尝试捕获对 super() 构造函数的调用
ClientConfiguration
是一个类,因此我们没有要实现的接口
java.policy
无法修改以允许访问该属性:环境不在我们的控制范围内
异常是从而不是从引发的,因此它甚至与单个对象无关...
【问题讨论】:
您至少可以修改 java 策略文件吗? ~/.java.policy` 或[java.home]/lib/security/java.policy
并添加以下内容:grant permission java.lang.RuntimePermission "getenv.AWS_RETRY_MODE", "read"; ;
谢谢,但是修改安全环境不是我们可以在那个环境下做的事情,我会澄清这个问题
【参考方案1】:
看起来 AmazonHttpClient 有一个 builder(),所以如果您在构建器上设置了 retryPolicy,ClientConfiguration 可能不会寻找 retryPolicy。
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/http/AmazonHttpClient.Builder.html
---------------- 另一种选择:
我们可以在官方 SDK 代码中看到,ClientConfiguration() 构造函数可以采用另一个 ClientConfiguration,因此可以使用 extends 创建一个自定义的构造函数。
public class ClientConfigurationByPassingSecurity extends ClientConfiguration
@Override
public RetryPolicy getRetryPolicy()
return xx;
//通过这个自定义创建你的 AmazonHttpClient
ClientConfiguration customClientConfiguration = new ClientConfigurationByPassingSecurity ();
ClientConfiguration clientConfig = new ClientConfiguration(customClientConfiguration);
new AmazonHttpClient(clientConfig);
覆盖由于 getVars 而失败的任何方法。
【讨论】:
非常聪明的方法!不幸的是,这似乎不起作用,因为不幸的是,自定义重试策略正在 在 对象初始化之后被读取,而 AccessControlException 在类初始化期间被引发(即更早:-() 你是对的,@SimoneAvogadro 它们是静态变量,将在构造函数之前初始化。我调查了一下,问题从 RetryPolicy 开始,因为它正在调用 RetryModeResolver,它首先查看 env、系统属性,然后是配置文件。 github.com/aws/aws-sdk-java/blob/…看到你开了bug票,祝你好运以上是关于在不允许 getEnv 调用的受保护环境中创建 AmazonHttpClient的主要内容,如果未能解决你的问题,请参考以下文章