设为首页 收藏本站
查看: 1361|回复: 0

[经验分享] Azure IoT Hub 入门

[复制链接]

尚未签到

发表于 2017-6-30 06:28:17 | 显示全部楼层 |阅读模式
  最初开始接触Azure IoT Hub的时候,被各种connection string和endpoint弄的眼花缭乱。本入门系列旨在将Azure IoT Hub 权限管理机制以及各个接口(endpoint)的用途解释清楚。
  首先抛出一个典型的IoT解决方案的架构,以让读者对IoT有个大概的认识。该架构通过平台层的核心服务和应用层组件来实现典型IoT解决方案需要解决的三个主要问题:


  • 设备的连接;
  • 数据的处理、分析与管理;
  • 数据的有效呈现以及业务逻辑的处理。
DSC0000.png

  回到本文的主题:IoT Hub 权限管理以及Endpoint。


    • Azure IoT Hub 权限管理
      总结起来,Azure 提供了以下两种权限管理机制:

      • Hub 层面的共享访问策略(shared access policies)
        在portal上新创建的IoT Hub默认包含了以下策略,你可以对已有的策略进行修改,或者添加新的策略。

        • iothubowner: 拥有所有的权限
        • service: ServiceConnect 权限 (给予服务端通信监控接口访问权限,例如读取device-to-cloud的消息,发送cloud-to-device消息等)
        • device: DeviceConnect 权限(给予设备端的通信接口访问权限,例如发送device-to-cloud消息)
        • registryRead: RegistryRead 权限(读设备注册列表)
        • registryReadWrite: RegistryRead和RegistryWrite权限(读写设备注册列表)  

      • device 层面的安全令牌(security credentials)
        IoT Hub维护了一个所有设备的注册列表。列表里的每一个设备都有自己的symmetric key,用户可以根据这个symmetric key 来获得DeviceConnect的权限。


      针对特定场景下所需要的权限举例如下:

      * 设备管理组件:registryReadWrite 策略

      * 事物处理组件:service 策略

      * 单设备连接组件:device策略


  • 如何生成安全令牌
    为避免直接在网络上传输密钥,IoT Hub通过安全令牌来对设备以及云端服务进行授权。一般情况下,Azure IoT Hub SDKs会自动根据密钥生成安全令牌。但在某些情况下(例如直接使用MQTT,AMQP或者HTTP接口)需要客户自己去生成安全令牌。
    安全令牌的格式如下:



    SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
      针对每个字段的注解,请参考:https://azure.microsoft.com/en-us/documentation/articles/iot-hub-devguide-security/
    下面给出完整的C#实现:


    DSC0001.gif DSC0002.gif


    public class SharedAccessSignatureBuilder
    {
    private string key;
    public string Key
    {
    get
    {
    return this.key;
    }
    set
    {
    // StringValidationHelper.EnsureBase64String(value, "Key");
    this.key = value;
    }
    }
    public string KeyName
    {
    get;
    set;
    }
    public string Target
    {
    get;
    set;
    }
    public TimeSpan TimeToLive
    {
    get;
    set;
    }
    public string TargetService
    {
    get;
    set;
    }
    public SharedAccessSignatureBuilder()
    {
    this.TimeToLive = TimeSpan.FromMinutes(20);
    TargetService = "iothub";
    }
    private static string BuildExpiresOn(TimeSpan timeToLive)
    {
    DateTime dateTime = DateTime.UtcNow.Add(timeToLive);
    TimeSpan timeSpan = dateTime.Subtract(SharedAccessSignatureConstants.EpochTime);
    return Convert.ToString(Convert.ToInt64(timeSpan.TotalSeconds, CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
    }
    private static string BuildSignature(string keyName, string key, string target, TimeSpan timeToLive, string targetService = "iothub")
    {
    string str = SharedAccessSignatureBuilder.BuildExpiresOn(timeToLive);
    string str1 = WebUtility.UrlEncode(target);
    List<string> strs = new List<string>()
    {
    str1,
    str
    };
    string str2 = SharedAccessSignatureBuilder.Sign(string.Join("\n", strs), key, targetService);
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}={2}&{3}={4}&{5}={6}", new object[] { "SharedAccessSignature", "sr", str1, "sig", WebUtility.UrlEncode(str2), "se", WebUtility.UrlEncode(str) });
    if (!string.IsNullOrEmpty(keyName))
    {
    stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "&{0}={1}", new object[] { "skn", WebUtility.UrlEncode(keyName) });
    }
    return stringBuilder.ToString();
    }
    private static string Sign(string requestString, string key, string targetService)
    {
    string base64String;
    if (!string.IsNullOrEmpty(targetService) && targetService.ToLower() == "servicebus")
    {
    using (HMACSHA256 hMACSHA256 = new HMACSHA256(Encoding.UTF8.GetBytes(key))) // key is not decoded
                    {
    base64String = Convert.ToBase64String(hMACSHA256.ComputeHash(Encoding.UTF8.GetBytes(requestString)));
    }
    }
    else
    {
    using (HMACSHA256 hMACSHA256 = new HMACSHA256(Convert.FromBase64String(key))) // key is decoded
                    {
    base64String = Convert.ToBase64String(hMACSHA256.ComputeHash(Encoding.UTF8.GetBytes(requestString)));
    }
    }
    return base64String;
    }
    public string ToSignature()
    {
    return SharedAccessSignatureBuilder.BuildSignature(this.KeyName, this.Key, this.Target, this.TimeToLive, this.TargetService);
    }
    }
    SharedAccessSignatureBuilder




    public class SharedAccessSignatureConstants
    {
    public const int MaxKeyNameLength = 256;
    public const int MaxKeyLength = 256;
    public const string SharedAccessSignature = "SharedAccessSignature";
    public const string AudienceFieldName = "sr";
    public const string SignatureFieldName = "sig";
    public const string KeyNameFieldName = "skn";
    public const string ExpiryFieldName = "se";
    public const string SignedResourceFullFieldName = "SharedAccessSignature sr";
    public const string KeyValueSeparator = "=";
    public const string PairSeparator = "&";
    public readonly static DateTime EpochTime;
    public readonly static TimeSpan MaxClockSkew;
    static SharedAccessSignatureConstants()
    {
    SharedAccessSignatureConstants.EpochTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    SharedAccessSignatureConstants.MaxClockSkew = TimeSpan.FromMinutes(5);
    }
    }
    SharedAccessSignatureConstants  你也可以直接引用我编译的DLL 文件,并在项目中引用它。



    using SharedAccessSignatureGenerator;
      调用方式:
      1)根据IoT Hub 共享访问策略生成安全令牌
    假设IoT Hub 共享访问策略连接串如下:



    HostName=<iot-hub-name>.azure-devices.cn;SharedAccessKeyName=<policy name>;SharedAccessKey=<key>
      调用方法:



    var sasBuilder = new SharedAccessSignatureBuilder()
    {
    KeyName = <policy name>,
    Key = <key>,
    Target = string.Format("{0}/devices", <iot-hub-name>),
    TimeToLive = TimeSpan.FromDays(Convert.ToDouble(ttlValue))
    };
    string sas = sasBuilder.ToSignature();
      输出示例:



    SharedAccessSignature sr=devpod.azure-devices.cn%2Fdevices&sig=eAtQg7Du%2FUBrBk9zELLpOwELyGSVuOH0qHv1iJ63xnc%3D&se=1478756374&skn=iothubowner
      2)根据设备的symmetric key生成安全令牌
      假设IoT Hub 设备的链接串如下:



    HostName=<iot-hub-name>.azure-devices.cn;DeviceId=<deviceId>;SharedAccessKey=<key>
      调用方法:



    var sasBuilder = new SharedAccessSignatureBuilder()
    {
    Key = <key>,
    Target = string.Format("{0}/devices/{1}", <iot-hub-name>, WebUtility.UrlEncode(<deviceId>)),
    TimeToLive = TimeSpan.FromDays(Convert.ToDouble(ttlValue))
    };
    string sas = sasBuilder.ToSignature();
      输出示例:



    SharedAccessSignature sr=devpod.azure-devices.cn%2Fdevices%2Fdevice001&sig=x6rceLUBASP99GU03LAX5w0YQ8gF05J6%2BYX5gJwKISQ%3D&se=1478756286

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-389513-1-1.html 上篇帖子: Azure存储基本介绍 下篇帖子: Azure Messaging
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表