微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

连接到 websocket 以实时使用 amazon chime API

如何解决连接到 websocket 以实时使用 amazon chime API

我想使用 Amazon Chime API 扩展我用 JavaFX 编写的软件以使用其消息传递。我知道有 JS SDK 可以毫无问题地建立消息传递 websocket 会话。但是在 java SDK 中没有相关的类。所以我想使用 STOMP 库来消费 websocket 端点。

当时我正在努力制作正确的 request,即 signing AWS request(计算 X-AMZ-Signature)

根据 post,我正在尝试计算正确的 X-AMZ-Signature 请求参数。这是课程:

@Slf4j
@Service
public class Aws4Signer {
    
    private final static String REQUEST_CONTENT_TYPE = "application/json";
    private final static String AUTH_ALGORITHM = "AWS4-HMAC-SHA256";
    private final static String REQUEST_METHOD = "GET";

    @Data
    class AuthenticationData {
        @NonNull
        String timestamp;
        @NonNull
        String date;
        @NonNull
        String authorizationHeader;
    }
    
    private AppConfig appConfig = new AppConfig();

    /**
     * Gets the timestamp in YYYYMMDD'T'HHMMSS'Z' format,which is the required
     * format for AWS4 signing request headers and credential string
     *
     * @param dateTime
     *            an OffsetDateTime object representing the UTC time of current
     *            signing request
     * @return the formatted timestamp string
     *
     * @see <a href=
     *      "https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html">
     *      Examples of the Complete Version 4 Signing Process (Python)</a>
     */
    public String getTimeStamp(OffsetDateTime dateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");
        String formatDateTime = dateTime.format(formatter);
        return formatDateTime;
    }

    /**
     * Gets the date string in yyyyMMdd format,which is required to build the
     * credential scope string
     *
     * @return the formatted date string
     */
    public String getDate(OffsetDateTime dateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formatDateTime = dateTime.format(formatter);
        return formatDateTime;
    }

    public byte[] generateAws4SigningKey(String timestamp) {
        String secretKey = appConfig.getAwsAuthConfig().getSecretKey();
        String regionName = appConfig.getAwsAuthConfig().getServiceRegion();
        String serviceName = appConfig.getAwsAuthConfig().getServiceName();

        byte[] signatureKey = null;
        try {
            signatureKey = Aws4SignatureKeyGenerator.generateSignatureKey(secretKey,timestamp,regionName,serviceName);
        } catch (Exception e) {
            log.error("An error has ocurred when generate signature key: " + e,e);
        }

        return signatureKey;
    }

    /**
     * Builds an {@link AuthenticationData} object containing the timestamp,date,* payload hash and the AWS4 signature
     * <p>
     *
     * The signing logic was translated from the Python implementation,see this
     * link for more details: <a href=
     * "https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html">Examples
     * of the Complete Version 4 Signing Process (Python)</a>
     *
     * @param target
     * @param requestBody
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     * @throws SignatureException
     * @throws IllegalStateException
     *
     */
    public AuthenticationData buildAuthorizationData() throws NoSuchAlgorithmException,UnsupportedEncodingException,InvalidKeyException,SignatureException,IllegalStateException {
        log.info("predict - start");

        // Starting building the lengthy signing data
        AwsAuthConfig awsAuthConfig = appConfig.getAwsAuthConfig();
        String payloadHash = Hmac.getSha256Hash(requestBody);

        OffsetDateTime Now = OffsetDateTime.Now(ZoneOffset.UTC);
        String timestamp = getTimeStamp(Now);
        String date = getDate(Now);

        // Step 1 is to define the verb (GET,POST,etc.) -- already done by defining
        // constant REQUEST_METHOD

        // Step 2: Create canonical URI--the part of the URI from domain to query
        // string (use '/' if no path)
        String canonical_uri = "/connect";

        // Step 3: Create the canonical query string. In this example,request
        // parameters are passed in the body of the request and the query string
        // is blank.
        String canonical_querystring = buildCanonicalQueryString();

        // Step 4: Create the canonical headers. Header names must be trimmed
        // and lowercase,and sorted in code point order from low to high.
        // Note that there is a trailing \n.
        String canonical_headers = "content-type:" + REQUEST_CONTENT_TYPE + "\n"
                                 + "host:" + awsAuthConfig.getServiceHost() + "\n"
                                 + "x-amz-date:" + timestamp + "\n";
        
        String signed_headers = "content-type;host;x-amz-date";

        log.debug("canonical_headers : {}",canonical_headers);

        String canonical_request = REQUEST_METHOD + "\n" + canonical_uri + "\n" + canonical_querystring + "\n"
                + canonical_headers + "\n" + signed_headers;

        log.debug("canonical_request : {}",canonical_request);

        String credential_scope = date + "/" + awsAuthConfig.getServiceRegion() + "/" + awsAuthConfig.getServiceName()
                + "/" + "aws4_request";
        String canonical_request_hash = Hmac.getSha256Hash(canonical_request);

        log.debug("canonical_request_hash : {}",canonical_request_hash);

        String string_to_sign = AUTH_ALGORITHM + "\n" + timestamp + "\n" + credential_scope + "\n"
                + canonical_request_hash;

        log.debug("string_to_sign : {}",string_to_sign);
        byte[] sigKey = generateAws4SigningKey(date);

        String signature = Hmac.calculateHMAC(string_to_sign,sigKey,Hmac.HMAC_SHA256);
        String authorization_header = AUTH_ALGORITHM + " " + "Credential=" + awsAuthConfig.getAccessKey() + "/"
                + credential_scope + "," + "SignedHeaders=" + signed_headers + "," + "Signature=" + signature;

        log.debug("authorization_header : {}",authorization_header);

        return new AuthenticationData(timestamp,authorization_header);
    }

    private String buildCanonicalQueryString() {
        String canonicalRequest = REQUEST_METHOD + "\n" +
                                 "/connect" + "\n" +
                "X-Amz-Algorithm=AWS4-HMAC-SHA256\n" +
                "&X-Amz-Credential=MYACCESKEY%2F"+ getDate(OffsetDateTime.Now()) + "%2Fus-east-1%2Fchime%2Faws4_request\n" +
                "&X-Amz-Date=" + getTimeStamp(OffsetDateTime.Now()) +"\n" +
                "&X-Amz-Expires=10\n" +
                "&X-Amz-SignedHeaders=host\n" +
                "&sessionId=" + UUID.randomUUID() +"\n" +
                "&userArn=" + "MYUSERARN";

        return canonicalRequest;
    }

}

提供的信息

  • 主机:node001.ue1.ws-messaging.chime.aws
  • 服务名称:chime
  • 区域:us-east-1

生成签名,我正在尝试通过邮递员使用它,但邮递员无法连接到端点 node001.ue1.ws-messaging.chime.aws/connect,只是说“连接 ETIMEDOUT 54.162.103.101: 80'。

我是亚马逊的新手,所以对我来说有点困难。你能说我错在哪里吗?

感谢任何帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?