【问题标题】:AWS S3 credential/certificate errorAWS S3 凭证/证书错误
【发布时间】:2016-11-21 18:48:51
【问题描述】:

我对 AWS 完全陌生。我正在尝试使用 AWS S3 通知 API。我收到以下错误。

com.amazonaws.services.sns.model.AmazonSNSException:请求中包含的安全令牌无效。 (服务:AmazonSNS;状态码:403;错误码:InvalidClientTokenId;...

我不知道出了什么问题。对于我的 accessID 和 secretID。我使用主要的 AWS 代码进行身份验证。我应该使用主要的 AWS 凭证还是其他什么东西。我没有使用任何类型的证书。我不知道他们是否甚至需要。

我使用 AWS 提供的示例代码进行了一些修改来读取属性文件,而不是硬编码 accessID 和 secretID。

有人可以引导我朝着正确的方向前进吗?我完全糊涂了。

public class AmazonSNSReceiver {
     // AWS credentials -- replace with your credentials
    static String ACCESS_KEY;
    static String SECRET_KEY;

    // Shared queue for notifications from HTTP server
    static BlockingQueue<Map<String, String>> messageQueue = new LinkedBlockingQueue<Map<String, String>>();

    // Receiver loop
    public static void main(String[] args) throws Exception {
        AmazonSNSReceiver sns = new AmazonSNSReceiver();

        sns.getPropertyValues();
        if (args.length == 1) {
        sns.SNSClient(args[0]);
            } else {
                sns.SNSClient("8989");
        }
    }
        // Create a client
        public void SNSClient(String thisport) throws Exception{

        AmazonSNSClient service = new AmazonSNSClient(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));

        // Create a topic
        CreateTopicRequest createReq = new CreateTopicRequest().withName("MyTopic");
        CreateTopicResult createRes = service.createTopic(createReq);

        // Get an HTTP Port
        int port = thisport == null ? 8989 : Integer.parseInt(thisport);

        // Create and start HTTP server
        Server server = new Server(port);
        server.setHandler(new AmazonSNSHandler());
        server.start();

        // Subscribe to topic
        SubscribeRequest subscribeReq = new SubscribeRequest()
            .withTopicArn(createRes.getTopicArn())
            .withProtocol("http")
            .withEndpoint("http://" + InetAddress.getLocalHost().getHostAddress() + ":" + port);
        service.subscribe(subscribeReq);

        for (;;) {

            // Wait for a message from HTTP server
            Map<String, String> messageMap = messageQueue.take();

            // Look for a subscription confirmation Token
            String token = messageMap.get("Token");
            if (token != null) {

                // Confirm subscription
                ConfirmSubscriptionRequest confirmReq = new ConfirmSubscriptionRequest()
                    .withTopicArn(createRes.getTopicArn())
                    .withToken(token);
                service.confirmSubscription(confirmReq);

                continue;
            }

            // Check for a notification
            String message = messageMap.get("Message");
            if (message != null) {
                System.out.println("Received message: " + message);
            }

        }

    }

    public void getPropertyValues() throws IOException {

        Properties prop = new Properties();

        InputStream properties = getClass().getClassLoader().getResourceAsStream("SNS.properties");

        prop.load(properties);

        ACCESS_KEY = prop.getProperty("ACCESS_KEY");
        SECRET_KEY = prop.getProperty("SECRET_KEY");

    }

    // HTTP handler
    static class AmazonSNSHandler extends AbstractHandler {

        // Handle HTTP request
        public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException {

            // Scan request into a string
            Scanner scanner = new Scanner(request.getInputStream());
            StringBuilder sb = new StringBuilder();
            while (scanner.hasNextLine()) {
                sb.append(scanner.nextLine());
            }

            // Build a message map from the JSON encoded message
            InputStream bytes = new ByteArrayInputStream(sb.toString().getBytes());
            Map<String, String> messageMap = new ObjectMapper().readValue(bytes, Map.class);

            // Enqueue message map for receive loop
            messageQueue.add(messageMap);

            // Set HTTP response
            response.setContentType("text/html");
            response.setStatus(HttpServletResponse.SC_OK);
            ((Request) request).setHandled(true);
        }        
    }
}

【问题讨论】:

  • 我使用了错误的凭据。但我收到错误消息:线程“主”com.amazonaws.services.sns.model.AuthorizationErrorException 中的异常:未授权订阅内部端点(服务:AmazonSNS;状态代码:403;错误代码:AuthorizationError;我该如何订阅到内部端点?我正在尝试使用控制台,但没有任何地方可以使用。
  • 此评论使您的问题的性质发生了重大变化。您不能这样做:InetAddress.getLocalHost().getHostAddress() + ":" + port); 这将返回一个私有(“内部端点”)IP 地址。 SNS 将仅传送到 Internet 可访问的端点。 SNS 在 AWS 内部,但在您的 VPC 外部,因此它可以从外部访问您。

标签: amazon-web-services amazon-s3


【解决方案1】:

您的应用程序需要提供 AWS 凭证。这些凭据可以通过多种方式获得:

  • 创建 IAM 用户 并生成访问密钥和秘密密钥。在 configuration file 中包含凭据(将它们放在您的应用程序中不是一个好主意,因为它们可能会意外地发布到其他地方)。
  • 如果在 Amazon EC2 实例上运行代码,请创建一个 IAM 角色,并在实例启动时将该角色分配给该实例。然后,凭据将自动提供给在该实例上运行的应用程序。

还需要assign permissions 给 IAM 用户/角色。这些权限授予调用各种 AWS API 调用的权利。您收到AuthorizationError 的事实表明正在使用的凭据没有足够的权限。

见:Managing Access to Your Amazon SNS Topics

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    相关资源
    最近更新 更多