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"

关于我的用例的信息 -

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_proxyNO_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());
        }