
# 自定义模板使用说明
#### 概述
自定义模板鉴权是指用户可以使用平台提供的[内部函数](https://support.huaweicloud.com/devg-iothub/iot_02_0211.html)实现自定义的鉴权方式，而不需使用[平台默认鉴权方式](https://support.huaweicloud.com/api-iothub/iot_06_v5_3009.html)，对接入平台的设备进行身份认证，用户可以通过平台预置的函数灵活编排鉴权方式。
#### 应用场景
- 迁移场景：当设备从第三方物联网平台迁移到华为云IoTDA时，通过配置平台提供的自定义鉴权模板可以兼容原来的鉴权方式，设备侧无需改动实现无缝迁移。
- 原生场景：自定义模板鉴权可以让用户扩展自己的设备鉴权方式，而不需要与平台默认鉴权绑定，极大的提高了设备可扩展性。
 
#### 自定义模板鉴权流程
图1自定义模板鉴权流程图   
![](https://support.huaweicloud.com/devg-iothub/figure/zh-cn_image_0000002338968293.png "点击放大")
#### 约束与限制
1. 使用自定义鉴权功能，要求设备必须使用TLS同时支持[SNI(Server Name Indication)](https://datatracker.ietf.org/doc/html/rfc3546#section-3.1)，SNI中需要携带平台分配的域名。
2. 默认每个用户最多支持5个自定义鉴权模板，只能启用一个激活状态的模板。
3. 鉴权模板函数嵌套最大深度为5层。
4. 模板内容体最大长度不能超过4000字符，且不能包含中文字符。
5. 设备为密钥认证类型时，模板密码函数必须包含设备原始密钥参数(iotda::device::secret)。
6. 使用模板鉴权时，鉴权参数username不能与自定义函数鉴权username格式重叠，否则会使用自定义函数鉴权，比如：
   ```
   {deviceId}|authorizer-name={authorizer-name}|xxx
   ```
   
7. 自定义模板鉴权优先级高于平台默认鉴权，即激活自定义鉴权模板后设备就会使用模板鉴权，不会再使用平台默认鉴权方式。
![](https://support.huaweicloud.com/devg-iothub/public_sys-resources/note_3.0-zh-cn.png)
自定义认证功能是为方便用户快速接入平台，免于设备侧改造，平台将使用您提供的鉴权模板进行鉴权，请合理审视认证方式的安全程度，避免使用弱校验或者免校验，由于您自定义模板安全程度过低造成的安全问题，平台将不承担任何安全责任。
#### 操作步骤
1. 创建鉴权模板：进入设备接入控制台左侧导航栏，选择"设备 \> 自定义鉴权"，单击"自定义模板"，单击"创建鉴权模板"。本示例演示使用的鉴权模板与[系统默认鉴权](https://support.huaweicloud.com/api-iothub/iot_06_v5_3009.html)一致。
   
   图2自定义鉴权-创建鉴权模板   
   ![](https://support.huaweicloud.com/devg-iothub/figure/zh-cn_image_0000001981501733.png "点击放大")
   模板整体内容如下：
   ```
   {
     "template_name": "system-default-auth",
     "description": "华为云IoTDA系统默认鉴权模板示例",
     "status": "ACTIVE",
     "template_body": {
       "parameters": {
         "iotda::mqtt::client_id": {
           "type": "String"
         },
         "iotda::mqtt::username": {
           "type": "String"
         },
         "iotda::device::secret": {
           "type": "String"
         }
       },
       "resources": {
         "device_id": {
           "Ref": "iotda::mqtt::username"
         },
         "timestamp": {
           "type": "FORMAT",
           "pattern": "yyyyMMddHH",
           "value": {
             "Fn::SubStringAfter": [
               "${iotda::mqtt::client_id}",
               "_0_1_"
             ]
           }
         },
         "password": {
           "Fn::HmacSHA256": [
             "${iotda::device::secret}",
             {
               "Fn::SubStringAfter": [
                 "${iotda::mqtt::client_id}",
                 "_0_1_"
               ]
             }
           ]
         }
       }
     }
   }
   ```
   表1鉴权模板参数信息 
   | 参数            | 参数名称      | 是否必填 | 描述                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   |:---|:---|:---|:---|
   | template_name | 模板名称      | 是    | 鉴权模板名称，单个用户下模板名称不能重复，长度不超过128，只允许字母、数字、下划线（_）、连接符（-）的组合。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | description   | 描述        | 否    | 鉴权模板的描述信息，长度不超过2048，只允许中文、字母、数字、以及_?'#().,\&%@!-等字符的组合。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
   | status        | 状态        | 否    | 是否激活该模板，默认状态为未激活，一个用户下只能有一个已激活状态的模板。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
   | parameters    | 参数        | 是    | 平台预定义的MQTT连接参数列表，当设备使用密码认证时模板必须包含设备原始密钥参数（iotda::device::secret）。 平台预定义了如下参数： iotda::mqtt::client_id ：mqtt连接参数三元组中的Client Id iotda::mqtt::username ：mqtt连接参数三元组中的User Name iotda::certificate::country : 设备证书（国家/地区,C ） iotda::certificate::organization : 设备证书（组织,O） iotda::certificate::organizational_unit : 设备证书（组织单位,OU） iotda::certificate::distinguished_name_qualifier : 设备证书（可辨别名称限定符,dnQualifier） iotda::certificate::state_name : 设备证书（省市,ST） iotda::certificate::common_name : 设备证书（公用名,CN） iotda::certificate::serial_number : 设备证书（序列号,serialNumber） iotda::device::secret ：表示设备原始密钥 |
   | device_id     | 设备ID函数    | 是    | 设备ID取值函数，JSON格式，平台通过解析该函数获取对应设备信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
   | timestamp     | 是否开启时间戳校验 | 否    | 是否校验设备连接信息中的时间戳，如果设备连接参数（clientId、username）中包含时间戳建议开启校验。开启校验平台会对比设备携带时间戳与平台系统时间，若设备时间戳加一小时小于平台系统时间则校验失败。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
   | type          | 时间戳类型     | 否    | UNIX：表示时间戳格式为Unix时间戳，长整型，单位秒。 FORMAT：格式化时间戳类型，比如：2024-03-28 11:47:39、2024/03/28 03:49:13                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
   | pattern       | 时间戳格式     | 否    | 时间格式模板，时间戳类型为FORMAT时必填，具体字符含义如下： y：年 M：月 d：日 H：时 m：分 s：秒 S：毫秒 示例：yyyy-MM-dd HH:mm:ss、yyyy/MM/dd HH:mm:ss                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
   | value         | 时间戳取值函数   | 否    | 开启时间戳校验后必填，设备时间戳获取函数，平台通过执行该函数获取设备建链时的时间戳。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
   | password      | MQTT密码函数  | 否    | 密码函数，当设备认证类型为密钥认证时必填，且模板参数中必须包含设备原始密钥参数（iotda::device::secret），当设备为证书认证时可不填。设备认证类型参考[注册设备](https://support.huaweicloud.com/usermanual-iothub/iot_01_0031.html)。平台把设备原始密钥等参数填入函数计算结果，若函数结果与设备建链携带的password参数一致则认证通过，否则认证失败。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
      
   
   
2. 选择设备调试模板：单击"调试"选择一个设备进行调试，输入mqtt连接参数后单击"调试"查看调试结果。注意：使用系统标准格式的clientId平台会校验username参数与clientId前缀一致。 
   图3自定义模板-调试   
   ![](https://support.huaweicloud.com/devg-iothub/figure/zh-cn_image_0000001950382316.png "点击放大")
   设备调试成功后单击"激活"启用模板，一旦激活模板所有设备鉴权将使用该模板，且已激活状态下的模板不能修改，后续修改模板建议新创建一个副本模板进行调试，确认无误后进行模板切换。
   
   
   
3. 使用mqtt.fx工具模拟设备真实建链，在控制台查看设备处于在线状态，Broker Address填[平台接入地址](https://support.huaweicloud.com/iothub_faq/iot_faq_01006.html)，选择"总览 \> 接入信息"，端口使用8883端口。
   
   图4设备建链   
   ![](https://support.huaweicloud.com/devg-iothub/figure/zh-cn_image_0000002305089154.png "点击放大")
   图5设备列表-设备在线   
   ![](https://support.huaweicloud.com/devg-iothub/figure/zh-cn_image_0000001950367902.png "点击放大")
   
   
 
