使用AMQP lite

时间:2017-02-28 07:45:28

标签: azure authentication amqp sasl azure-iot-hub

在AMQP lite github页面上的示例之后,我已经使用SASL ANONYMOUS成功连接,然后在$ cbs端点上使用令牌。 (https://github.com/Azure/amqpnetlite/blob/master/docs/articles/service_to_iothub.md

在每个请求上生成SAS令牌都是多余的,我希望在连接到IoT Hub时使用共享访问策略和密钥作为用户和密码。 我已经跟踪了https://github.com/Azure/amqpnetlite/blob/master/docs/articles/building_application.md#specifying-an-address上的文档以及https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security#protocol-specifics上的指示,但是我一直在使用代码“Sys”获得一些未经身份验证的错误。

凭据肯定是好的,因为我使用它们来生成SAS令牌,并且我尝试了用户名的变体(有/没有域)但没有成功。我已经专门检查了用户名和密码是否为URL编码。

根据SASL标准的文档,错误代码Sys似乎表明接收方有些问题(http://www.rfc-base.org/txt/rfc-3206.txt第3页)。

还有其他人遇到过这个问题吗?有没有解决方案,或者可以通过这种方式连接到IoT Hub?

谢谢, 乔治

1 个答案:

答案 0 :(得分:1)

由于没有发送put-token消息,我收到“amqp:unauthorized-access”错误:

        string sasToken = GetSharedAccessSignature(null, device_key, resourceUri, new TimeSpan(1, 0, 0));
        bool cbs = PutCbsToken(connection, host, sasToken, audience);

我使用以下代码在Windows 10桌面上进行测试,它适用于发送和接收:

    static string host = "[IOT_HUB_NAME].azure-devices.net";
    static int port = 5671;
    static string device_id = "[DEVICE_ID]";
    static string device_key = "[DEVICE_KEY]";
    static Session session;

    static void Main(string[] args)
    {
        Address address = new Address(host, port, null, null);
        Connection connection = new Connection(address);

        string audience = Fx.Format("{0}/devices/{1}", host, device_id);
        string resourceUri = Fx.Format("{0}/devices/{1}", host, device_id);

        string sasToken = GetSharedAccessSignature(null, device_key, resourceUri, new TimeSpan(1, 0, 0));
        bool cbs = PutCbsToken(connection, host, sasToken, audience);

        session = new Session(connection);

        SendEvent();
        ReceiveCommands();
        Console.ReadLine();
    }

    static private void SendEvent()
    {
        string entity = Fx.Format("/devices/{0}/messages/events", device_id);

        SenderLink senderLink = new SenderLink(session, "sender-link", entity);

        var messageValue = Encoding.UTF8.GetBytes("i am a message.");
        Message message = new Message()
        {
            BodySection = new Data() { Binary = messageValue }
        };

        senderLink.Send(message);
        senderLink.Close();
    }

    static private void ReceiveCommands()
    {
        string entity = Fx.Format("/devices/{0}/messages/deviceBound", device_id);

        ReceiverLink receiveLink = new ReceiverLink(session, "receive-link", entity);

        Message received = receiveLink.Receive();
        if (received != null)
            receiveLink.Accept(received);
        Console.WriteLine(received.BodySection.ToString());
        receiveLink.Close();
    }

有关详细信息,请参阅“CONNECTING TO THE AZURE IOT HUB USING AN AMQP STACK”。

<强>更新

以下代码不使用上述代码段之类的SAS令牌,而是使用共享访问策略和密钥(SASL PLAIN):

    static string host = "[IOT_HUB_NAME].azure-devices.net";
    static int port = 5671;
    static string device_id = "[DEVICE_ID]";
    static string device_key = "[DEVICE_KEY]";
    private const string username_hublevel = "iothubowner@sas.root.[IOT_HUB_NAME]";
    private const string password_hublevel = "SharedAccessSignature sr={URL-encoded-resourceURI}&sig={signature-string}&se={expiry}&skn={policyName}";

    static Session session;

    static void Main(string[] args)
    {
        Address address = new Address(host, port, username_hublevel, password_hublevel);
        Connection connection = new Connection(address);

        string audience = Fx.Format("{0}/devices/{1}", host, device_id);
        string resourceUri = Fx.Format("{0}/devices/{1}", host, device_id);

        session = new Session(connection);

        SendEvent();
        Console.WriteLine("Sent Hello AMQP!");
        ReceiveCommands();
        Console.ReadLine();
    }