繁体   English   中英

无法将 sam 本地 api 连接到机密管理器

[英]Trouble connecting sam local api to secrets manager

我正在尝试在本地设置 AWS SAM,因此不必每次更改代码时都进行部署。 但是我无法从 Secrets Manager 中获取机密。 我使用sam init --runtime java创建了一个新的 SAM 项目

然后,我在 Secret Manager 中创建了一个新密钥,并更改了 HelloWorldFunction 中的代码以尝试检索该密钥。

package helloworld;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.*;

/**
 * Handler for requests to Lambda function.
 */
public class App implements RequestHandler<Object, Object> {

    public Object handleRequest(final Object input, final Context context) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("X-Custom-Header", "application/json");
        try {
            String secretName = "testsecret";
            String region = "us-west-2";

            // Create a Secrets Manager client
            AWSSecretsManager client  = AWSSecretsManagerClientBuilder.standard()
                                            .withRegion(region)
                                            .build();

            String secret, decodedBinarySecret;
            GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest()
                            .withSecretId(secretName);
            GetSecretValueResult getSecretValueResult = null;

            try {
                getSecretValueResult = client.getSecretValue(getSecretValueRequest);
            } catch (DecryptionFailureException e) {
                // Secrets Manager can't decrypt the protected secret text using the provided KMS key.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw e;
            } catch (InternalServiceErrorException e) {
                // An error occurred on the server side.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw e;
            } catch (InvalidParameterException e) {
                // You provided an invalid value for a parameter.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw e;
            } catch (InvalidRequestException e) {
                // You provided a parameter value that is not valid for the current state of the resource.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw e;
            } catch (ResourceNotFoundException e) {
                System.out.println(e.getMessage());

                StringWriter outError = new StringWriter();
                e.printStackTrace(new PrintWriter(outError));
                System.out.println(outError.toString());
                // We can't find the resource that you asked for.
                // Deal with the exception here, and/or rethrow at your discretion.
                throw e;
            }

            // Decrypts secret using the associated KMS CMK.
            // Depending on whether the secret is a string or binary, one of these fields will be populated.
            if (getSecretValueResult.getSecretString() != null) {
                secret = getSecretValueResult.getSecretString();
                return new GatewayResponse(secret, headers, 200);
            }
            else {
                decodedBinarySecret = new String(Base64.getDecoder().decode(getSecretValueResult.getSecretBinary()).array());
                return new GatewayResponse(decodedBinarySecret, headers, 200);
            }
        } catch (Exception e) {
            return new GatewayResponse("{}", headers, 500);
        }
    }
}

当我运行sam local start-api并导航到http://127.0.0.1:3000/hello ,出现此错误:

Secrets Manager can’t find the specified secret. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 6881467f-d968-4f4e-ae60-7e3128124cc5)
com.amazonaws.services.secretsmanager.model.ResourceNotFoundException: Secrets Manager can’t find the specified secret. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 6881467f-d968-4f4e-ae60-7e3128124cc5)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1632)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1304)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1058)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
    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.secretsmanager.AWSSecretsManagerClient.doInvoke(AWSSecretsManagerClient.java:2024)
    at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.invoke(AWSSecretsManagerClient.java:2000)
    at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.executeGetSecretValue(AWSSecretsManagerClient.java:878)
    at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.getSecretValue(AWSSecretsManagerClient.java:853)
    at helloworld.App.handleRequest(App.java:53)
    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)
    at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.handleRequest(EventHandlerLoader.java:259)
    at lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:178)
    at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888)
    at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:293)
    at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:114)

但是,获取机密管理器中给出的机密的代码是相同的。 是否无法从 sam local 连接到真正的 AWS 服务? 我在 DynamoDB 上遇到了类似的问题,但能够通过使用 DynamoDB Local 来处理它。

关于如何连接到真正的秘密管理器或以某种方式在本地伪造它的任何建议?

当您运行 DynamoDB Local 时,它实际上是在您运行的测试进程中的线程(或作为本地进程,取决于您如何启动它)中运行模拟 DDB 服务器。 遗憾的是,Secrets Manager 和其他 AWS 服务不提供等效的测试解决方案。

但是,如果您返回 ResourceNotFoundException,则您似乎能够成功连接到 Secrets Manager。 与机密管理器的连接使用的帐户可能与您存储机密的帐户不同。 您可以检查代码正在使用哪些凭据的一种方法是使用STS get caller identity调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM