【发布时间】:2019-07-28 13:01:27
【问题描述】:
关于我的用例的信息 -
- Lambda 在 AWS 账户 A 中
- AWS 账户 B 中的 S3
S3 中的文件上传事件(AWS 账户 B 中存在)触发 lambda 函数(AWS 账户 A 中存在),lambda 函数以 S3 事件作为输入,必须从 S3 下载文件。 Lambda 配置有附加策略的 IAM 角色。策略有权访问 S3(存在于 AWS 账户 B 中)。
为了让 lambda 与 S3 交互,lambda 服务器必须设置 aws 令牌(它自己使用 IAM 角色执行此操作),然后承担设置令牌配置文件以与 S3 交互而不会被拒绝访问的角色。为此,我在我的 lambda 函数中编写了 AWSTokenManager(下面共享的类代码),执行时会引发此错误 -
Unable to load credentials from service endpoint: com.amazonaws.SdkClientException
com.amazonaws.SdkClientException: Unable to load credentials from service endpoint
at com.amazonaws.auth.EC2CredentialsFetcher.handleError(EC2CredentialsFetcher.java:183)
at com.amazonaws.auth.EC2CredentialsFetcher.fetchCredentials(EC2CredentialsFetcher.java:162)
at com.amazonaws.auth.EC2CredentialsFetcher.getCredentials(EC2CredentialsFetcher.java:82)
at com.amazonaws.auth.InstanceProfileCredentialsProvider.getCredentials(InstanceProfileCredentialsProvider.java:164)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1166)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:762)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:724)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.doInvoke(AWSSecurityTokenServiceClient.java:1271)
at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.invoke(AWSSecurityTokenServiceClient.java:1247)
at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.executeAssumeRole(AWSSecurityTokenServiceClient.java:454)
at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.assumeRole(AWSSecurityTokenServiceClient.java:431)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
at sun.net.www.http.HttpClient.New(HttpClient.java:339)
at sun.net.www.http.HttpClient.New(HttpClient.java:357)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1199)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
at com.amazonaws.internal.ConnectionUtils.connectToEndpoint(ConnectionUtils.java:54)
at com.amazonaws.internal.EC2CredentialsUtils.readResource(EC2CredentialsUtils.java:116)
at com.amazonaws.internal.EC2CredentialsUtils.readResource(EC2CredentialsUtils.java:87)
at com.amazonaws.auth.InstanceProfileCredentialsProvider$InstanceMetadataCredentialsEndpointProvider.getCredentialsEndpoint(InstanceProfileCredentialsProvider.java:189)
at com.amazonaws.auth.EC2CredentialsFetcher.fetchCredentials(EC2CredentialsFetcher.java:122)
这是 AWSTokenManager 类代码 - 包 com.packagename;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.InstanceProfileCredentialsProvider;
import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.Credentials;
public class AWSTokenManager {
public void awsTokenManager() {
System.out.println("Inside awsTokenManager method");
basicSessionCredentials();
}
BasicSessionCredentials basicSessionCredentials() {
System.out.println("Call reached inside basicSessionCredentials method");
AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
.withCredentials(InstanceProfileCredentialsProvider.getInstance()).build();
AssumeRoleRequest roleRequest = new AssumeRoleRequest()
.withRoleArn("arn:aws:iam::111:role/iamrolenamehere").withRoleSessionName("role_profilename");
return gets3Credentials(stsClient, roleRequest);
}
public static BasicSessionCredentials gets3Credentials(AWSSecurityTokenService stsClient, AssumeRoleRequest roleRequest) {
Credentials s3Credentials = stsClient.assumeRole(roleRequest).getCredentials();
BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
s3Credentials.getAccessKeyId(), s3Credentials.getSecretAccessKey(),
s3Credentials.getSessionToken());
return basicSessionCredentials;
}
}
另请注意,lambda 配置中的no_proxy 和NO_PROXY 环境变量具有169.254.169.254。我这样做的原因是为了避免在连接到 AWS 服务时出现代理问题,根据我的理解,该服务在上面给出的 ip 上运行。
【问题讨论】:
-
我能够通过更新解决上述错误
标签: java amazon-s3 lambda aws-lambda aws-sdk