lambda 中的令牌管理过程出错(Java 运行时)"Unable to load credentials from service endpoint: com.amazonaws.SdkClientException"
Error while token management process in lambda (Java runtime) "Unable to load credentials from service endpoint: com.amazonaws.SdkClientException"
关于我的用例的信息 -
- 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(class 下面共享的代码),该函数在执行时抛出此错误 -
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.access0(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 class 代码 -
包裹 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 上运行。
通过将 awstokenManager
方法更新为 -
,我能够通过上述错误
public void awsTokenManager() {
System.out.println("Inside awsTokenManager method");
STSAssumeRoleSessionCredentialsProvider stsAssumeRoleSessionCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(iAM_ROLE_ARN_TO_ASSUME, "us-east-1b")
.withStsClient(AWSSecurityTokenServiceClientBuilder.standard().build())
.withRoleSessionDurationSeconds(900)
.build();
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSAccessKeyId());
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSSecretKey());
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getSessionToken());
}
关于我的用例的信息 -
- 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(class 下面共享的代码),该函数在执行时抛出此错误 -
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.access0(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 class 代码 - 包裹 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 上运行。
通过将 awstokenManager
方法更新为 -
public void awsTokenManager() {
System.out.println("Inside awsTokenManager method");
STSAssumeRoleSessionCredentialsProvider stsAssumeRoleSessionCredentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(iAM_ROLE_ARN_TO_ASSUME, "us-east-1b")
.withStsClient(AWSSecurityTokenServiceClientBuilder.standard().build())
.withRoleSessionDurationSeconds(900)
.build();
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSAccessKeyId());
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getAWSSecretKey());
System.out.println("SessionCredentials awsaccesskeyid is - " + stsAssumeRoleSessionCredentialsProvider.getCredentials().getSessionToken());
}