1
votes

We have started a PoC to connect some of our existing code the Azure IoT Hub via MQTT to test Azure’s support for standard protocols and tools. We are using the Paho client but are getting a CONNACK with a return code of 5 – Not Authorized.

We followed the instructions on how to setup an IoT Hub and created one using the F1 (free) scale tier. We then followed another Azure document and downloaded Device Explorer, created a device and generated a SAS token. We then plugged everything into Paho:

public static void main( String[] args ) {
  String deviceId = "device-fcbd127a";
  String sasToken = "SharedAccessSignature sr=CoyoteIoT.azure-devices.net%2fdevices%2fdevice-fcbd127a&sig=3acRHQXXXXXXXXXXX‌​Zg%3d&se=1468067737";
  String brokerUri = "ssl://CoyoteIoT.azure-devices.net:8883";
  String clientId = deviceId;
  System.out.println( "Connecting to " + brokerUri +" as "+clientId);

  MqttAsyncClient client = null;
  try {
    client = new MqttAsyncClient( brokerUri, clientId );
    if ( client != null ) {
      MqttConnectOptions options = new MqttConnectOptions();
      client.setCallback( new AzureCallback() );
      options.setUserName( "CoyoteIoT.azure-devices.net/device-fcbd127a"     );
      options.setPassword( sasToken.toCharArray() );
      IMqttToken token = client.connect( options );
      token.waitForCompletion( 5000 );
      if ( client.isConnected() ) {
        System.out.println( "Success!" );
      } else {
        System.out.println( "Could not connect to Azure IoT hub, timed-out" );
      }
    }
  } catch ( MqttException e ) {
    client.getDebug().dumpBaseDebug();
    e.printStackTrace();
  } finally {
    if ( client != null ) {
      try {
        client.disconnect();
      } catch ( MqttException ignore ) {}
    }
  }
}

We have confirmed with Wireshark that a SSL connection is made to Azure and that the CONNECT packet is sent. We then see the CONNACK with a return code of 5 being sent to Paho and Azure dropping the connection soon thereafter. We then looked into “Shared Access Policies” and tried different settings. There is nothing in the audit logs and we have “verbose” turned on for everything.

Has anyone connected Paho (or other third-party Java client) to the Azure IoT Hub?

Where do we find any diagnostic information so we can troubleshoot this ourselves?

On a side note, we shelved this (MQTT) approach and tried to connect via the ReST services and receive an even more ambiguous “500-Internal Server Error“ as a response. This makes us think there is a more fundamental access issue here. Does the F1 scale hub only support the Microsoft SDK? Are there some hidden access control settings we are missing? Is the format of the names strict, not allowing certain characters or case?

4

4 Answers

1
votes

Apparently we had issues with the Device Explorer utility. Instead of generating a SAS Token with an expiry of 365 days, it generated a token good for only 365 seconds.

Note the se=1468067737 in the SAS token, it evaluates to an expiration of Jul 09 08:35:37 EDT 2016, well past our test execution.

0
votes

Your SAS token looks a bit off.

"SharedAccessSignature=Share[snipped]%3d&se=1468067737"

vs. what's in the docs:

"SharedAccessSignature sr=iothubname.azure-devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501"

Yes, whitespace included.

See: https://github.com/Azure/azure-content/blob/master/articles/iot-hub/iot-hub-devguide.md#example

I made that PR after struggling with forming the password for half a day, i promise you that works :)

0
votes

@SCote, my suggestion is that you can try to refer to the source code MqttIotHubConnection.java of Azure IoTHub SDK for device with Java which is also based on Paho.

I viewed the code, then found the difference below for UserName at the 128 line and set up all properties in the function updateConnectionOptions at the 346 line.

String clientIdentifier = "DeviceClientType=" + URLEncoder.encode(TransportUtils.javaDeviceClientIdentifier + TransportUtils.clientVersion, "UTF-8");
this.iotHubUserName = this.config.getIotHubHostname() + "/" + this.config.getDeviceId() + "/" + clientIdentifier;

So I think you can try to follow the offical implementation to rewrite your partial code.

Hope it helps for solving your issue.

0
votes

I tried connecting from Paho GUI Client (Which I have validated already connecting to azure with my credentials - Works!!) with your credentials specified in your code. I ended up with an error message showing "org.eclipse.paho.client.mqttv3.MqttException: Connection lost". I hope, you have not eliminated or modified any portions of your credentials. Try to validate your credentials with this paho GUI app.

Paho GUI Client.