Authenticating MQTT client on the MQTT server by username and password in C# asp.net core 2.1

Viewed 2335

I want to check username and password of MQTT client in MQTT server then allow its connection. I implemented a server and send data from a device. I get the data but the problem is the authentication does not work properly because I need to get the client information from DB based on the topic that the client sent. What did I do so far is as below:

public async Task Received()
{
  var options = new MqttServerOptions();                
  var mqttServer = new MqttFactory().CreateMqttServer();
  mqttServer.ApplicationMessageReceived += (sender, eventArgs) =>
  {    
    var path = eventArgs.ApplicationMessage.Topic;
    var device= GetDevice(path);   

    options.ConnectionValidator = p =>
    {    
      if (p.Username != device.username || p.Password != device.password)
      {
        p.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
      }
    };
  };

  mqttServer.ClientConnected += (s, e) => { };

  mqttServer.ClientDisconnected += (s, e) => { };

  mqttServer.ClientSubscribedTopic += (s, e) => { };

  mqttServer.ClientUnsubscribedTopic += (s, e) => { };

  mqttServer.Started += (s, e) => { };

  mqttServer.Stopped += (s, e) => { };

  await mqttServer.StartAsync(options);
}

and this code is in my startup

app.UseMqttServer(server =>
{
  server.Started += async (sender, args) => await myClass.Received();
});

I can get the requests in my method but I have difficulty to check the username and password.

1 Answers

You can implement this by disconnecting the client when it attempts to publish/subscribe to an invalid topic.

This means using authorisation instead of authentication to enforce your policy. Authentication can only be done using the parameters that are available in an MQTT connect message e.g. client id, password.

So to do this the ConnectionValidator event handler needs to be setup when the server starts. It can record the client id and password that the client attempts to connect with and always allow the connection to proceed.

The ApplicationMessageReceived event handler will be invoked when the client publishes/subscribes to a topic. This event handler can verify the client id and password that were passed in when the client connected against the one in your database (using the topic as you require). If the path, client id and password are invalid then you need to explicitly disconnect the client.

The client can be explicitly disconnected by finding the client in the list of all sessions on the server using mqttServer.GetClientSessionsStatus(). Then invoke DisconnectAsync() on the client session.

Related