更新时间:2024-11-26 GMT+08:00

自定义鉴权使用说明

使用说明

图1 自定义鉴权操作流程

操作步骤

  1. 配置自定义鉴权函数:用户通过调用函数服务(FunctionGraph)创建自定义鉴权函数。

    图2 函数列表-创建函数
    图3 创建函数-参数信息

  2. 创建自定义鉴权:用户可以通过Console配置自定义鉴权信息,IoTDA负责自定义鉴权信息存库和进行相应的管理维护。用户最多支持配置10个自定义鉴权器,其中最多可以设置1个默认鉴权器。

    图4 自定义鉴权-创建鉴权

    表1 自定义鉴权参数信息

    参数名称

    是否必选

    描述

    鉴权名称

    自定义鉴权器名称。

    鉴权函数

    自定义鉴权器对应的函数名称,从1中FunctionGraph已经创建的函数列表中选取。

    状态

    激活停用参数,用于表示该鉴权是否为激活状态,默认为停用状态。若需使用该鉴权器,则应激活后才能生效。

    签名认证

    启动签名认证后,不满足签名要求的鉴权信息将被拒绝,以减少无效的函数调用,默认为开启。

    token值

    签名校验的token值,开启签名校验时使用,用于认证设备携带的签名信息是否正确。

    公钥

    签名校验的公钥,开启签名校验时使用,用于认证设备携带的签名信息是否正确。

    是否默认自定义鉴权器

    开启后,如果设备发起鉴权时的username没有携带authorizer_name参数,则默认使用此鉴权器。此处默认为不开启。

    是否缓存

    缓存开关,用于开启缓存FunctionGraph的鉴权结果,缓存时间为300分钟~1天,默认不开启。

  3. 设备发起鉴权请求:设备通过MQTT协议发起的CONNECT请求需携带username参数,该参数应包含自定义鉴权的相关可选参数。

    • username格式如下。参数传值时需去掉大括号“{}”,username的每个参数需采用分隔符“|”分隔,各参数具体内容不要出现“|”,否则可能导致鉴权失败。
      {device-identifier}|authorizer-name={authorizer-name}|authorizer-signature={token-signature}|signing-token={token-value}
      示例:
      659b70a0bd3f665a471e5ec9_auth|authorizer-name=Test_auth_1|authorizer-signature=***|signing-token=tokenValue
      表2 username参数信息

      参数名称

      是否必选

      描述

      device-identifier

      设备标识符,建议设定为设备id。

      authorizer-name

      自定义鉴权器名称,需要同用户配置的鉴权器一致。不携带鉴权器名称时,如用户配置了默认的自定义鉴权器,则使用自定义鉴权,否则使用原有的密钥/证书鉴权方式。

      authorizer-signature

      签名校验功能开启时,需要携带该参数。该参数由私钥和signing-token进行加密后获取。需与2中创建自定义鉴权时填写的鉴权名称保持一致。

      signing-token

      签名校验功能开启时,需要携带该参数。该参数为签名校验的token,需与2中创建自定义鉴权时填写的token值保持一致。

    • authorizer-signature通过如下命令行获取:
      echo -n {signing-token} | openssl dgst -sha256 -sign {private key} | openssl base64
      表3 命令行参数解析

      参数名称

      描述

      echo -n {signing-token}

      使用echo命令将签名令牌(signing-token)的值输出,并使用-n参数去掉末尾的换行符。signing-token需与2中创建自定义鉴权时填写的token值保持一致。

      openssl dgst -sha256 -sign

      使用 SHA256 算法对输入的数据进行哈希处理。

      {private key}

      使用 RSA 算法加密的私钥,可传入.pem/.key格式的私钥文件。

      openssl base64

      将签名结果进行Base64编码,以便于传输和存储。

  4. IoTDA处理鉴权请求:IoTDA收到鉴权请求时,会根据username的参数信息和自定义鉴权的配置来决策是否使用自定义鉴权方式。

    1. 判断username是否携带了自定义鉴权名称,如果有携带,则根据平台的自定义鉴权名称,去匹配鉴权器处理函数。如果没有携带,则使用用户配置的默认自定义鉴权器去匹配鉴权处理函数,若无匹配到则使用原有的密钥/证书鉴权方式。
    2. 检查用户是否开启了签名校验,如果开启了签名校验,则校验username携带的签名信息是否可以校验成功,校验失败则直接返回鉴权失败。
    3. 匹配到处理函数后,携带设备的鉴权信息(即5的入参event)并通过函数urn向FunctionGraph发起鉴权请求。

  5. 用户实现鉴权逻辑:用户在1中通过FunctionGraph创建的处理函数中进行开发,函数的返回结果有要求,函数使用示例及返回的JSON格式要求如下:

    exports.handler = async (event, context) => {
        console.log("username=" + event.username);
        // 此处编写您的校验逻辑
        
    
        // 返回的JSON格式(格式固定不变)
        const authRes = {
            "result_code": 200,
            "result_desc": "successful",
            "refresh_seconds": 300,
            "device": {
                "device_id": "myDeviceId",
                "provision_enable": true,
                "provisioning_resource": {
                    "device_name": "myDeviceName",
                    "node_id": "myNodeId",
                    "product_id": "myProductId",
                    "app_id": "customization0000000000000000000",
                    "policy_ids": ["657a4e0c2ea0cb2cd831d12a", "657a4e0c2ea0cb2cd831d12b"]
                }
            }
        }
        return JSON.stringify(authRes);
    }

    其中,函数的请求参数(即event,JSON格式)如下:

    {
        "username": "myUserName",
        "password": "myPassword",
        "client_id": "myClientId",
        "certificate_info": {
            "common_name": "",
            "fingerprint": "123"
        }
    }
    表4 请求参数信息

    参数名称

    参数类型

    是否必选

    描述

    username

    String

    MQTT协议中CONNECT消息的username字段,与3的username格式相同。

    password

    String

    MQTT协议中CONNECT消息的password参数。

    client_id

    String

    MQTT协议中CONNECT消息的clientId参数。

    certificate_info

    JsonObject

    MQTT协议中CONNECT消息的设备证书信息。

    表5 certificate_info证书信息

    参数名称

    参数类型

    是否必选

    描述

    common_name

    String

    设备携带设备证书时,从设备证书中解析的commonName信息。

    fingerprint

    String

    设备携带设备证书时,从设备证书中解析的指纹信息。

    表6 返回参数信息

    参数名称

    参数类型

    是否必选

    描述

    result_code

    Integer

    鉴权结果码, 返回200标识鉴权成功。

    result_desc

    String

    鉴权结果描述信息。

    refresh_seconds

    Integer

    鉴权结果的缓存时间,单位(s)。

    device

    JsonObject

    认证成功时的设备信息。当设备信息中的设备ID不存在时,如果用户开启自注册,则平台会根据设备信息自动创建对应的设备。

    表7 device设备信息

    参数名称

    参数类型

    是否必选

    描述

    device_id

    String

    参数说明:设备ID,自注册场景、非自注册场景都必选。全局唯一,用于唯一标识一个设备。如果携带该参数,平台将设备ID设置为该参数值;建议使用product_id + _ + node_id拼接而成。 取值范围:长度不超过128,只允许字母、数字、下划线(_)、连接符(-)的组合,建议不少于4个字符。

    provision_enable

    Boolean

    参数说明:自注册开关,默认为false。

    provisioning_resource

    JsonObject

    自注册场景必选

    参数说明:自注册参数信息。

    表8 provisioning_resource自注册参数信息

    参数名称

    参数类型

    是否必选

    描述

    device_name

    String

    参数说明:设备名称,资源空间下唯一,用于资源空间下唯一标识一个设备。 取值范围:长度不超过256,只允许中文、字母、数字、以及_?'#().,&%@!-等字符的组合,建议不少于4个字符。

    最小长度:1

    最大长度:256

    node_id

    String

    参数说明:设备标识码,通常使用IMEI、MAC地址或Serial No作为node_id。 设备标识码长度为1到64个字符,包含英文字母、数字、连接号-和下划线_。 注意:NB设备由于模组烧录信息后无法配置,所以NB设备会校验node_id全局唯一。 取值范围:长度不超过64,只允许字母、数字、下划线(_)、连接符(-)的组合,建议不少于4个字符。

    product_id

    String

    参数说明:设备关联的产品ID,用于唯一标识一个产品模型,创建产品后获得。取值范围:长度不超过256,只允许中文、字母、数字、以及_?'#().,&%@!-等字符的组合,建议不少于4个字符。

    最小长度:1

    最大长度:256

    app_id

    String

    参数说明:资源空间ID,该参数指定创建的设备归属到哪个资源空间。 取值范围:长度不超过36,只允许字母、数字、下划线(_)、连接符(-)的组合。

    policy_ids

    List<String>

    参数说明:Topic策略ID。

    图5 函数编写-部署

  6. FunctionGraph返回结果后,判断是否需要支持自注册功能,如果需要则触发设备的自动注册。自注册设备全部默认为密钥认证,密钥随机生成。IoTDA收到鉴权结果后,进行接下来的业务实现流程。