更新时间:2024-09-19 GMT+08:00

使用HTTP/HTTPS转发

概述

订阅推送的示意图如下图所示:

物联网平台采用HTTPS协议向应用服务器进行消息推送时,物联网平台需要校验应用服务器的真实性,需要在物联网平台上加载CA证书,该证书由应用服务器侧提供(调测时可自行制作调测证书,商用时建议更换为商用证书,否则会带来安全风险)。

推送机制:物联网平台向应用服务器推送消息后,如果应用服务器接收消息成功,会向物联网平台返回200 OK响应码。如果应用服务器无响应(或响应时间超过15秒),或者应用服务器向物联网平台返回非200响应码(如500、501、502、503、504等),表示消息推送失败,消息推送失败后该消息将被丢弃。推送失败连续累计达到10次,物联网平台会将该订阅URL的主机地址加入黑名单,在黑名单期间消息将会积压在平台(默认积压最近24小时或1GB数据,若只想保留最新数据可参考数据转发积压策略配置进行配置)。此后每3分钟尝试对黑名单中的订阅URL主机地址进行消息推送,如果推送失败,则继续保持黑名单;如果推送成功,则解除黑名单。解除黑名单后消息将会以最大流控值推送完积压的消息后才会正常推送最新消息(默认流控为800TPS,自定义配置参考数据转发流控策略配置)。

如何进行数据订阅

应用服务器接入到“设备接入服务”后,在控制台创建订阅任务,也可以通过调用API接口进行数据订阅。

推送数据格式

数据订阅成功后,物联网平台推送到应用侧的数据格式样例请参考流转数据

http协议消息头中,媒体类型信息Content-Type为application/json;字符集为utf-8。

加载推送证书

使用HTTPS协议推送,需要参考本小节完成推送证书的加载,然后参考HTTP/HTTPS服务端订阅在控制台创建订阅任务。

  • 如果应用服务器取消了订阅后再重新订阅(URL不变),需要在物联网平台上重新上传CA证书。
  • 如果应用服务器新增了订阅类型(新增URL),需要在物联网平台上加载与该URL对应的CA证书。即使新增URL使用的CA证书与原来推送的URL使用相同的证书,也需要重新上传CA证书。
  1. 访问设备接入服务,单击“管理控制台”进入设备接入控制台。选择您的实例,单击实例卡片进入。
  2. 在左侧导航栏选择规则 > 服务端证书,单击“上传证书”,按照下表填写相关信息后,单击“确定”完成证书的加载。

    参数名称

    参数说明

    证书名称

    可自定义,用于区分不同证书

    CA证书

    需要提前申请和购买CA证书文件,CA证书由应用服务器侧提供。

    说明:

    调测时可自行制作调测证书,商用时建议更换为商用证书,否则会带来安全风险。

  3. 单击左侧导航栏规则>服务端证书,选择对应证书,单击可获取证书ID,用于后续创建规则动作时,作为参数使用。

    图1 服务端证书-获取证书ID

制作调测证书

调测证书,又叫做自签名证书,用于客户端通过HTTPS访问服务端时进行安全认证。在物联网平台的使用中,可用于物联网平台向应用服务器采用HTTPS协议推送数据时,物联网平台认证应用服务器的合法性。本文以Windows环境为例,介绍通过Openssl工具制作调测证书的方法,生成的证书为PEM编码格式的证书,后缀为.cer。

常见的证书存储格式如下表所示。

存储格式

说明

DER

二进制编码,后缀名.der/.cer/.crt

PEM

BASE 64编码,后缀名.pem/.cer/.crt

JKS

Java的证书存储格式,后缀名.jks

自签名证书仅用于调测阶段,在商用时,您需要向知名CA机构申请证书,否则可能会带来安全风险。

  1. 在浏览器中访问这里,下载并安装OpenSSL工具。
  2. 以管理员身份运行cmd命令行窗口。
  3. 执行cd c:\openssl\bin(请替换为openssl实际安装路径),进入openssl命令视图。
  4. 执行如下命令生成CA根证书私钥文件ca_private.key。

    openssl genrsa -passout pass:123456 -aes256  -out ca_private.key 2048
    • aes256:代表加密算法。
    • passout pass:代表私钥密码。
    • 2048:代表密钥长度。

  5. 执行如下命令使用CA根证书私钥文件生成csr文件ca.csr,用于6生成CA根证书。

    openssl req -passin pass:123456 -new -key ca_private.key -out ca.csr -subj "/C=CN/ST=GD/L=SZ/O=Huawei/OU=IoT/CN=CA"

    如下信息您可以根据实际情况进行修改。

    • C:代表国家,填写CN。
    • ST:地区,如GD。
    • L:城市,如SZ。
    • O:组织,如Huawei。
    • OU:组织单位,如IoT。
    • CN:Common Name,填写为CA的组织名,如CA。

  6. 执行如下命令生成CA根证书ca.cer。

    openssl x509 -req -passin pass:123456 -in ca.csr -out ca.cer -signkey ca_private.key -CAcreateserial -days 3650

    如下信息您可以根据实际情况进行修改。

    • passin pass:必须与4中设置的私钥密码保持一致。
    • days:代表证书有效期。

  7. 执行如下命令生成应用服务器端私钥文件。

    openssl genrsa -passout pass:123456 -aes256 -out server_private.key 2048

  8. 执行如下命令生成应用服务器端csr文件,用于生成服务端证书。

    openssl req -passin pass:123456 -new -key server_private.key -out server.csr -subj "/C=CN/ST=GD/L=SZ/O=Huawei/OU=IoT/CN=appserver.iot.com"

    如下信息您可以根据实际情况进行修改。

    • C:代表国家,填写CN。
    • ST:地区,如GD。
    • L:城市,如SZ。
    • O:组织,如Huawei。
    • OU:组织单位,如IoT。
    • CN:Common Name,一般填写为应用服务器的域名或IP。

  9. 通过CA私钥文件ca_private.key对服务端csr文件server.csr进行签名,生成服务端证书文件server.cer。

    openssl x509 -req -passin pass:123456 -in server.csr -out server.cer -sha256 -CA ca.cer -CAkey ca_private.key -CAserial ca.srl -CAcreateserial -days 3650

  10. (可选)如果您需要.crt/.pem后缀的证书,可以根据如下命令进行转换。下面将以server.cer转为为server.crt为例进行说明,需要转换ca.cer证书时,请将命令中的server替换为ca。

    openssl x509 -inform PEM -in server.cer -out server.crt

  11. 在openssl安装目录的bin文件夹下,获取生成的CA证书(ca.cer/ca.crt/ca.pem)、应用服务器证书(server.cer/server.crt/server.pem)和私钥文件(server_private.key)。其中CA证书用于加载到物联网平台,应用服务器证书和私钥文件用于加载到应用服务器。

配置HTTP/HTTPS服务端订阅

本小节介绍如何在物联网平台配置HTTP/HTTPS服务端订阅。

  1. 访问设备接入服务,单击“管理控制台”进入设备接入控制台。选择您的实例,单击实例卡片进入。
  2. 选择左侧导航栏的规则 > 数据转发,单击页面左上角的“创建规则”
  3. 参考下表填写参数后,单击“创建规则”

    表1 创建规则参数列表

    参数名

    参数说明

    规则名称

    创建的规则名称。

    规则描述

    对该规则的描述。

    数据来源

    • 设备:将操作设备的信息,如设备添加、设备删除、设备更新设置为数据来源。当数据来源选择“设备”时,不支持快速配置。
    • 设备属性:将归属在某个资源空间下的设备上报给平台的属性值设置为数据来源。单击右侧的“快速配置”勾选需要转发的产品、属性、服务等数据。
    • 设备消息:将归属在某个资源空间下的设备上报给平台的消息设置为转发目标。单击右侧的“快速配置”,仅转发指定Topic的数据。选择所属产品,填写Topic名称。您可以使用在产品详情页面自定义的Topic,也可以使用平台预置的Topic
    • 设备消息状态:将设备和平台之间流转的设备消息状态变更设置为转发目标。设备消息状态详见这里。当数据来源选择“设备消息状态”,不支持快速配置。
    • 设备状态:将归属在某个资源空间下的直连或非直连设备状态变更转发至其他服务。单击“快速配置”,您可以转发设备状态为“在线”、“离线”和“异常”的设备信息到其他服务。物联网平台直连设备状态详见这里
    • 批量任务:将批量任务状态的数据设置为数据来源。当数据来源选择“批量任务”时,不支持快速配置。
    • 产品:将操作产品的信息,如产品添加、产品删除、产品更新设置为数据来源。当数据来源选择“产品”时,不支持快速配置。
    • 设备异步命令状态:针对LwM2M/CoAP协议的设备,物联网平台支持下发异步命令给设备。将异步命令的状态变更设置为数据来源。物联网平台设备异步命令状态详见这里。当数据来源选择“设备异步命令状态”时,不支持快速配置。
    • 运行日志:将MQTT设备的业务运行日志设置为数据来源。当数据来源选择“运行日志”时,不支持快速配置。

    触发事件

    选择数据来源后,对应修改触发事件。

    资源空间

    您可以选择单个资源空间或所有资源空间。当选择“所有资源空间”时,不支持快速配置。

  4. 在设置转发目标页面,单击“添加”,在弹出的页面中参考下表配置完参数后,单击“确认”。

    参数名

    参数说明

    转发目标

    选择“第三方应用服务(HTTP推送)”

    推送URL

    物联网平台推送消息到应用服务器的URL。例如,推送URL为“https://www.example.com:8443/example/”,则加载推送证书“域名/IP与端口”“www.example.com:8443”

    • 如果“推送URL”使用HTTP协议,不需要使用CA证书;
    • 如果“推送URL”使用HTTPS协议,需要上传CA证书,证书的上传可参考加载推送证书

    Token

    3-32位长度英文或数字, 用于认证签名,平台推送数据到客户服务器时,将会使用Token进行签名并将签名信息组装到头域中进行推送。

    证书ID

    仅推送Https服务器有效,作为Truststore证书,用于客户端校验服务端合规商用证书,如自签名证书、证书链不完整证书等不合规证书该配置不可用。

    SNI证书域名

    启用SNI需要配置证书域名,同时确保服务端已经正确地配置了相应的证书和域名。

  5. 完成完整的规则定义后,单击“启动规则”,实现数据转发至HTTP/HTTPS消息队列。

HTTP/HTTPS推送基于Token认证物联网平台

用户如果在添加转发目标到第三方应用服务(HTTP推送)时,已勾选“鉴权”并填写Token,物联网开发平台将在HTTP或HTTPS请求中头部增加如下字段:

参数

描述

timestamp

平台推送时的时间戳

nonce

平台生成的随机数

signature

结合token、timestamp、nonce组成的签名

签名规则:

  1. 将token、timestamp、nonce进行字典排序。
  2. 将排序后的字符串进行sha256加密。
  3. 客户收到推送信息后,可以根据token以及头域中的timestamp和nonce按照该规则进行加密后与头域中的signature进行比较来确认是否是平台的消息。

校验signature的java示例如下:

  1. 引入依赖,具体版本请根据实际业务需求来决定。
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>${commons.version}</version>
    </dependency>
  2. 从请求头中获取签名信息并使用commons-codec依赖包进行签名。
    public boolean checkSignature(String nonce, String timestamp, String signature, String token) {
        List<String> list = new ArrayList<>();
        list.add(token);
        if (StringUtil.isNotEmpty(nonce)) {
            list.add(nonce);
        }
        if (StringUtil.isNotEmpty(timestamp)) {
            list.add(timestamp);
        }
        Collections.sort(list);
        StringBuilder signatureBuilder = new StringBuilder();
        for (String s : list) {
            signatureBuilder.append(s);
        }
        String serverSignature = DigestUtils.sha256Hex(signatureBuilder.toString());
        if (StringUtil.isNotEmpty(serverSignature) && serverSignature.equals(signature)) {
            return true;
        }
        return false;
    }
  3. 例如某次请求,用户设置的Token为aaaaaa,头域中收到如下参数:
    nonce:8b9b796d388d49bba43adaa53aaf5bc4
    timestamp: 1675654743514
    signature: 2ff821fb8a976ede7d06434395ec8c25e4100bff8b3d12d8099ef7e30b58bd4c

    排序后的字符串为:16756547435148b9b796d388d49bba43adaa53aaf5bc4aaaaaa,sha256加密后:2ff821fb8a976ede7d06434395ec8c25e4100bff8b3d12d8099ef7e30b58bd4c

    token创建后, 每次修改转发目标时都需要重新填写token,否则token将不生效。

平台认证

作为服务端,应用侧如果需要认证IoT平台的身份,需要加载IoT平台的CA证书。请参考资源页面获取。