Authentication & Authorization

Cong Lance edited this page May 16, 2016 · 4 revisions

With Mosca you can authorize a client defining three methods.

  • #authenticate
  • #authorizePublish
  • #authorizeSubscribe

Those methods can be used to restrict the accessible topics for a specific clients. Here is an example of a client that sends a username and a password during the connection phase and where the username will be saved and used later on. (To verify if a specific client can publish or subscribe for the specific user)

// Accepts the connection if the username and password are valid
var authenticate = function(client, username, password, callback) {
  var authorized = (username === 'alice' && password.toString() === 'secret');
  if (authorized) client.user = username;
  callback(null, authorized);
}

// In this case the client authorized as alice can publish to /users/alice taking
// the username from the topic and verifing it is the same of the authorized user
var authorizePublish = function(client, topic, payload, callback) {
  callback(null, client.user == topic.split('/')[1]);
}

// In this case the client authorized as alice can subscribe to /users/alice taking
// the username from the topic and verifing it is the same of the authorized user
var authorizeSubscribe = function(client, topic, callback) {
  callback(null, client.user == topic.split('/')[1]);
}

With this logic someone that is authorized as 'alice' will not be able to publish to the topic users/bob. Now that we have the authorizing methods we can configure mosca.

var server = new mosca.Server(settings);
server.on('ready', setup);

function setup() {
  server.authenticate = authenticate;
  server.authorizePublish = authorizePublish;
  server.authorizeSubscribe = authorizeSubscribe;
}

Using Mosca's standalone authorizer with an embedded Mosca

If you are using Mosca as embedded broker into your own application, but would still like to make use of its authorization feature with CLI as defined in the Mosca as a standalone wiki page, you may proceed as described below.

First, you should copy the loadAuthorizer() method out from lib/cli.js since it is defined as private. Or simply refer to it from below:

var fs = require("fs");
var Authorizer = require("mosca/lib/authorizer");

function loadAuthorizer(program, cb) {
	if (program.credentials) {
	    fs.readFile(program.credentials, function(err, data) {
		    if (err) {
		        cb(err);
		        return;
		    }

		    var authorizer = new Authorizer();

		    try {
		        authorizer.users = JSON.parse(data);
		        cb(null, authorizer);
		    } catch(err) {
		        cb(err);
		    }
	    });
	} else {
	    cb(null, null);
	}
}

Then add the credentials setting into your moscaSettings with the path to your credentials file.

credentials: "config/mqtt_credentials.json"

Finally, setup your authorizer in the setup() method like below:

function setup() {
	// setup authorizer
	loadAuthorizer(moscaSettings, function(err, authorizer) {
	    if (err) {
		    // handle error here
	    }

	    if (authorizer) {
		    server.authenticate = authorizer.authenticate;
		    server.authorizeSubscribe = authorizer.authorizeSubscribe;
		    server.authorizePublish = authorizer.authorizePublish;
	    }
	});

    // you are good to go!
}